513 lines
20 KiB
Go
513 lines
20 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"github.com/davecgh/go-spew/spew"
|
||
|
"net/http"
|
||
|
"strconv"
|
||
|
"time"
|
||
|
"log"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
|
||
|
http.HandleFunc("/piwik.php", func(w http.ResponseWriter, r *http.Request) {
|
||
|
pr := ParseV3(r)
|
||
|
spew.Dump(pr)
|
||
|
})
|
||
|
http.Handle("/", http.FileServer(http.Dir("assets")))
|
||
|
http.ListenAndServe(":8080", nil)
|
||
|
}
|
||
|
|
||
|
type V3Visit struct {
|
||
|
SiteID string //idsite
|
||
|
Record bool //rec
|
||
|
URL string //url
|
||
|
ActionName string //action_anem
|
||
|
VisitorID string //_id
|
||
|
Referrer string //urlref
|
||
|
CustomVars map[string]interface{} //_cvar
|
||
|
VisitsCount string //_idvc
|
||
|
ViewTime time.Time //_viewts
|
||
|
VisitorFirstVisitTime time.Time //_idts
|
||
|
CampaignName string //_rcn
|
||
|
CampaignKeyword string //_rck
|
||
|
Resolution string //res
|
||
|
LocalHour string //h
|
||
|
LocalMinute string //m
|
||
|
LocalSeconds string //s
|
||
|
LocalTimeUTC time.Time
|
||
|
Plugins struct {
|
||
|
Flash bool //fla
|
||
|
Java bool //java
|
||
|
Director bool //dir
|
||
|
Quicktime bool //qt
|
||
|
RealPlayer bool //realp
|
||
|
PDF bool //pdf
|
||
|
WindowsMedia bool //wma
|
||
|
Gears bool //gears
|
||
|
Silverlight bool //ag
|
||
|
}
|
||
|
SupportsCookies bool //cookie
|
||
|
UserAgent string //ua
|
||
|
Language string //lang
|
||
|
UserID string //uid
|
||
|
CustomUserID string //cid
|
||
|
NewVisit bool //new_visit
|
||
|
|
||
|
PageCustomVars map[string]interface{} //cvar
|
||
|
Link string //link
|
||
|
Download string //download
|
||
|
Search string //search
|
||
|
SearchCategory string //search_cat
|
||
|
SearchCount string //search_count
|
||
|
PageViewID string //pv_id
|
||
|
GoalID string //idgoal
|
||
|
Revenue string //revenue
|
||
|
GenerationTime string //gt_ms
|
||
|
Characterset string //cs
|
||
|
|
||
|
EventCategory string //e_c
|
||
|
EventAction string //e_a
|
||
|
EventName string //e_n
|
||
|
EventValue string //e_v
|
||
|
|
||
|
ContentName string //c_n
|
||
|
ContentPiece string //c_p
|
||
|
ContentTarget string //c_t
|
||
|
ContentInteraction string //c_i
|
||
|
|
||
|
ECommerceID string // ec_id
|
||
|
ECommerceItems [][]string // ec_items
|
||
|
ECommerceSubTotal string // ec_st
|
||
|
ECommerceTax string // ec_tx
|
||
|
ECommerceShipping string // ec_sh
|
||
|
ECommerceDiscount string // ec_dt
|
||
|
ECommerceTime time.Time // ec_ts
|
||
|
|
||
|
TokenAuth string //token_auth
|
||
|
CustomIP string //cip
|
||
|
CustomDateTime string //cdt
|
||
|
CustomCountry string //country
|
||
|
CustomRegion string //region
|
||
|
CustomCity string //city
|
||
|
CustomLatitude string //lat
|
||
|
CustomLongitude string //long
|
||
|
|
||
|
MediaID string // ma_id
|
||
|
MediaTitle string // ma_ti
|
||
|
MediaResource string // ma_re
|
||
|
MediaType string // ma_mt
|
||
|
MediaPlayerName string // ma_pn
|
||
|
MediaSecondsPlayingTime string // ma_st
|
||
|
MediaLength string // ma_le
|
||
|
MediaProgress string // ma_ps
|
||
|
MediaTimeUntilPlay string // ma_ttp
|
||
|
MediaWidth string // ma_w
|
||
|
MediaHeight string // ma_h
|
||
|
MediaFullscreen bool // ma_fs
|
||
|
|
||
|
SendImage string //send_image
|
||
|
}
|
||
|
|
||
|
func ParseV3(r *http.Request) *V3Visit {
|
||
|
/*
|
||
|
https://developer.piwik.org/api-reference/tracking-api
|
||
|
*/
|
||
|
|
||
|
v3 := new(V3Visit)
|
||
|
// (required) — The ID of the website we're tracking a visit/action for.
|
||
|
v3.SiteID = r.URL.Query().Get("idsite")
|
||
|
|
||
|
// (required) — Required for tracking, must be set to one, eg, &rec=1.
|
||
|
if r.URL.Query().Get("rec") == "1" {
|
||
|
v3.Record = true
|
||
|
} else {
|
||
|
v3.Record = false
|
||
|
}
|
||
|
|
||
|
// (required) — The full URL for the current action.
|
||
|
v3.URL = r.URL.Query().Get("url")
|
||
|
|
||
|
// (recommended) — The title of the action being tracked.
|
||
|
// It is possible to use slashes / to set one or several categories for this action.
|
||
|
// For example, Help / Feedback will create the Action Feedback in the category Help.
|
||
|
v3.ActionName = r.URL.Query().Get("action_name")
|
||
|
|
||
|
// (recommended) — The unique visitor ID, must be a 16 characters hexadecimal string.
|
||
|
// Every unique visitor must be assigned a different ID and this ID must not change after it is assigned.
|
||
|
// If this value is not set Piwik will still track visits, but the unique visitors metric might be less accurate.
|
||
|
v3.VisitorID = r.URL.Query().Get("_id")
|
||
|
|
||
|
/*
|
||
|
r.URL.Query().Get("rand") // (recommended) — Meant to hold a random value that is generated before each request. Using it helps avoid the tracking request being cached by the browser or a proxy.
|
||
|
r.URL.Query().Get("apiv") // (recommended) — The parameter &apiv=1 defines the api version to use (currently always set to 1)
|
||
|
*/
|
||
|
|
||
|
// The full HTTP Referrer URL.
|
||
|
// This value is used to determine how someone got to your website (ie, through a website, search engine or campaign).
|
||
|
v3.Referrer = r.URL.Query().Get("urlref")
|
||
|
|
||
|
// Visit scope custom variables.
|
||
|
// This is a JSON encoded string of the custom variable array (see below for an example value).
|
||
|
if e := json.Unmarshal([]byte(r.URL.Query().Get("_cvar")), v3.CustomVars);e != nil {
|
||
|
log.Println(e)
|
||
|
}
|
||
|
|
||
|
// The current count of visits for this visitor.
|
||
|
// To set this value correctly, it would be required to store the value for each visitor in your application (using sessions or persisting in a database).
|
||
|
// Then you would manually increment the counts by one on each new visit or "session", depending on how you choose to define a visit.
|
||
|
// This value is used to populate the report Visitors > Engagement > Visits by visit number.
|
||
|
v3.VisitsCount = r.URL.Query().Get("_idvc")
|
||
|
|
||
|
// The UNIX timestamp of this visitor's previous visit. This parameter is used to populate the report Visitors > Engagement > Visits by days since last visit.
|
||
|
v3.ViewTime = stringToTime(r.URL.Query().Get("_viewts"))
|
||
|
|
||
|
// The UNIX timestamp of this visitor's first visit. This could be set to the date where the user first started using your software/app, or when he/she created an account.
|
||
|
// This parameter is used to populate the Goals > Days to Conversion report.
|
||
|
v3.VisitorFirstVisitTime = stringToTime(r.URL.Query().Get("_idts"))
|
||
|
|
||
|
// The Campaign name (see Tracking Campaigns).
|
||
|
// Used to populate the Referrers > Campaigns report.
|
||
|
// Note: this parameter will only be used for the first pageview of a visit.
|
||
|
v3.CampaignName = r.URL.Query().Get("_rcn")
|
||
|
|
||
|
// The Campaign Keyword (see Tracking Campaigns).
|
||
|
// Used to populate the Referrers > Campaigns report (clicking on a campaign loads all keywords for this campaign).
|
||
|
// Note: this parameter will only be used for the first pageview of a visit.
|
||
|
v3.CampaignKeyword = r.URL.Query().Get("_rck")
|
||
|
|
||
|
// The resolution of the device the visitor is using, eg 1280x1024.
|
||
|
v3.Resolution = r.URL.Query().Get("res")
|
||
|
|
||
|
// The current hour (local time).
|
||
|
v3.LocalHour = r.URL.Query().Get("h")
|
||
|
|
||
|
// The current minute (local time).
|
||
|
v3.LocalMinute = r.URL.Query().Get("m")
|
||
|
|
||
|
// The current second (local time).
|
||
|
v3.LocalSeconds = r.URL.Query().Get("s")
|
||
|
|
||
|
v3.LocalTimeUTC = time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), atoi(r.URL.Query().Get("h")), atoi(r.URL.Query().Get("m")), atoi(r.URL.Query().Get("s")), 0, time.UTC)
|
||
|
|
||
|
// plugins used by the visitor can be specified by setting the following parameters to 1
|
||
|
|
||
|
// Flash
|
||
|
if r.URL.Query().Get("fla") == "1" {
|
||
|
v3.Plugins.Flash = true
|
||
|
}
|
||
|
|
||
|
// Java
|
||
|
if r.URL.Query().Get("java") == "1" {
|
||
|
v3.Plugins.Java = true
|
||
|
}
|
||
|
|
||
|
// Director
|
||
|
if r.URL.Query().Get("dir") == "1" {
|
||
|
v3.Plugins.Director = true
|
||
|
}
|
||
|
|
||
|
// Quicktime
|
||
|
if r.URL.Query().Get("qt") == "1" {
|
||
|
v3.Plugins.Quicktime = true
|
||
|
}
|
||
|
|
||
|
// Real Player
|
||
|
if r.URL.Query().Get("realp") == "1" {
|
||
|
v3.Plugins.RealPlayer = true
|
||
|
}
|
||
|
|
||
|
// PDF
|
||
|
if r.URL.Query().Get("pdf") == "1" {
|
||
|
v3.Plugins.PDF = true
|
||
|
}
|
||
|
|
||
|
// Windows Media
|
||
|
if r.URL.Query().Get("wma") == "1" {
|
||
|
v3.Plugins.WindowsMedia = true
|
||
|
}
|
||
|
|
||
|
// Gears
|
||
|
if r.URL.Query().Get("gears") == "1" {
|
||
|
v3.Plugins.Gears = true
|
||
|
}
|
||
|
|
||
|
// Silverlight
|
||
|
if r.URL.Query().Get("ag") == "1" {
|
||
|
v3.Plugins.Silverlight = true
|
||
|
}
|
||
|
|
||
|
// when set to 1, the visitor's client is known to support cookies.
|
||
|
if r.URL.Query().Get("cookie") == "1" {
|
||
|
v3.SupportsCookies = true
|
||
|
}
|
||
|
|
||
|
// An override value for the User-Agent HTTP header field. The user agent is used to detect the operating system and browser used.
|
||
|
if r.URL.Query().Get("ua") != "" {
|
||
|
v3.UserAgent = r.URL.Query().Get("ua")
|
||
|
} else {
|
||
|
v3.UserAgent = r.UserAgent()
|
||
|
}
|
||
|
|
||
|
// An override value for the Accept-Language HTTP header field. This value is used to detect the visitor's country if GeoIP is not enabled.
|
||
|
if r.URL.Query().Get("lang") != "" {
|
||
|
v3.Language = r.URL.Query().Get("lang")
|
||
|
} else {
|
||
|
v3.Language = r.Header.Get("Accept-Language")
|
||
|
}
|
||
|
|
||
|
// defines the User ID for this request.
|
||
|
// User ID is any non empty unique string identifying the user (such as an email address or a username).
|
||
|
// To access this value, users must be logged-in in your system so you can fetch this user ID from your system, and pass it to Piwik.
|
||
|
// The User ID appears in the visitor log, the Visitor profile, and you can Segment reports for one or several User ID (userId segment).
|
||
|
// When specified, the User ID will be "enforced".
|
||
|
// This means that if there is no recent visit with this User ID, a new one will be created.
|
||
|
// If a visit is found in the last 30 minutes with your specified User ID, then the new action will be recorded to this existing visit.
|
||
|
v3.UserID = r.URL.Query().Get("uid")
|
||
|
|
||
|
// defines the visitor ID for this request.
|
||
|
// You must set this value to exactly a 16 character hexadecimal string (containing only characters 01234567890abcdefABCDEF).
|
||
|
// We recommended to set the User ID via uid rather than use this cid
|
||
|
v3.CustomUserID = r.URL.Query().Get("cid")
|
||
|
|
||
|
// If set to 1, will force a new visit to be created for this action. This feature is also available in JavaScript.
|
||
|
if r.URL.Query().Get("new_visit") == "1" {
|
||
|
v3.NewVisit = true
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
// ? scopes?
|
||
|
dimension := make(map[string]string)
|
||
|
for k, v := range r.URL.Query() {
|
||
|
if strings.HasPrefix(k, "dimension") {
|
||
|
dimension[strings.TrimPrefix(k, "dimension")] = v
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
Optional Action info (measure Page view, Outlink, Download, Site search)
|
||
|
*/
|
||
|
|
||
|
// Page scope custom variables. This is a JSON encoded string of the custom variable array (see below for an example value).
|
||
|
json.Unmarshal([]byte(r.URL.Query().Get("cvar")), v3.PageCustomVars)
|
||
|
|
||
|
// An external URL the user has opened.
|
||
|
// Used for tracking outlink clicks.
|
||
|
// We recommend to also set the url parameter to this same value.
|
||
|
v3.Link = r.URL.Query().Get("link")
|
||
|
|
||
|
// URL of a file the user has downloaded.
|
||
|
// Used for tracking downloads.
|
||
|
// We recommend to also set the url parameter to this same value.
|
||
|
v3.Download = r.URL.Query().Get("download")
|
||
|
|
||
|
// The Site Search keyword.
|
||
|
// When specified, the request will not be tracked as a normal pageview but will instead be tracked as a Site Search request.
|
||
|
v3.Search = r.URL.Query().Get("search")
|
||
|
|
||
|
// when search is specified, you can optionally specify a search category with this parameter.
|
||
|
v3.SearchCategory = r.URL.Query().Get("search_cat")
|
||
|
|
||
|
// when search is specified, we also recommend to set the search_count to the number of search results displayed on the results page.
|
||
|
// When keywords are tracked with &search_count=0 they will appear in the "No Result Search Keyword" report.
|
||
|
v3.SearchCount = r.URL.Query().Get("search_count")
|
||
|
|
||
|
// Accepts a six character unique ID that identifies which actions were performed on a specific page view.
|
||
|
// When a page was viewed, all following tracking requests (such as events) during that page view should use the same pageview ID.
|
||
|
// Once another page was viewed a new unique ID should be generated.
|
||
|
// Use [0-9a-Z] as possible characters for the unique ID.
|
||
|
v3.PageViewID = r.URL.Query().Get("pv_id")
|
||
|
|
||
|
// If specified, the tracking request will trigger a conversion for the goal of the website being tracked with this ID.
|
||
|
v3.GoalID = r.URL.Query().Get("idgoal")
|
||
|
|
||
|
// A monetary value that was generated as revenue by this goal conversion.
|
||
|
// Only used if idgoal is specified in the request.
|
||
|
v3.Revenue = r.URL.Query().Get("revenue")
|
||
|
|
||
|
// The amount of time it took the server to generate this action, in milliseconds.
|
||
|
// This value is used to process the Page speed report Avg. generation time column in the Page URL and Page Title reports,
|
||
|
// as well as a site wide running average of the speed of your server.
|
||
|
// Note: when using the JavaScript tracker this value is set to the time for server to generate response + the time for client to download response.
|
||
|
v3.GenerationTime = r.URL.Query().Get("gt_ms")
|
||
|
|
||
|
// The charset of the page being tracked.
|
||
|
// Specify the charset if the data you send to Piwik is encoded in a different character set than the default utf-8.
|
||
|
v3.Characterset = r.URL.Query().Get("cs")
|
||
|
|
||
|
/*
|
||
|
Optional Event Tracking info
|
||
|
*/
|
||
|
|
||
|
// The event category. Must not be empty. (eg. Videos, Music, Games...)
|
||
|
v3.EventCategory = r.URL.Query().Get("e_c")
|
||
|
|
||
|
// The event action. Must not be empty. (eg. Play, Pause, Duration, Add Playlist, Downloaded, Clicked...)
|
||
|
v3.EventAction = r.URL.Query().Get("e_a")
|
||
|
|
||
|
// The event name. (eg. a Movie name, or Song name, or File name...)
|
||
|
v3.EventName = r.URL.Query().Get("e_n")
|
||
|
|
||
|
// The event value. Must be a float or integer value (numeric), not a string.
|
||
|
v3.EventValue = r.URL.Query().Get("e_v")
|
||
|
|
||
|
/*
|
||
|
Optional Content Tracking info
|
||
|
*/
|
||
|
|
||
|
// The name of the content. For instance 'Ad Foo Bar'
|
||
|
v3.ContentName = r.URL.Query().Get("c_n")
|
||
|
// The actual content piece. For instance the path to an image, video, audio, any text
|
||
|
v3.ContentPiece = r.URL.Query().Get("c_p")
|
||
|
// The target of the content. For instance the URL of a landing page
|
||
|
v3.ContentTarget = r.URL.Query().Get("c_t")
|
||
|
// The name of the interaction with the content. For instance a 'click'
|
||
|
v3.ContentInteraction = r.URL.Query().Get("c_i")
|
||
|
|
||
|
// Optional Ecommerce info
|
||
|
// you must set &idgoal=0 in the request to track an ecommerce interaction: cart update or an ecommerce order.
|
||
|
if r.URL.Query().Get("idgoal") == "0" {
|
||
|
// The unique string identifier for the ecommerce order (required when tracking an ecommerce order)
|
||
|
v3.ECommerceID = r.URL.Query().Get("ec_id")
|
||
|
|
||
|
// Items in the Ecommerce order.
|
||
|
// This is a JSON encoded array of items. Each item is an array with the following info in this order: item sku, item name, item category, item price, item quantity.
|
||
|
json.Unmarshal([]byte(r.URL.Query().Get("ec_items")), v3.ECommerceItems)
|
||
|
|
||
|
// The grand total for the ecommerce order (required when tracking an ecommerce order)
|
||
|
v3.Revenue = r.URL.Query().Get("revenue")
|
||
|
|
||
|
// The sub total of the order; excludes shipping.
|
||
|
v3.ECommerceSubTotal = r.URL.Query().Get("ec_st")
|
||
|
|
||
|
// Tax Amount of the order
|
||
|
v3.ECommerceTax = r.URL.Query().Get("ec_tx")
|
||
|
|
||
|
// Shipping cost of the Order
|
||
|
v3.ECommerceShipping = r.URL.Query().Get("ec_sh")
|
||
|
|
||
|
// Discount offered
|
||
|
v3.ECommerceDiscount = r.URL.Query().Get("ec_dt")
|
||
|
|
||
|
// The UNIX timestamp of this customer's last ecommerce order.
|
||
|
// This value is used to process the "Days since last order" report.
|
||
|
v3.ECommerceTime = stringToTime(r.URL.Query().Get("_ects"))
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Other parameters (require authentication via token_auth)
|
||
|
*/
|
||
|
|
||
|
// 32 character authorization key used to authenticate the API request.
|
||
|
v3.TokenAuth = r.URL.Query().Get("token_auth")
|
||
|
|
||
|
// Override value for the visitor IP (both IPv4 and IPv6 notations supported).
|
||
|
v3.CustomIP = r.URL.Query().Get("cip")
|
||
|
|
||
|
// Override for the datetime of the request (normally the current time is used).
|
||
|
// This can be used to record visits and page views in the past.
|
||
|
// The expected format is either a datetime such as: 2011-04-05 00:11:42 (remember to URL encode the value!), or a valid UNIX timestamp such as 1301919102.
|
||
|
// The datetime must be sent in UTC timezone.
|
||
|
// Note: if you record data in the past, you will need to force Piwik to re-process reports for the past dates.
|
||
|
// If you set cdt to a datetime older than 24 hours then token_auth must be set.
|
||
|
// If you set cdt with a datetime in the last 24 hours then you don't need to pass token_auth.
|
||
|
v3.CustomDateTime = r.URL.Query().Get("cdt")
|
||
|
|
||
|
// An override value for the country. Should be set to the two letter country code of the visitor (lowercase), eg fr, de, us.
|
||
|
v3.CustomCountry = r.URL.Query().Get("country")
|
||
|
|
||
|
// An override value for the region. Should be set to the two letter region code as defined by MaxMind's GeoIP databases. See here for a list of them for every country (the region codes are located in the second column, to the left of the region name and to the right of the country code).
|
||
|
v3.CustomRegion = r.URL.Query().Get("region")
|
||
|
|
||
|
// An override value for the city. The name of the city the visitor is located in, eg, Tokyo.
|
||
|
v3.CustomCity = r.URL.Query().Get("city")
|
||
|
|
||
|
// An override value for the visitor's latitude, eg 22.456.
|
||
|
v3.CustomLatitude = r.URL.Query().Get("lat")
|
||
|
|
||
|
// An override value for the visitor's longitude, eg 22.456.
|
||
|
v3.CustomLongitude = r.URL.Query().Get("long")
|
||
|
|
||
|
/*
|
||
|
Media Analytics parameters
|
||
|
https://developer.piwik.org/guides/media-analytics/custom-player#media-analytics-http-tracking-api-reference
|
||
|
*/
|
||
|
|
||
|
// A unique id that is always the same while playing a media. As soon as the played media changes (new video or audio started), this ID has to change.
|
||
|
v3.MediaID = r.URL.Query().Get("ma_id")
|
||
|
|
||
|
// The name / title of the media.
|
||
|
v3.MediaTitle = r.URL.Query().Get("ma_ti")
|
||
|
|
||
|
// The URL of the media resource.
|
||
|
v3.MediaResource = r.URL.Query().Get("ma_re")
|
||
|
|
||
|
// video or audio depending on the type of the media.
|
||
|
v3.MediaType = r.URL.Query().Get("ma_mt")
|
||
|
|
||
|
// The name of the media player, for example html5.
|
||
|
v3.MediaPlayerName = r.URL.Query().Get("ma_pn")
|
||
|
|
||
|
// The time in seconds for how long a user has been playing this media.
|
||
|
// This number should typically increase when you send a media tracking request.
|
||
|
// It should be 0 if the media was only visible/impressed but not played.
|
||
|
// Do not increase this number when a media is paused.
|
||
|
v3.MediaSecondsPlayingTime = r.URL.Query().Get("ma_st")
|
||
|
|
||
|
// The duration (the length) of the media in seconds. For example if a video is 90 seconds long, the value should be 90.
|
||
|
v3.MediaLength = r.URL.Query().Get("ma_le")
|
||
|
|
||
|
// The progress / current position within the media. Defines basically at which position within the total length the user is currently playing.
|
||
|
v3.MediaProgress = r.URL.Query().Get("ma_ps")
|
||
|
|
||
|
// Defines after how many seconds the user has started playing this media.
|
||
|
// For example a user might have seen the poster of the video for 30 seconds before a user actually pressed the play button.
|
||
|
v3.MediaTimeUntilPlay = r.URL.Query().Get("ma_ttp")
|
||
|
|
||
|
// The resolution width of the media in pixels. Only recommended to be set for videos.
|
||
|
v3.MediaWidth = r.URL.Query().Get("ma_w")
|
||
|
|
||
|
// The resolution height of the media in pixels. Only recommended to be set for videos.
|
||
|
v3.MediaHeight = r.URL.Query().Get("ma_h")
|
||
|
|
||
|
// Should be 0 or 1 and defines whether the media is currently viewed in full screen. Only recommended to be set for videos.
|
||
|
switch r.URL.Query().Get("ma_fs") {
|
||
|
case "0":
|
||
|
v3.MediaFullscreen = false
|
||
|
case "1":
|
||
|
v3.MediaFullscreen = true
|
||
|
default:
|
||
|
v3.MediaFullscreen = false
|
||
|
}
|
||
|
|
||
|
// If set to 0 (send_image=0) Piwik will respond with a HTTP 204 response code instead of a GIF image.
|
||
|
// This improves performance and can fix errors if images are not allowed to be obtained directly (eg Chrome Apps).
|
||
|
// Available since Piwik 2.10.0
|
||
|
v3.SendImage = r.URL.Query().Get("send_image")
|
||
|
|
||
|
return v3
|
||
|
|
||
|
/*
|
||
|
r.URL.Query().Get("") //
|
||
|
*/
|
||
|
|
||
|
}
|
||
|
|
||
|
func stringToTime(s string) time.Time {
|
||
|
i, err := strconv.ParseInt(s, 10, 64)
|
||
|
if err != nil {
|
||
|
return time.Time{}
|
||
|
}
|
||
|
return time.Unix(i, 0)
|
||
|
}
|
||
|
|
||
|
func atoi(a string) int {
|
||
|
i, err := strconv.Atoi(a)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
return i
|
||
|
}
|