From a7df867ea3136433d3f93b07d71d38d3a5716865 Mon Sep 17 00:00:00 2001 From: Jason Harvey Date: Mon, 26 Oct 2015 16:45:06 -0800 Subject: [PATCH 1/2] Add third party requirements for google analytics collector. --- .../golang.org/x/net/context/context.go | 447 + .../golang.org/x/net/context/context_test.go | 575 + .../x/net/context/ctxhttp/cancelreq.go | 18 + .../x/net/context/ctxhttp/cancelreq_go14.go | 23 + .../x/net/context/ctxhttp/ctxhttp.go | 79 + .../x/net/context/ctxhttp/ctxhttp_test.go | 72 + .../x/net/context/withtimeout_test.go | 26 + _third_party/golang.org/x/oauth2/AUTHORS | 3 + .../golang.org/x/oauth2/CONTRIBUTING.md | 31 + _third_party/golang.org/x/oauth2/CONTRIBUTORS | 3 + _third_party/golang.org/x/oauth2/LICENSE | 27 + _third_party/golang.org/x/oauth2/README.md | 64 + .../golang.org/x/oauth2/client_appengine.go | 24 + .../golang.org/x/oauth2/example_test.go | 45 + .../golang.org/x/oauth2/google/appengine.go | 83 + .../x/oauth2/google/appengine_hook.go | 13 + .../golang.org/x/oauth2/google/default.go | 154 + .../x/oauth2/google/example_test.go | 150 + .../golang.org/x/oauth2/google/google.go | 145 + .../golang.org/x/oauth2/google/google_test.go | 67 + .../golang.org/x/oauth2/google/sdk.go | 168 + .../golang.org/x/oauth2/google/sdk_test.go | 46 + .../golang.org/x/oauth2/internal/oauth2.go | 69 + .../x/oauth2/internal/oauth2_test.go | 62 + _third_party/golang.org/x/oauth2/jws/jws.go | 160 + .../golang.org/x/oauth2/jwt/example_test.go | 31 + _third_party/golang.org/x/oauth2/jwt/jwt.go | 147 + .../golang.org/x/oauth2/jwt/jwt_test.go | 134 + _third_party/golang.org/x/oauth2/oauth2.go | 523 + .../golang.org/x/oauth2/oauth2_test.go | 439 + _third_party/golang.org/x/oauth2/token.go | 104 + .../golang.org/x/oauth2/token_test.go | 50 + _third_party/golang.org/x/oauth2/transport.go | 138 + .../golang.org/x/oauth2/transport_test.go | 53 + .../api/analytics/v3/analytics-api.json | 6675 +++++++ .../api/analytics/v3/analytics-gen.go | 16243 ++++++++++++++++ .../api/googleapi/googleapi.go | 592 + .../api/googleapi/googleapi_test.go | 599 + .../googleapi/internal/uritemplates/LICENSE | 18 + .../internal/uritemplates/uritemplates.go | 359 + .../googleapi/internal/uritemplates/utils.go | 13 + .../google.golang.org/api/googleapi/types.go | 182 + .../api/googleapi/types_test.go | 44 + .../google.golang.org/api/internal/json.go | 173 + .../api/internal/json_test.go | 367 + .../cloud/compute/metadata/go13.go | 37 + .../cloud/compute/metadata/metadata.go | 267 + .../google.golang.org/cloud/internal/cloud.go | 128 + 48 files changed, 29870 insertions(+) create mode 100644 _third_party/golang.org/x/net/context/context.go create mode 100644 _third_party/golang.org/x/net/context/context_test.go create mode 100644 _third_party/golang.org/x/net/context/ctxhttp/cancelreq.go create mode 100644 _third_party/golang.org/x/net/context/ctxhttp/cancelreq_go14.go create mode 100644 _third_party/golang.org/x/net/context/ctxhttp/ctxhttp.go create mode 100644 _third_party/golang.org/x/net/context/ctxhttp/ctxhttp_test.go create mode 100644 _third_party/golang.org/x/net/context/withtimeout_test.go create mode 100644 _third_party/golang.org/x/oauth2/AUTHORS create mode 100644 _third_party/golang.org/x/oauth2/CONTRIBUTING.md create mode 100644 _third_party/golang.org/x/oauth2/CONTRIBUTORS create mode 100644 _third_party/golang.org/x/oauth2/LICENSE create mode 100644 _third_party/golang.org/x/oauth2/README.md create mode 100644 _third_party/golang.org/x/oauth2/client_appengine.go create mode 100644 _third_party/golang.org/x/oauth2/example_test.go create mode 100644 _third_party/golang.org/x/oauth2/google/appengine.go create mode 100644 _third_party/golang.org/x/oauth2/google/appengine_hook.go create mode 100644 _third_party/golang.org/x/oauth2/google/default.go create mode 100644 _third_party/golang.org/x/oauth2/google/example_test.go create mode 100644 _third_party/golang.org/x/oauth2/google/google.go create mode 100644 _third_party/golang.org/x/oauth2/google/google_test.go create mode 100644 _third_party/golang.org/x/oauth2/google/sdk.go create mode 100644 _third_party/golang.org/x/oauth2/google/sdk_test.go create mode 100644 _third_party/golang.org/x/oauth2/internal/oauth2.go create mode 100644 _third_party/golang.org/x/oauth2/internal/oauth2_test.go create mode 100644 _third_party/golang.org/x/oauth2/jws/jws.go create mode 100644 _third_party/golang.org/x/oauth2/jwt/example_test.go create mode 100644 _third_party/golang.org/x/oauth2/jwt/jwt.go create mode 100644 _third_party/golang.org/x/oauth2/jwt/jwt_test.go create mode 100644 _third_party/golang.org/x/oauth2/oauth2.go create mode 100644 _third_party/golang.org/x/oauth2/oauth2_test.go create mode 100644 _third_party/golang.org/x/oauth2/token.go create mode 100644 _third_party/golang.org/x/oauth2/token_test.go create mode 100644 _third_party/golang.org/x/oauth2/transport.go create mode 100644 _third_party/golang.org/x/oauth2/transport_test.go create mode 100644 _third_party/google.golang.org/api/analytics/v3/analytics-api.json create mode 100644 _third_party/google.golang.org/api/analytics/v3/analytics-gen.go create mode 100644 _third_party/google.golang.org/api/googleapi/googleapi.go create mode 100644 _third_party/google.golang.org/api/googleapi/googleapi_test.go create mode 100644 _third_party/google.golang.org/api/googleapi/internal/uritemplates/LICENSE create mode 100644 _third_party/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go create mode 100644 _third_party/google.golang.org/api/googleapi/internal/uritemplates/utils.go create mode 100644 _third_party/google.golang.org/api/googleapi/types.go create mode 100644 _third_party/google.golang.org/api/googleapi/types_test.go create mode 100644 _third_party/google.golang.org/api/internal/json.go create mode 100644 _third_party/google.golang.org/api/internal/json_test.go create mode 100644 _third_party/google.golang.org/cloud/compute/metadata/go13.go create mode 100644 _third_party/google.golang.org/cloud/compute/metadata/metadata.go create mode 100644 _third_party/google.golang.org/cloud/internal/cloud.go diff --git a/_third_party/golang.org/x/net/context/context.go b/_third_party/golang.org/x/net/context/context.go new file mode 100644 index 0000000000..1c7b6b72ed --- /dev/null +++ b/_third_party/golang.org/x/net/context/context.go @@ -0,0 +1,447 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package context defines the Context type, which carries deadlines, +// cancelation signals, and other request-scoped values across API boundaries +// and between processes. +// +// Incoming requests to a server should create a Context, and outgoing calls to +// servers should accept a Context. The chain of function calls between must +// propagate the Context, optionally replacing it with a modified copy created +// using WithDeadline, WithTimeout, WithCancel, or WithValue. +// +// Programs that use Contexts should follow these rules to keep interfaces +// consistent across packages and enable static analysis tools to check context +// propagation: +// +// Do not store Contexts inside a struct type; instead, pass a Context +// explicitly to each function that needs it. The Context should be the first +// parameter, typically named ctx: +// +// func DoSomething(ctx context.Context, arg Arg) error { +// // ... use ctx ... +// } +// +// Do not pass a nil Context, even if a function permits it. Pass context.TODO +// if you are unsure about which Context to use. +// +// Use context Values only for request-scoped data that transits processes and +// APIs, not for passing optional parameters to functions. +// +// The same Context may be passed to functions running in different goroutines; +// Contexts are safe for simultaneous use by multiple goroutines. +// +// See http://blog.golang.org/context for example code for a server that uses +// Contexts. +package context // import "bosun.org/_third_party/golang.org/x/net/context" + +import ( + "errors" + "fmt" + "sync" + "time" +) + +// A Context carries a deadline, a cancelation signal, and other values across +// API boundaries. +// +// Context's methods may be called by multiple goroutines simultaneously. +type Context interface { + // Deadline returns the time when work done on behalf of this context + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that's closed when work done on behalf of this + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. + // + // WithCancel arranges for Done to be closed when cancel is called; + // WithDeadline arranges for Done to be closed when the deadline + // expires; WithTimeout arranges for Done to be closed when the timeout + // elapses. + // + // Done is provided for use in select statements: + // + // // Stream generates values with DoSomething and sends them to out + // // until DoSomething returns an error or ctx.Done is closed. + // func Stream(ctx context.Context, out <-chan Value) error { + // for { + // v, err := DoSomething(ctx) + // if err != nil { + // return err + // } + // select { + // case <-ctx.Done(): + // return ctx.Err() + // case out <- v: + // } + // } + // } + // + // See http://blog.golang.org/pipelines for more examples of how to use + // a Done channel for cancelation. + Done() <-chan struct{} + + // Err returns a non-nil error value after Done is closed. Err returns + // Canceled if the context was canceled or DeadlineExceeded if the + // context's deadline passed. No other values for Err are defined. + // After Done is closed, successive calls to Err return the same value. + Err() error + + // Value returns the value associated with this context for key, or nil + // if no value is associated with key. Successive calls to Value with + // the same key returns the same result. + // + // Use context values only for request-scoped data that transits + // processes and API boundaries, not for passing optional parameters to + // functions. + // + // A key identifies a specific value in a Context. Functions that wish + // to store values in Context typically allocate a key in a global + // variable then use that key as the argument to context.WithValue and + // Context.Value. A key can be any type that supports equality; + // packages should define keys as an unexported type to avoid + // collisions. + // + // Packages that define a Context key should provide type-safe accessors + // for the values stores using that key: + // + // // Package user defines a User type that's stored in Contexts. + // package user + // + // import "golang.org/x/net/context" + // + // // User is the type of value stored in the Contexts. + // type User struct {...} + // + // // key is an unexported type for keys defined in this package. + // // This prevents collisions with keys defined in other packages. + // type key int + // + // // userKey is the key for user.User values in Contexts. It is + // // unexported; clients use user.NewContext and user.FromContext + // // instead of using this key directly. + // var userKey key = 0 + // + // // NewContext returns a new Context that carries value u. + // func NewContext(ctx context.Context, u *User) context.Context { + // return context.WithValue(ctx, userKey, u) + // } + // + // // FromContext returns the User value stored in ctx, if any. + // func FromContext(ctx context.Context) (*User, bool) { + // u, ok := ctx.Value(userKey).(*User) + // return u, ok + // } + Value(key interface{}) interface{} +} + +// Canceled is the error returned by Context.Err when the context is canceled. +var Canceled = errors.New("context canceled") + +// DeadlineExceeded is the error returned by Context.Err when the context's +// deadline passes. +var DeadlineExceeded = errors.New("context deadline exceeded") + +// An emptyCtx is never canceled, has no values, and has no deadline. It is not +// struct{}, since vars of this type must have distinct addresses. +type emptyCtx int + +func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { + return +} + +func (*emptyCtx) Done() <-chan struct{} { + return nil +} + +func (*emptyCtx) Err() error { + return nil +} + +func (*emptyCtx) Value(key interface{}) interface{} { + return nil +} + +func (e *emptyCtx) String() string { + switch e { + case background: + return "context.Background" + case todo: + return "context.TODO" + } + return "unknown empty Context" +} + +var ( + background = new(emptyCtx) + todo = new(emptyCtx) +) + +// Background returns a non-nil, empty Context. It is never canceled, has no +// values, and has no deadline. It is typically used by the main function, +// initialization, and tests, and as the top-level Context for incoming +// requests. +func Background() Context { + return background +} + +// TODO returns a non-nil, empty Context. Code should use context.TODO when +// it's unclear which Context to use or it's is not yet available (because the +// surrounding function has not yet been extended to accept a Context +// parameter). TODO is recognized by static analysis tools that determine +// whether Contexts are propagated correctly in a program. +func TODO() Context { + return todo +} + +// A CancelFunc tells an operation to abandon its work. +// A CancelFunc does not wait for the work to stop. +// After the first call, subsequent calls to a CancelFunc do nothing. +type CancelFunc func() + +// WithCancel returns a copy of parent with a new Done channel. The returned +// context's Done channel is closed when the returned cancel function is called +// or when the parent context's Done channel is closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { + c := newCancelCtx(parent) + propagateCancel(parent, &c) + return &c, func() { c.cancel(true, Canceled) } +} + +// newCancelCtx returns an initialized cancelCtx. +func newCancelCtx(parent Context) cancelCtx { + return cancelCtx{ + Context: parent, + done: make(chan struct{}), + } +} + +// propagateCancel arranges for child to be canceled when parent is. +func propagateCancel(parent Context, child canceler) { + if parent.Done() == nil { + return // parent is never canceled + } + if p, ok := parentCancelCtx(parent); ok { + p.mu.Lock() + if p.err != nil { + // parent has already been canceled + child.cancel(false, p.err) + } else { + if p.children == nil { + p.children = make(map[canceler]bool) + } + p.children[child] = true + } + p.mu.Unlock() + } else { + go func() { + select { + case <-parent.Done(): + child.cancel(false, parent.Err()) + case <-child.Done(): + } + }() + } +} + +// parentCancelCtx follows a chain of parent references until it finds a +// *cancelCtx. This function understands how each of the concrete types in this +// package represents its parent. +func parentCancelCtx(parent Context) (*cancelCtx, bool) { + for { + switch c := parent.(type) { + case *cancelCtx: + return c, true + case *timerCtx: + return &c.cancelCtx, true + case *valueCtx: + parent = c.Context + default: + return nil, false + } + } +} + +// removeChild removes a context from its parent. +func removeChild(parent Context, child canceler) { + p, ok := parentCancelCtx(parent) + if !ok { + return + } + p.mu.Lock() + if p.children != nil { + delete(p.children, child) + } + p.mu.Unlock() +} + +// A canceler is a context type that can be canceled directly. The +// implementations are *cancelCtx and *timerCtx. +type canceler interface { + cancel(removeFromParent bool, err error) + Done() <-chan struct{} +} + +// A cancelCtx can be canceled. When canceled, it also cancels any children +// that implement canceler. +type cancelCtx struct { + Context + + done chan struct{} // closed by the first cancel call. + + mu sync.Mutex + children map[canceler]bool // set to nil by the first cancel call + err error // set to non-nil by the first cancel call +} + +func (c *cancelCtx) Done() <-chan struct{} { + return c.done +} + +func (c *cancelCtx) Err() error { + c.mu.Lock() + defer c.mu.Unlock() + return c.err +} + +func (c *cancelCtx) String() string { + return fmt.Sprintf("%v.WithCancel", c.Context) +} + +// cancel closes c.done, cancels each of c's children, and, if +// removeFromParent is true, removes c from its parent's children. +func (c *cancelCtx) cancel(removeFromParent bool, err error) { + if err == nil { + panic("context: internal error: missing cancel error") + } + c.mu.Lock() + if c.err != nil { + c.mu.Unlock() + return // already canceled + } + c.err = err + close(c.done) + for child := range c.children { + // NOTE: acquiring the child's lock while holding parent's lock. + child.cancel(false, err) + } + c.children = nil + c.mu.Unlock() + + if removeFromParent { + removeChild(c.Context, c) + } +} + +// WithDeadline returns a copy of the parent context with the deadline adjusted +// to be no later than d. If the parent's deadline is already earlier than d, +// WithDeadline(parent, d) is semantically equivalent to parent. The returned +// context's Done channel is closed when the deadline expires, when the returned +// cancel function is called, or when the parent context's Done channel is +// closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { + if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { + // The current deadline is already sooner than the new one. + return WithCancel(parent) + } + c := &timerCtx{ + cancelCtx: newCancelCtx(parent), + deadline: deadline, + } + propagateCancel(parent, c) + d := deadline.Sub(time.Now()) + if d <= 0 { + c.cancel(true, DeadlineExceeded) // deadline has already passed + return c, func() { c.cancel(true, Canceled) } + } + c.mu.Lock() + defer c.mu.Unlock() + if c.err == nil { + c.timer = time.AfterFunc(d, func() { + c.cancel(true, DeadlineExceeded) + }) + } + return c, func() { c.cancel(true, Canceled) } +} + +// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to +// implement Done and Err. It implements cancel by stopping its timer then +// delegating to cancelCtx.cancel. +type timerCtx struct { + cancelCtx + timer *time.Timer // Under cancelCtx.mu. + + deadline time.Time +} + +func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { + return c.deadline, true +} + +func (c *timerCtx) String() string { + return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) +} + +func (c *timerCtx) cancel(removeFromParent bool, err error) { + c.cancelCtx.cancel(false, err) + if removeFromParent { + // Remove this timerCtx from its parent cancelCtx's children. + removeChild(c.cancelCtx.Context, c) + } + c.mu.Lock() + if c.timer != nil { + c.timer.Stop() + c.timer = nil + } + c.mu.Unlock() +} + +// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete: +// +// func slowOperationWithTimeout(ctx context.Context) (Result, error) { +// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) +// defer cancel() // releases resources if slowOperation completes before timeout elapses +// return slowOperation(ctx) +// } +func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { + return WithDeadline(parent, time.Now().Add(timeout)) +} + +// WithValue returns a copy of parent in which the value associated with key is +// val. +// +// Use context Values only for request-scoped data that transits processes and +// APIs, not for passing optional parameters to functions. +func WithValue(parent Context, key interface{}, val interface{}) Context { + return &valueCtx{parent, key, val} +} + +// A valueCtx carries a key-value pair. It implements Value for that key and +// delegates all other calls to the embedded Context. +type valueCtx struct { + Context + key, val interface{} +} + +func (c *valueCtx) String() string { + return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) +} + +func (c *valueCtx) Value(key interface{}) interface{} { + if c.key == key { + return c.val + } + return c.Context.Value(key) +} diff --git a/_third_party/golang.org/x/net/context/context_test.go b/_third_party/golang.org/x/net/context/context_test.go new file mode 100644 index 0000000000..05345fc5e5 --- /dev/null +++ b/_third_party/golang.org/x/net/context/context_test.go @@ -0,0 +1,575 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package context + +import ( + "fmt" + "math/rand" + "runtime" + "strings" + "sync" + "testing" + "time" +) + +// otherContext is a Context that's not one of the types defined in context.go. +// This lets us test code paths that differ based on the underlying type of the +// Context. +type otherContext struct { + Context +} + +func TestBackground(t *testing.T) { + c := Background() + if c == nil { + t.Fatalf("Background returned nil") + } + select { + case x := <-c.Done(): + t.Errorf("<-c.Done() == %v want nothing (it should block)", x) + default: + } + if got, want := fmt.Sprint(c), "context.Background"; got != want { + t.Errorf("Background().String() = %q want %q", got, want) + } +} + +func TestTODO(t *testing.T) { + c := TODO() + if c == nil { + t.Fatalf("TODO returned nil") + } + select { + case x := <-c.Done(): + t.Errorf("<-c.Done() == %v want nothing (it should block)", x) + default: + } + if got, want := fmt.Sprint(c), "context.TODO"; got != want { + t.Errorf("TODO().String() = %q want %q", got, want) + } +} + +func TestWithCancel(t *testing.T) { + c1, cancel := WithCancel(Background()) + + if got, want := fmt.Sprint(c1), "context.Background.WithCancel"; got != want { + t.Errorf("c1.String() = %q want %q", got, want) + } + + o := otherContext{c1} + c2, _ := WithCancel(o) + contexts := []Context{c1, o, c2} + + for i, c := range contexts { + if d := c.Done(); d == nil { + t.Errorf("c[%d].Done() == %v want non-nil", i, d) + } + if e := c.Err(); e != nil { + t.Errorf("c[%d].Err() == %v want nil", i, e) + } + + select { + case x := <-c.Done(): + t.Errorf("<-c.Done() == %v want nothing (it should block)", x) + default: + } + } + + cancel() + time.Sleep(100 * time.Millisecond) // let cancelation propagate + + for i, c := range contexts { + select { + case <-c.Done(): + default: + t.Errorf("<-c[%d].Done() blocked, but shouldn't have", i) + } + if e := c.Err(); e != Canceled { + t.Errorf("c[%d].Err() == %v want %v", i, e, Canceled) + } + } +} + +func TestParentFinishesChild(t *testing.T) { + // Context tree: + // parent -> cancelChild + // parent -> valueChild -> timerChild + parent, cancel := WithCancel(Background()) + cancelChild, stop := WithCancel(parent) + defer stop() + valueChild := WithValue(parent, "key", "value") + timerChild, stop := WithTimeout(valueChild, 10000*time.Hour) + defer stop() + + select { + case x := <-parent.Done(): + t.Errorf("<-parent.Done() == %v want nothing (it should block)", x) + case x := <-cancelChild.Done(): + t.Errorf("<-cancelChild.Done() == %v want nothing (it should block)", x) + case x := <-timerChild.Done(): + t.Errorf("<-timerChild.Done() == %v want nothing (it should block)", x) + case x := <-valueChild.Done(): + t.Errorf("<-valueChild.Done() == %v want nothing (it should block)", x) + default: + } + + // The parent's children should contain the two cancelable children. + pc := parent.(*cancelCtx) + cc := cancelChild.(*cancelCtx) + tc := timerChild.(*timerCtx) + pc.mu.Lock() + if len(pc.children) != 2 || !pc.children[cc] || !pc.children[tc] { + t.Errorf("bad linkage: pc.children = %v, want %v and %v", + pc.children, cc, tc) + } + pc.mu.Unlock() + + if p, ok := parentCancelCtx(cc.Context); !ok || p != pc { + t.Errorf("bad linkage: parentCancelCtx(cancelChild.Context) = %v, %v want %v, true", p, ok, pc) + } + if p, ok := parentCancelCtx(tc.Context); !ok || p != pc { + t.Errorf("bad linkage: parentCancelCtx(timerChild.Context) = %v, %v want %v, true", p, ok, pc) + } + + cancel() + + pc.mu.Lock() + if len(pc.children) != 0 { + t.Errorf("pc.cancel didn't clear pc.children = %v", pc.children) + } + pc.mu.Unlock() + + // parent and children should all be finished. + check := func(ctx Context, name string) { + select { + case <-ctx.Done(): + default: + t.Errorf("<-%s.Done() blocked, but shouldn't have", name) + } + if e := ctx.Err(); e != Canceled { + t.Errorf("%s.Err() == %v want %v", name, e, Canceled) + } + } + check(parent, "parent") + check(cancelChild, "cancelChild") + check(valueChild, "valueChild") + check(timerChild, "timerChild") + + // WithCancel should return a canceled context on a canceled parent. + precanceledChild := WithValue(parent, "key", "value") + select { + case <-precanceledChild.Done(): + default: + t.Errorf("<-precanceledChild.Done() blocked, but shouldn't have") + } + if e := precanceledChild.Err(); e != Canceled { + t.Errorf("precanceledChild.Err() == %v want %v", e, Canceled) + } +} + +func TestChildFinishesFirst(t *testing.T) { + cancelable, stop := WithCancel(Background()) + defer stop() + for _, parent := range []Context{Background(), cancelable} { + child, cancel := WithCancel(parent) + + select { + case x := <-parent.Done(): + t.Errorf("<-parent.Done() == %v want nothing (it should block)", x) + case x := <-child.Done(): + t.Errorf("<-child.Done() == %v want nothing (it should block)", x) + default: + } + + cc := child.(*cancelCtx) + pc, pcok := parent.(*cancelCtx) // pcok == false when parent == Background() + if p, ok := parentCancelCtx(cc.Context); ok != pcok || (ok && pc != p) { + t.Errorf("bad linkage: parentCancelCtx(cc.Context) = %v, %v want %v, %v", p, ok, pc, pcok) + } + + if pcok { + pc.mu.Lock() + if len(pc.children) != 1 || !pc.children[cc] { + t.Errorf("bad linkage: pc.children = %v, cc = %v", pc.children, cc) + } + pc.mu.Unlock() + } + + cancel() + + if pcok { + pc.mu.Lock() + if len(pc.children) != 0 { + t.Errorf("child's cancel didn't remove self from pc.children = %v", pc.children) + } + pc.mu.Unlock() + } + + // child should be finished. + select { + case <-child.Done(): + default: + t.Errorf("<-child.Done() blocked, but shouldn't have") + } + if e := child.Err(); e != Canceled { + t.Errorf("child.Err() == %v want %v", e, Canceled) + } + + // parent should not be finished. + select { + case x := <-parent.Done(): + t.Errorf("<-parent.Done() == %v want nothing (it should block)", x) + default: + } + if e := parent.Err(); e != nil { + t.Errorf("parent.Err() == %v want nil", e) + } + } +} + +func testDeadline(c Context, wait time.Duration, t *testing.T) { + select { + case <-time.After(wait): + t.Fatalf("context should have timed out") + case <-c.Done(): + } + if e := c.Err(); e != DeadlineExceeded { + t.Errorf("c.Err() == %v want %v", e, DeadlineExceeded) + } +} + +func TestDeadline(t *testing.T) { + c, _ := WithDeadline(Background(), time.Now().Add(100*time.Millisecond)) + if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) { + t.Errorf("c.String() = %q want prefix %q", got, prefix) + } + testDeadline(c, 200*time.Millisecond, t) + + c, _ = WithDeadline(Background(), time.Now().Add(100*time.Millisecond)) + o := otherContext{c} + testDeadline(o, 200*time.Millisecond, t) + + c, _ = WithDeadline(Background(), time.Now().Add(100*time.Millisecond)) + o = otherContext{c} + c, _ = WithDeadline(o, time.Now().Add(300*time.Millisecond)) + testDeadline(c, 200*time.Millisecond, t) +} + +func TestTimeout(t *testing.T) { + c, _ := WithTimeout(Background(), 100*time.Millisecond) + if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) { + t.Errorf("c.String() = %q want prefix %q", got, prefix) + } + testDeadline(c, 200*time.Millisecond, t) + + c, _ = WithTimeout(Background(), 100*time.Millisecond) + o := otherContext{c} + testDeadline(o, 200*time.Millisecond, t) + + c, _ = WithTimeout(Background(), 100*time.Millisecond) + o = otherContext{c} + c, _ = WithTimeout(o, 300*time.Millisecond) + testDeadline(c, 200*time.Millisecond, t) +} + +func TestCanceledTimeout(t *testing.T) { + c, _ := WithTimeout(Background(), 200*time.Millisecond) + o := otherContext{c} + c, cancel := WithTimeout(o, 400*time.Millisecond) + cancel() + time.Sleep(100 * time.Millisecond) // let cancelation propagate + select { + case <-c.Done(): + default: + t.Errorf("<-c.Done() blocked, but shouldn't have") + } + if e := c.Err(); e != Canceled { + t.Errorf("c.Err() == %v want %v", e, Canceled) + } +} + +type key1 int +type key2 int + +var k1 = key1(1) +var k2 = key2(1) // same int as k1, different type +var k3 = key2(3) // same type as k2, different int + +func TestValues(t *testing.T) { + check := func(c Context, nm, v1, v2, v3 string) { + if v, ok := c.Value(k1).(string); ok == (len(v1) == 0) || v != v1 { + t.Errorf(`%s.Value(k1).(string) = %q, %t want %q, %t`, nm, v, ok, v1, len(v1) != 0) + } + if v, ok := c.Value(k2).(string); ok == (len(v2) == 0) || v != v2 { + t.Errorf(`%s.Value(k2).(string) = %q, %t want %q, %t`, nm, v, ok, v2, len(v2) != 0) + } + if v, ok := c.Value(k3).(string); ok == (len(v3) == 0) || v != v3 { + t.Errorf(`%s.Value(k3).(string) = %q, %t want %q, %t`, nm, v, ok, v3, len(v3) != 0) + } + } + + c0 := Background() + check(c0, "c0", "", "", "") + + c1 := WithValue(Background(), k1, "c1k1") + check(c1, "c1", "c1k1", "", "") + + if got, want := fmt.Sprint(c1), `context.Background.WithValue(1, "c1k1")`; got != want { + t.Errorf("c.String() = %q want %q", got, want) + } + + c2 := WithValue(c1, k2, "c2k2") + check(c2, "c2", "c1k1", "c2k2", "") + + c3 := WithValue(c2, k3, "c3k3") + check(c3, "c2", "c1k1", "c2k2", "c3k3") + + c4 := WithValue(c3, k1, nil) + check(c4, "c4", "", "c2k2", "c3k3") + + o0 := otherContext{Background()} + check(o0, "o0", "", "", "") + + o1 := otherContext{WithValue(Background(), k1, "c1k1")} + check(o1, "o1", "c1k1", "", "") + + o2 := WithValue(o1, k2, "o2k2") + check(o2, "o2", "c1k1", "o2k2", "") + + o3 := otherContext{c4} + check(o3, "o3", "", "c2k2", "c3k3") + + o4 := WithValue(o3, k3, nil) + check(o4, "o4", "", "c2k2", "") +} + +func TestAllocs(t *testing.T) { + bg := Background() + for _, test := range []struct { + desc string + f func() + limit float64 + gccgoLimit float64 + }{ + { + desc: "Background()", + f: func() { Background() }, + limit: 0, + gccgoLimit: 0, + }, + { + desc: fmt.Sprintf("WithValue(bg, %v, nil)", k1), + f: func() { + c := WithValue(bg, k1, nil) + c.Value(k1) + }, + limit: 3, + gccgoLimit: 3, + }, + { + desc: "WithTimeout(bg, 15*time.Millisecond)", + f: func() { + c, _ := WithTimeout(bg, 15*time.Millisecond) + <-c.Done() + }, + limit: 8, + gccgoLimit: 15, + }, + { + desc: "WithCancel(bg)", + f: func() { + c, cancel := WithCancel(bg) + cancel() + <-c.Done() + }, + limit: 5, + gccgoLimit: 8, + }, + { + desc: "WithTimeout(bg, 100*time.Millisecond)", + f: func() { + c, cancel := WithTimeout(bg, 100*time.Millisecond) + cancel() + <-c.Done() + }, + limit: 8, + gccgoLimit: 25, + }, + } { + limit := test.limit + if runtime.Compiler == "gccgo" { + // gccgo does not yet do escape analysis. + // TOOD(iant): Remove this when gccgo does do escape analysis. + limit = test.gccgoLimit + } + if n := testing.AllocsPerRun(100, test.f); n > limit { + t.Errorf("%s allocs = %f want %d", test.desc, n, int(limit)) + } + } +} + +func TestSimultaneousCancels(t *testing.T) { + root, cancel := WithCancel(Background()) + m := map[Context]CancelFunc{root: cancel} + q := []Context{root} + // Create a tree of contexts. + for len(q) != 0 && len(m) < 100 { + parent := q[0] + q = q[1:] + for i := 0; i < 4; i++ { + ctx, cancel := WithCancel(parent) + m[ctx] = cancel + q = append(q, ctx) + } + } + // Start all the cancels in a random order. + var wg sync.WaitGroup + wg.Add(len(m)) + for _, cancel := range m { + go func(cancel CancelFunc) { + cancel() + wg.Done() + }(cancel) + } + // Wait on all the contexts in a random order. + for ctx := range m { + select { + case <-ctx.Done(): + case <-time.After(1 * time.Second): + buf := make([]byte, 10<<10) + n := runtime.Stack(buf, true) + t.Fatalf("timed out waiting for <-ctx.Done(); stacks:\n%s", buf[:n]) + } + } + // Wait for all the cancel functions to return. + done := make(chan struct{}) + go func() { + wg.Wait() + close(done) + }() + select { + case <-done: + case <-time.After(1 * time.Second): + buf := make([]byte, 10<<10) + n := runtime.Stack(buf, true) + t.Fatalf("timed out waiting for cancel functions; stacks:\n%s", buf[:n]) + } +} + +func TestInterlockedCancels(t *testing.T) { + parent, cancelParent := WithCancel(Background()) + child, cancelChild := WithCancel(parent) + go func() { + parent.Done() + cancelChild() + }() + cancelParent() + select { + case <-child.Done(): + case <-time.After(1 * time.Second): + buf := make([]byte, 10<<10) + n := runtime.Stack(buf, true) + t.Fatalf("timed out waiting for child.Done(); stacks:\n%s", buf[:n]) + } +} + +func TestLayersCancel(t *testing.T) { + testLayers(t, time.Now().UnixNano(), false) +} + +func TestLayersTimeout(t *testing.T) { + testLayers(t, time.Now().UnixNano(), true) +} + +func testLayers(t *testing.T, seed int64, testTimeout bool) { + rand.Seed(seed) + errorf := func(format string, a ...interface{}) { + t.Errorf(fmt.Sprintf("seed=%d: %s", seed, format), a...) + } + const ( + timeout = 200 * time.Millisecond + minLayers = 30 + ) + type value int + var ( + vals []*value + cancels []CancelFunc + numTimers int + ctx = Background() + ) + for i := 0; i < minLayers || numTimers == 0 || len(cancels) == 0 || len(vals) == 0; i++ { + switch rand.Intn(3) { + case 0: + v := new(value) + ctx = WithValue(ctx, v, v) + vals = append(vals, v) + case 1: + var cancel CancelFunc + ctx, cancel = WithCancel(ctx) + cancels = append(cancels, cancel) + case 2: + var cancel CancelFunc + ctx, cancel = WithTimeout(ctx, timeout) + cancels = append(cancels, cancel) + numTimers++ + } + } + checkValues := func(when string) { + for _, key := range vals { + if val := ctx.Value(key).(*value); key != val { + errorf("%s: ctx.Value(%p) = %p want %p", when, key, val, key) + } + } + } + select { + case <-ctx.Done(): + errorf("ctx should not be canceled yet") + default: + } + if s, prefix := fmt.Sprint(ctx), "context.Background."; !strings.HasPrefix(s, prefix) { + t.Errorf("ctx.String() = %q want prefix %q", s, prefix) + } + t.Log(ctx) + checkValues("before cancel") + if testTimeout { + select { + case <-ctx.Done(): + case <-time.After(timeout + 100*time.Millisecond): + errorf("ctx should have timed out") + } + checkValues("after timeout") + } else { + cancel := cancels[rand.Intn(len(cancels))] + cancel() + select { + case <-ctx.Done(): + default: + errorf("ctx should be canceled") + } + checkValues("after cancel") + } +} + +func TestCancelRemoves(t *testing.T) { + checkChildren := func(when string, ctx Context, want int) { + if got := len(ctx.(*cancelCtx).children); got != want { + t.Errorf("%s: context has %d children, want %d", when, got, want) + } + } + + ctx, _ := WithCancel(Background()) + checkChildren("after creation", ctx, 0) + _, cancel := WithCancel(ctx) + checkChildren("with WithCancel child ", ctx, 1) + cancel() + checkChildren("after cancelling WithCancel child", ctx, 0) + + ctx, _ = WithCancel(Background()) + checkChildren("after creation", ctx, 0) + _, cancel = WithTimeout(ctx, 60*time.Minute) + checkChildren("with WithTimeout child ", ctx, 1) + cancel() + checkChildren("after cancelling WithTimeout child", ctx, 0) +} diff --git a/_third_party/golang.org/x/net/context/ctxhttp/cancelreq.go b/_third_party/golang.org/x/net/context/ctxhttp/cancelreq.go new file mode 100644 index 0000000000..48610e3627 --- /dev/null +++ b/_third_party/golang.org/x/net/context/ctxhttp/cancelreq.go @@ -0,0 +1,18 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.5 + +package ctxhttp + +import "net/http" + +func canceler(client *http.Client, req *http.Request) func() { + ch := make(chan struct{}) + req.Cancel = ch + + return func() { + close(ch) + } +} diff --git a/_third_party/golang.org/x/net/context/ctxhttp/cancelreq_go14.go b/_third_party/golang.org/x/net/context/ctxhttp/cancelreq_go14.go new file mode 100644 index 0000000000..56bcbadb85 --- /dev/null +++ b/_third_party/golang.org/x/net/context/ctxhttp/cancelreq_go14.go @@ -0,0 +1,23 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.5 + +package ctxhttp + +import "net/http" + +type requestCanceler interface { + CancelRequest(*http.Request) +} + +func canceler(client *http.Client, req *http.Request) func() { + rc, ok := client.Transport.(requestCanceler) + if !ok { + return func() {} + } + return func() { + rc.CancelRequest(req) + } +} diff --git a/_third_party/golang.org/x/net/context/ctxhttp/ctxhttp.go b/_third_party/golang.org/x/net/context/ctxhttp/ctxhttp.go new file mode 100644 index 0000000000..8cbcb05ede --- /dev/null +++ b/_third_party/golang.org/x/net/context/ctxhttp/ctxhttp.go @@ -0,0 +1,79 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ctxhttp provides helper functions for performing context-aware HTTP requests. +package ctxhttp // import "bosun.org/_third_party/golang.org/x/net/context/ctxhttp" + +import ( + "io" + "net/http" + "net/url" + "strings" + + "bosun.org/_third_party/golang.org/x/net/context" +) + +// Do sends an HTTP request with the provided http.Client and returns an HTTP response. +// If the client is nil, http.DefaultClient is used. +// If the context is canceled or times out, ctx.Err() will be returned. +func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { + if client == nil { + client = http.DefaultClient + } + + // Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go. + cancel := canceler(client, req) + + type responseAndError struct { + resp *http.Response + err error + } + result := make(chan responseAndError, 1) + + go func() { + resp, err := client.Do(req) + result <- responseAndError{resp, err} + }() + + select { + case <-ctx.Done(): + cancel() + return nil, ctx.Err() + case r := <-result: + return r.resp, r.err + } +} + +// Get issues a GET request via the Do function. +func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + return Do(ctx, client, req) +} + +// Head issues a HEAD request via the Do function. +func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { + req, err := http.NewRequest("HEAD", url, nil) + if err != nil { + return nil, err + } + return Do(ctx, client, req) +} + +// Post issues a POST request via the Do function. +func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { + req, err := http.NewRequest("POST", url, body) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", bodyType) + return Do(ctx, client, req) +} + +// PostForm issues a POST request via the Do function. +func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { + return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) +} diff --git a/_third_party/golang.org/x/net/context/ctxhttp/ctxhttp_test.go b/_third_party/golang.org/x/net/context/ctxhttp/ctxhttp_test.go new file mode 100644 index 0000000000..b9664bfde6 --- /dev/null +++ b/_third_party/golang.org/x/net/context/ctxhttp/ctxhttp_test.go @@ -0,0 +1,72 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ctxhttp + +import ( + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" + "time" + + "bosun.org/_third_party/golang.org/x/net/context" +) + +const ( + requestDuration = 100 * time.Millisecond + requestBody = "ok" +) + +func TestNoTimeout(t *testing.T) { + ctx := context.Background() + resp, err := doRequest(ctx) + + if resp == nil || err != nil { + t.Fatalf("error received from client: %v %v", err, resp) + } +} +func TestCancel(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + go func() { + time.Sleep(requestDuration / 2) + cancel() + }() + + resp, err := doRequest(ctx) + + if resp != nil || err == nil { + t.Fatalf("expected error, didn't get one. resp: %v", resp) + } + if err != ctx.Err() { + t.Fatalf("expected error from context but got: %v", err) + } +} + +func TestCancelAfterRequest(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + + resp, err := doRequest(ctx) + + // Cancel before reading the body. + // Request.Body should still be readable after the context is canceled. + cancel() + + b, err := ioutil.ReadAll(resp.Body) + if err != nil || string(b) != requestBody { + t.Fatalf("could not read body: %q %v", b, err) + } +} + +func doRequest(ctx context.Context) (*http.Response, error) { + var okHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + time.Sleep(requestDuration) + w.Write([]byte(requestBody)) + }) + + serv := httptest.NewServer(okHandler) + defer serv.Close() + + return Get(ctx, nil, serv.URL) +} diff --git a/_third_party/golang.org/x/net/context/withtimeout_test.go b/_third_party/golang.org/x/net/context/withtimeout_test.go new file mode 100644 index 0000000000..e61364cf90 --- /dev/null +++ b/_third_party/golang.org/x/net/context/withtimeout_test.go @@ -0,0 +1,26 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package context_test + +import ( + "fmt" + "time" + + "bosun.org/_third_party/golang.org/x/net/context" +) + +func ExampleWithTimeout() { + // Pass a context with a timeout to tell a blocking function that it + // should abandon its work after the timeout elapses. + ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond) + select { + case <-time.After(200 * time.Millisecond): + fmt.Println("overslept") + case <-ctx.Done(): + fmt.Println(ctx.Err()) // prints "context deadline exceeded" + } + // Output: + // context deadline exceeded +} diff --git a/_third_party/golang.org/x/oauth2/AUTHORS b/_third_party/golang.org/x/oauth2/AUTHORS new file mode 100644 index 0000000000..15167cd746 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/_third_party/golang.org/x/oauth2/CONTRIBUTING.md b/_third_party/golang.org/x/oauth2/CONTRIBUTING.md new file mode 100644 index 0000000000..46aa2b12dd --- /dev/null +++ b/_third_party/golang.org/x/oauth2/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing to Go + +Go is an open source project. + +It is the work of hundreds of contributors. We appreciate your help! + + +## Filing issues + +When [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions: + +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? + +General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. +The gophers there will answer or ask you to file an issue if you've tripped over a bug. + +## Contributing code + +Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) +before sending patches. + +**We do not accept GitHub pull requests** +(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). + +Unless otherwise noted, the Go source files are distributed under +the BSD-style license found in the LICENSE file. + diff --git a/_third_party/golang.org/x/oauth2/CONTRIBUTORS b/_third_party/golang.org/x/oauth2/CONTRIBUTORS new file mode 100644 index 0000000000..1c4577e968 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/_third_party/golang.org/x/oauth2/LICENSE b/_third_party/golang.org/x/oauth2/LICENSE new file mode 100644 index 0000000000..d02f24fd52 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The oauth2 Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/_third_party/golang.org/x/oauth2/README.md b/_third_party/golang.org/x/oauth2/README.md new file mode 100644 index 0000000000..a5afeca221 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/README.md @@ -0,0 +1,64 @@ +# OAuth2 for Go + +[![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2) + +oauth2 package contains a client implementation for OAuth 2.0 spec. + +## Installation + +~~~~ +go get golang.org/x/oauth2 +~~~~ + +See godoc for further documentation and examples. + +* [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2) +* [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google) + + +## App Engine + +In change 96e89be (March 2015) we removed the `oauth2.Context2` type in favor +of the [`context.Context`](https://golang.org/x/net/context#Context) type from +the `golang.org/x/net/context` package + +This means its no longer possible to use the "Classic App Engine" +`appengine.Context` type with the `oauth2` package. (You're using +Classic App Engine if you import the package `"appengine"`.) + +To work around this, you may use the new `"google.golang.org/appengine"` +package. This package has almost the same API as the `"appengine"` package, +but it can be fetched with `go get` and used on "Managed VMs" and well as +Classic App Engine. + +See the [new `appengine` package's readme](https://github.com/golang/appengine#updating-a-go-app-engine-app) +for information on updating your app. + +If you don't want to update your entire app to use the new App Engine packages, +you may use both sets of packages in parallel, using only the new packages +with the `oauth2` package. + + import ( + "golang.org/x/net/context" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + newappengine "google.golang.org/appengine" + newurlftech "google.golang.org/urlfetch" + + "appengine" + ) + + func handler(w http.ResponseWriter, r *http.Request) { + var c appengine.Context = appengine.NewContext(r) + c.Infof("Logging a message with the old package") + + var ctx context.Context = newappengine.NewContext(r) + client := &http.Client{ + Transport: &oauth2.Transport{ + Source: google.AppEngineTokenSource(ctx, "scope"), + Base: &newurlfetch.Transport{Context: ctx}, + }, + } + client.Get("...") + } + diff --git a/_third_party/golang.org/x/oauth2/client_appengine.go b/_third_party/golang.org/x/oauth2/client_appengine.go new file mode 100644 index 0000000000..76a6e5b654 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/client_appengine.go @@ -0,0 +1,24 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build appengine appenginevm + +// App Engine hooks. + +package oauth2 + +import ( + "net/http" + + "bosun.org/_third_party/golang.org/x/net/context" + "bosun.org/_third_party/google.golang.org/appengine/urlfetch" +) + +func init() { + registerContextClientFunc(contextClientAppEngine) +} + +func contextClientAppEngine(ctx context.Context) (*http.Client, error) { + return urlfetch.Client(ctx), nil +} diff --git a/_third_party/golang.org/x/oauth2/example_test.go b/_third_party/golang.org/x/oauth2/example_test.go new file mode 100644 index 0000000000..a61ed3be04 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/example_test.go @@ -0,0 +1,45 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package oauth2_test + +import ( + "fmt" + "log" + + "bosun.org/_third_party/golang.org/x/oauth2" +) + +func ExampleConfig() { + conf := &oauth2.Config{ + ClientID: "YOUR_CLIENT_ID", + ClientSecret: "YOUR_CLIENT_SECRET", + Scopes: []string{"SCOPE1", "SCOPE2"}, + Endpoint: oauth2.Endpoint{ + AuthURL: "https://provider.com/o/oauth2/auth", + TokenURL: "https://provider.com/o/oauth2/token", + }, + } + + // Redirect user to consent page to ask for permission + // for the scopes specified above. + url := conf.AuthCodeURL("state", oauth2.AccessTypeOffline) + fmt.Printf("Visit the URL for the auth dialog: %v", url) + + // Use the authorization code that is pushed to the redirect URL. + // NewTransportWithCode will do the handshake to retrieve + // an access token and initiate a Transport that is + // authorized and authenticated by the retrieved token. + var code string + if _, err := fmt.Scan(&code); err != nil { + log.Fatal(err) + } + tok, err := conf.Exchange(oauth2.NoContext, code) + if err != nil { + log.Fatal(err) + } + + client := conf.Client(oauth2.NoContext, tok) + client.Get("...") +} diff --git a/_third_party/golang.org/x/oauth2/google/appengine.go b/_third_party/golang.org/x/oauth2/google/appengine.go new file mode 100644 index 0000000000..dc46450285 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/google/appengine.go @@ -0,0 +1,83 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package google + +import ( + "sort" + "strings" + "sync" + "time" + + "bosun.org/_third_party/golang.org/x/net/context" + "bosun.org/_third_party/golang.org/x/oauth2" +) + +// Set at init time by appengine_hook.go. If nil, we're not on App Engine. +var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error) + +// AppEngineTokenSource returns a token source that fetches tokens +// issued to the current App Engine application's service account. +// If you are implementing a 3-legged OAuth 2.0 flow on App Engine +// that involves user accounts, see oauth2.Config instead. +// +// The provided context must have come from appengine.NewContext. +func AppEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource { + if appengineTokenFunc == nil { + panic("google: AppEngineTokenSource can only be used on App Engine.") + } + scopes := append([]string{}, scope...) + sort.Strings(scopes) + return &appEngineTokenSource{ + ctx: ctx, + scopes: scopes, + key: strings.Join(scopes, " "), + } +} + +// aeTokens helps the fetched tokens to be reused until their expiration. +var ( + aeTokensMu sync.Mutex + aeTokens = make(map[string]*tokenLock) // key is space-separated scopes +) + +type tokenLock struct { + mu sync.Mutex // guards t; held while fetching or updating t + t *oauth2.Token +} + +type appEngineTokenSource struct { + ctx context.Context + scopes []string + key string // to aeTokens map; space-separated scopes +} + +func (ts *appEngineTokenSource) Token() (*oauth2.Token, error) { + if appengineTokenFunc == nil { + panic("google: AppEngineTokenSource can only be used on App Engine.") + } + + aeTokensMu.Lock() + tok, ok := aeTokens[ts.key] + if !ok { + tok = &tokenLock{} + aeTokens[ts.key] = tok + } + aeTokensMu.Unlock() + + tok.mu.Lock() + defer tok.mu.Unlock() + if tok.t.Valid() { + return tok.t, nil + } + access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...) + if err != nil { + return nil, err + } + tok.t = &oauth2.Token{ + AccessToken: access, + Expiry: exp, + } + return tok.t, nil +} diff --git a/_third_party/golang.org/x/oauth2/google/appengine_hook.go b/_third_party/golang.org/x/oauth2/google/appengine_hook.go new file mode 100644 index 0000000000..e74c0788ac --- /dev/null +++ b/_third_party/golang.org/x/oauth2/google/appengine_hook.go @@ -0,0 +1,13 @@ +// Copyright 2015 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build appengine appenginevm + +package google + +import "bosun.org/_third_party/google.golang.org/appengine" + +func init() { + appengineTokenFunc = appengine.AccessToken +} diff --git a/_third_party/golang.org/x/oauth2/google/default.go b/_third_party/golang.org/x/oauth2/google/default.go new file mode 100644 index 0000000000..a5b524e780 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/google/default.go @@ -0,0 +1,154 @@ +// Copyright 2015 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package google + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "runtime" + + "bosun.org/_third_party/golang.org/x/net/context" + "bosun.org/_third_party/golang.org/x/oauth2" + "bosun.org/_third_party/golang.org/x/oauth2/jwt" + "bosun.org/_third_party/google.golang.org/cloud/compute/metadata" +) + +// DefaultClient returns an HTTP Client that uses the +// DefaultTokenSource to obtain authentication credentials. +// +// This client should be used when developing services +// that run on Google App Engine or Google Compute Engine +// and use "Application Default Credentials." +// +// For more details, see: +// https://developers.google.com/accounts/application-default-credentials +// +func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) { + ts, err := DefaultTokenSource(ctx, scope...) + if err != nil { + return nil, err + } + return oauth2.NewClient(ctx, ts), nil +} + +// DefaultTokenSource is a token source that uses +// "Application Default Credentials". +// +// It looks for credentials in the following places, +// preferring the first location found: +// +// 1. A JSON file whose path is specified by the +// GOOGLE_APPLICATION_CREDENTIALS environment variable. +// 2. A JSON file in a location known to the gcloud command-line tool. +// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json. +// On other systems, $HOME/.config/gcloud/application_default_credentials.json. +// 3. On Google App Engine it uses the appengine.AccessToken function. +// 4. On Google Compute Engine, it fetches credentials from the metadata server. +// (In this final case any provided scopes are ignored.) +// +// For more details, see: +// https://developers.google.com/accounts/application-default-credentials +// +func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) { + // First, try the environment variable. + const envVar = "GOOGLE_APPLICATION_CREDENTIALS" + if filename := os.Getenv(envVar); filename != "" { + ts, err := tokenSourceFromFile(ctx, filename, scope) + if err != nil { + return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err) + } + return ts, nil + } + + // Second, try a well-known file. + filename := wellKnownFile() + _, err := os.Stat(filename) + if err == nil { + ts, err2 := tokenSourceFromFile(ctx, filename, scope) + if err2 == nil { + return ts, nil + } + err = err2 + } else if os.IsNotExist(err) { + err = nil // ignore this error + } + if err != nil { + return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err) + } + + // Third, if we're on Google App Engine use those credentials. + if appengineTokenFunc != nil { + return AppEngineTokenSource(ctx, scope...), nil + } + + // Fourth, if we're on Google Compute Engine use the metadata server. + if metadata.OnGCE() { + return ComputeTokenSource(""), nil + } + + // None are found; return helpful error. + const url = "https://developers.google.com/accounts/application-default-credentials" + return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url) +} + +func wellKnownFile() string { + const f = "application_default_credentials.json" + if runtime.GOOS == "windows" { + return filepath.Join(os.Getenv("APPDATA"), "gcloud", f) + } + return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f) +} + +func tokenSourceFromFile(ctx context.Context, filename string, scopes []string) (oauth2.TokenSource, error) { + b, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + var d struct { + // Common fields + Type string + ClientID string `json:"client_id"` + + // User Credential fields + ClientSecret string `json:"client_secret"` + RefreshToken string `json:"refresh_token"` + + // Service Account fields + ClientEmail string `json:"client_email"` + PrivateKeyID string `json:"private_key_id"` + PrivateKey string `json:"private_key"` + } + if err := json.Unmarshal(b, &d); err != nil { + return nil, err + } + switch d.Type { + case "authorized_user": + cfg := &oauth2.Config{ + ClientID: d.ClientID, + ClientSecret: d.ClientSecret, + Scopes: append([]string{}, scopes...), // copy + Endpoint: Endpoint, + } + tok := &oauth2.Token{RefreshToken: d.RefreshToken} + return cfg.TokenSource(ctx, tok), nil + case "service_account": + cfg := &jwt.Config{ + Email: d.ClientEmail, + PrivateKey: []byte(d.PrivateKey), + Scopes: append([]string{}, scopes...), // copy + TokenURL: JWTTokenURL, + } + return cfg.TokenSource(ctx), nil + case "": + return nil, errors.New("missing 'type' field in credentials") + default: + return nil, fmt.Errorf("unknown credential type: %q", d.Type) + } +} diff --git a/_third_party/golang.org/x/oauth2/google/example_test.go b/_third_party/golang.org/x/oauth2/google/example_test.go new file mode 100644 index 0000000000..9079d595af --- /dev/null +++ b/_third_party/golang.org/x/oauth2/google/example_test.go @@ -0,0 +1,150 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build appenginevm !appengine + +package google_test + +import ( + "fmt" + "io/ioutil" + "log" + "net/http" + + "bosun.org/_third_party/golang.org/x/oauth2" + "bosun.org/_third_party/golang.org/x/oauth2/google" + "bosun.org/_third_party/golang.org/x/oauth2/jwt" + "bosun.org/_third_party/google.golang.org/appengine" + "bosun.org/_third_party/google.golang.org/appengine/urlfetch" +) + +func ExampleDefaultClient() { + client, err := google.DefaultClient(oauth2.NoContext, + "https://www.googleapis.com/auth/devstorage.full_control") + if err != nil { + log.Fatal(err) + } + client.Get("...") +} + +func Example_webServer() { + // Your credentials should be obtained from the Google + // Developer Console (https://console.developers.google.com). + conf := &oauth2.Config{ + ClientID: "YOUR_CLIENT_ID", + ClientSecret: "YOUR_CLIENT_SECRET", + RedirectURL: "YOUR_REDIRECT_URL", + Scopes: []string{ + "https://www.googleapis.com/auth/bigquery", + "https://www.googleapis.com/auth/blogger", + }, + Endpoint: google.Endpoint, + } + // Redirect user to Google's consent page to ask for permission + // for the scopes specified above. + url := conf.AuthCodeURL("state") + fmt.Printf("Visit the URL for the auth dialog: %v", url) + + // Handle the exchange code to initiate a transport. + tok, err := conf.Exchange(oauth2.NoContext, "authorization-code") + if err != nil { + log.Fatal(err) + } + client := conf.Client(oauth2.NoContext, tok) + client.Get("...") +} + +func ExampleJWTConfigFromJSON() { + // Your credentials should be obtained from the Google + // Developer Console (https://console.developers.google.com). + // Navigate to your project, then see the "Credentials" page + // under "APIs & Auth". + // To create a service account client, click "Create new Client ID", + // select "Service Account", and click "Create Client ID". A JSON + // key file will then be downloaded to your computer. + data, err := ioutil.ReadFile("/path/to/your-project-key.json") + if err != nil { + log.Fatal(err) + } + conf, err := google.JWTConfigFromJSON(data, "https://www.googleapis.com/auth/bigquery") + if err != nil { + log.Fatal(err) + } + // Initiate an http.Client. The following GET request will be + // authorized and authenticated on the behalf of + // your service account. + client := conf.Client(oauth2.NoContext) + client.Get("...") +} + +func ExampleSDKConfig() { + // The credentials will be obtained from the first account that + // has been authorized with `gcloud auth login`. + conf, err := google.NewSDKConfig("") + if err != nil { + log.Fatal(err) + } + // Initiate an http.Client. The following GET request will be + // authorized and authenticated on the behalf of the SDK user. + client := conf.Client(oauth2.NoContext) + client.Get("...") +} + +func Example_serviceAccount() { + // Your credentials should be obtained from the Google + // Developer Console (https://console.developers.google.com). + conf := &jwt.Config{ + Email: "xxx@developer.gserviceaccount.com", + // The contents of your RSA private key or your PEM file + // that contains a private key. + // If you have a p12 file instead, you + // can use `openssl` to export the private key into a pem file. + // + // $ openssl pkcs12 -in key.p12 -passin pass:notasecret -out key.pem -nodes + // + // The field only supports PEM containers with no passphrase. + // The openssl command will convert p12 keys to passphrase-less PEM containers. + PrivateKey: []byte("-----BEGIN RSA PRIVATE KEY-----..."), + Scopes: []string{ + "https://www.googleapis.com/auth/bigquery", + "https://www.googleapis.com/auth/blogger", + }, + TokenURL: google.JWTTokenURL, + // If you would like to impersonate a user, you can + // create a transport with a subject. The following GET + // request will be made on the behalf of user@example.com. + // Optional. + Subject: "user@example.com", + } + // Initiate an http.Client, the following GET request will be + // authorized and authenticated on the behalf of user@example.com. + client := conf.Client(oauth2.NoContext) + client.Get("...") +} + +func ExampleAppEngineTokenSource() { + var req *http.Request // from the ServeHTTP handler + ctx := appengine.NewContext(req) + client := &http.Client{ + Transport: &oauth2.Transport{ + Source: google.AppEngineTokenSource(ctx, "https://www.googleapis.com/auth/bigquery"), + Base: &urlfetch.Transport{ + Context: ctx, + }, + }, + } + client.Get("...") +} + +func ExampleComputeTokenSource() { + client := &http.Client{ + Transport: &oauth2.Transport{ + // Fetch from Google Compute Engine's metadata server to retrieve + // an access token for the provided account. + // If no account is specified, "default" is used. + Source: google.ComputeTokenSource(""), + }, + } + client.Get("...") +} diff --git a/_third_party/golang.org/x/oauth2/google/google.go b/_third_party/golang.org/x/oauth2/google/google.go new file mode 100644 index 0000000000..d63cffcd2b --- /dev/null +++ b/_third_party/golang.org/x/oauth2/google/google.go @@ -0,0 +1,145 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package google provides support for making OAuth2 authorized and +// authenticated HTTP requests to Google APIs. +// It supports the Web server flow, client-side credentials, service accounts, +// Google Compute Engine service accounts, and Google App Engine service +// accounts. +// +// For more information, please read +// https://developers.google.com/accounts/docs/OAuth2 +// and +// https://developers.google.com/accounts/application-default-credentials. +package google // import "bosun.org/_third_party/golang.org/x/oauth2/google" + +import ( + "encoding/json" + "errors" + "fmt" + "strings" + "time" + + "bosun.org/_third_party/golang.org/x/oauth2" + "bosun.org/_third_party/golang.org/x/oauth2/jwt" + "bosun.org/_third_party/google.golang.org/cloud/compute/metadata" +) + +// Endpoint is Google's OAuth 2.0 endpoint. +var Endpoint = oauth2.Endpoint{ + AuthURL: "https://accounts.google.com/o/oauth2/auth", + TokenURL: "https://accounts.google.com/o/oauth2/token", +} + +// JWTTokenURL is Google's OAuth 2.0 token URL to use with the JWT flow. +const JWTTokenURL = "https://accounts.google.com/o/oauth2/token" + +// ConfigFromJSON uses a Google Developers Console client_credentials.json +// file to construct a config. +// client_credentials.json can be downloadable from https://console.developers.google.com, +// under "APIs & Auth" > "Credentials". Download the Web application credentials in the +// JSON format and provide the contents of the file as jsonKey. +func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) { + type cred struct { + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + RedirectURIs []string `json:"redirect_uris"` + AuthURI string `json:"auth_uri"` + TokenURI string `json:"token_uri"` + } + var j struct { + Web *cred `json:"web"` + Installed *cred `json:"installed"` + } + if err := json.Unmarshal(jsonKey, &j); err != nil { + return nil, err + } + var c *cred + switch { + case j.Web != nil: + c = j.Web + case j.Installed != nil: + c = j.Installed + default: + return nil, fmt.Errorf("oauth2/google: no credentials found") + } + if len(c.RedirectURIs) < 1 { + return nil, errors.New("oauth2/google: missing redirect URL in the client_credentials.json") + } + return &oauth2.Config{ + ClientID: c.ClientID, + ClientSecret: c.ClientSecret, + RedirectURL: c.RedirectURIs[0], + Scopes: scope, + Endpoint: oauth2.Endpoint{ + AuthURL: c.AuthURI, + TokenURL: c.TokenURI, + }, + }, nil +} + +// JWTConfigFromJSON uses a Google Developers service account JSON key file to read +// the credentials that authorize and authenticate the requests. +// Create a service account on "Credentials" page under "APIs & Auth" for your +// project at https://console.developers.google.com to download a JSON key file. +func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) { + var key struct { + Email string `json:"client_email"` + PrivateKey string `json:"private_key"` + } + if err := json.Unmarshal(jsonKey, &key); err != nil { + return nil, err + } + return &jwt.Config{ + Email: key.Email, + PrivateKey: []byte(key.PrivateKey), + Scopes: scope, + TokenURL: JWTTokenURL, + }, nil +} + +// ComputeTokenSource returns a token source that fetches access tokens +// from Google Compute Engine (GCE)'s metadata server. It's only valid to use +// this token source if your program is running on a GCE instance. +// If no account is specified, "default" is used. +// Further information about retrieving access tokens from the GCE metadata +// server can be found at https://cloud.google.com/compute/docs/authentication. +func ComputeTokenSource(account string) oauth2.TokenSource { + return oauth2.ReuseTokenSource(nil, computeSource{account: account}) +} + +type computeSource struct { + account string +} + +func (cs computeSource) Token() (*oauth2.Token, error) { + if !metadata.OnGCE() { + return nil, errors.New("oauth2/google: can't get a token from the metadata service; not running on GCE") + } + acct := cs.account + if acct == "" { + acct = "default" + } + tokenJSON, err := metadata.Get("instance/service-accounts/" + acct + "/token") + if err != nil { + return nil, err + } + var res struct { + AccessToken string `json:"access_token"` + ExpiresInSec int `json:"expires_in"` + TokenType string `json:"token_type"` + } + err = json.NewDecoder(strings.NewReader(tokenJSON)).Decode(&res) + if err != nil { + return nil, fmt.Errorf("oauth2/google: invalid token JSON from metadata: %v", err) + } + if res.ExpiresInSec == 0 || res.AccessToken == "" { + return nil, fmt.Errorf("oauth2/google: incomplete token received from metadata") + } + return &oauth2.Token{ + AccessToken: res.AccessToken, + TokenType: res.TokenType, + Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second), + }, nil +} diff --git a/_third_party/golang.org/x/oauth2/google/google_test.go b/_third_party/golang.org/x/oauth2/google/google_test.go new file mode 100644 index 0000000000..4cc01884b2 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/google/google_test.go @@ -0,0 +1,67 @@ +// Copyright 2015 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package google + +import ( + "strings" + "testing" +) + +var webJSONKey = []byte(` +{ + "web": { + "auth_uri": "https://google.com/o/oauth2/auth", + "client_secret": "3Oknc4jS_wA2r9i", + "token_uri": "https://google.com/o/oauth2/token", + "client_email": "222-nprqovg5k43uum874cs9osjt2koe97g8@developer.gserviceaccount.com", + "redirect_uris": ["https://www.example.com/oauth2callback"], + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/222-nprqovg5k43uum874cs9osjt2koe97g8@developer.gserviceaccount.com", + "client_id": "222-nprqovg5k43uum874cs9osjt2koe97g8.apps.googleusercontent.com", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "javascript_origins": ["https://www.example.com"] + } +}`) + +var installedJSONKey = []byte(`{ + "installed": { + "client_id": "222-installed.apps.googleusercontent.com", + "redirect_uris": ["https://www.example.com/oauth2callback"] + } +}`) + +func TestConfigFromJSON(t *testing.T) { + conf, err := ConfigFromJSON(webJSONKey, "scope1", "scope2") + if err != nil { + t.Error(err) + } + if got, want := conf.ClientID, "222-nprqovg5k43uum874cs9osjt2koe97g8.apps.googleusercontent.com"; got != want { + t.Errorf("ClientID = %q; want %q", got, want) + } + if got, want := conf.ClientSecret, "3Oknc4jS_wA2r9i"; got != want { + t.Errorf("ClientSecret = %q; want %q", got, want) + } + if got, want := conf.RedirectURL, "https://www.example.com/oauth2callback"; got != want { + t.Errorf("RedictURL = %q; want %q", got, want) + } + if got, want := strings.Join(conf.Scopes, ","), "scope1,scope2"; got != want { + t.Errorf("Scopes = %q; want %q", got, want) + } + if got, want := conf.Endpoint.AuthURL, "https://google.com/o/oauth2/auth"; got != want { + t.Errorf("AuthURL = %q; want %q", got, want) + } + if got, want := conf.Endpoint.TokenURL, "https://google.com/o/oauth2/token"; got != want { + t.Errorf("TokenURL = %q; want %q", got, want) + } +} + +func TestConfigFromJSON_Installed(t *testing.T) { + conf, err := ConfigFromJSON(installedJSONKey) + if err != nil { + t.Error(err) + } + if got, want := conf.ClientID, "222-installed.apps.googleusercontent.com"; got != want { + t.Errorf("ClientID = %q; want %q", got, want) + } +} diff --git a/_third_party/golang.org/x/oauth2/google/sdk.go b/_third_party/golang.org/x/oauth2/google/sdk.go new file mode 100644 index 0000000000..4ad857bf8d --- /dev/null +++ b/_third_party/golang.org/x/oauth2/google/sdk.go @@ -0,0 +1,168 @@ +// Copyright 2015 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package google + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "os" + "os/user" + "path/filepath" + "runtime" + "strings" + "time" + + "bosun.org/_third_party/golang.org/x/net/context" + "bosun.org/_third_party/golang.org/x/oauth2" + "bosun.org/_third_party/golang.org/x/oauth2/internal" +) + +type sdkCredentials struct { + Data []struct { + Credential struct { + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + TokenExpiry *time.Time `json:"token_expiry"` + } `json:"credential"` + Key struct { + Account string `json:"account"` + Scope string `json:"scope"` + } `json:"key"` + } +} + +// An SDKConfig provides access to tokens from an account already +// authorized via the Google Cloud SDK. +type SDKConfig struct { + conf oauth2.Config + initialToken *oauth2.Token +} + +// NewSDKConfig creates an SDKConfig for the given Google Cloud SDK +// account. If account is empty, the account currently active in +// Google Cloud SDK properties is used. +// Google Cloud SDK credentials must be created by running `gcloud auth` +// before using this function. +// The Google Cloud SDK is available at https://cloud.google.com/sdk/. +func NewSDKConfig(account string) (*SDKConfig, error) { + configPath, err := sdkConfigPath() + if err != nil { + return nil, fmt.Errorf("oauth2/google: error getting SDK config path: %v", err) + } + credentialsPath := filepath.Join(configPath, "credentials") + f, err := os.Open(credentialsPath) + if err != nil { + return nil, fmt.Errorf("oauth2/google: failed to load SDK credentials: %v", err) + } + defer f.Close() + + var c sdkCredentials + if err := json.NewDecoder(f).Decode(&c); err != nil { + return nil, fmt.Errorf("oauth2/google: failed to decode SDK credentials from %q: %v", credentialsPath, err) + } + if len(c.Data) == 0 { + return nil, fmt.Errorf("oauth2/google: no credentials found in %q, run `gcloud auth login` to create one", credentialsPath) + } + if account == "" { + propertiesPath := filepath.Join(configPath, "properties") + f, err := os.Open(propertiesPath) + if err != nil { + return nil, fmt.Errorf("oauth2/google: failed to load SDK properties: %v", err) + } + defer f.Close() + ini, err := internal.ParseINI(f) + if err != nil { + return nil, fmt.Errorf("oauth2/google: failed to parse SDK properties %q: %v", propertiesPath, err) + } + core, ok := ini["core"] + if !ok { + return nil, fmt.Errorf("oauth2/google: failed to find [core] section in %v", ini) + } + active, ok := core["account"] + if !ok { + return nil, fmt.Errorf("oauth2/google: failed to find %q attribute in %v", "account", core) + } + account = active + } + + for _, d := range c.Data { + if account == "" || d.Key.Account == account { + if d.Credential.AccessToken == "" && d.Credential.RefreshToken == "" { + return nil, fmt.Errorf("oauth2/google: no token available for account %q", account) + } + var expiry time.Time + if d.Credential.TokenExpiry != nil { + expiry = *d.Credential.TokenExpiry + } + return &SDKConfig{ + conf: oauth2.Config{ + ClientID: d.Credential.ClientID, + ClientSecret: d.Credential.ClientSecret, + Scopes: strings.Split(d.Key.Scope, " "), + Endpoint: Endpoint, + RedirectURL: "oob", + }, + initialToken: &oauth2.Token{ + AccessToken: d.Credential.AccessToken, + RefreshToken: d.Credential.RefreshToken, + Expiry: expiry, + }, + }, nil + } + } + return nil, fmt.Errorf("oauth2/google: no such credentials for account %q", account) +} + +// Client returns an HTTP client using Google Cloud SDK credentials to +// authorize requests. The token will auto-refresh as necessary. The +// underlying http.RoundTripper will be obtained using the provided +// context. The returned client and its Transport should not be +// modified. +func (c *SDKConfig) Client(ctx context.Context) *http.Client { + return &http.Client{ + Transport: &oauth2.Transport{ + Source: c.TokenSource(ctx), + }, + } +} + +// TokenSource returns an oauth2.TokenSource that retrieve tokens from +// Google Cloud SDK credentials using the provided context. +// It will returns the current access token stored in the credentials, +// and refresh it when it expires, but it won't update the credentials +// with the new access token. +func (c *SDKConfig) TokenSource(ctx context.Context) oauth2.TokenSource { + return c.conf.TokenSource(ctx, c.initialToken) +} + +// Scopes are the OAuth 2.0 scopes the current account is authorized for. +func (c *SDKConfig) Scopes() []string { + return c.conf.Scopes +} + +// sdkConfigPath tries to guess where the gcloud config is located. +// It can be overridden during tests. +var sdkConfigPath = func() (string, error) { + if runtime.GOOS == "windows" { + return filepath.Join(os.Getenv("APPDATA"), "gcloud"), nil + } + homeDir := guessUnixHomeDir() + if homeDir == "" { + return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty") + } + return filepath.Join(homeDir, ".config", "gcloud"), nil +} + +func guessUnixHomeDir() string { + usr, err := user.Current() + if err == nil { + return usr.HomeDir + } + return os.Getenv("HOME") +} diff --git a/_third_party/golang.org/x/oauth2/google/sdk_test.go b/_third_party/golang.org/x/oauth2/google/sdk_test.go new file mode 100644 index 0000000000..79df889644 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/google/sdk_test.go @@ -0,0 +1,46 @@ +// Copyright 2015 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package google + +import "testing" + +func TestSDKConfig(t *testing.T) { + sdkConfigPath = func() (string, error) { + return "testdata/gcloud", nil + } + + tests := []struct { + account string + accessToken string + err bool + }{ + {"", "bar_access_token", false}, + {"foo@example.com", "foo_access_token", false}, + {"bar@example.com", "bar_access_token", false}, + {"baz@serviceaccount.example.com", "", true}, + } + for _, tt := range tests { + c, err := NewSDKConfig(tt.account) + if got, want := err != nil, tt.err; got != want { + if !tt.err { + t.Errorf("expected no error, got error: %v", tt.err, err) + } else { + t.Errorf("expected error, got none") + } + continue + } + if err != nil { + continue + } + tok := c.initialToken + if tok == nil { + t.Errorf("expected token %q, got: nil", tt.accessToken) + continue + } + if tok.AccessToken != tt.accessToken { + t.Errorf("expected token %q, got: %q", tt.accessToken, tok.AccessToken) + } + } +} diff --git a/_third_party/golang.org/x/oauth2/internal/oauth2.go b/_third_party/golang.org/x/oauth2/internal/oauth2.go new file mode 100644 index 0000000000..37571a1292 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/internal/oauth2.go @@ -0,0 +1,69 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package internal contains support packages for oauth2 package. +package internal + +import ( + "bufio" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" + "fmt" + "io" + "strings" +) + +// ParseKey converts the binary contents of a private key file +// to an *rsa.PrivateKey. It detects whether the private key is in a +// PEM container or not. If so, it extracts the the private key +// from PEM container before conversion. It only supports PEM +// containers with no passphrase. +func ParseKey(key []byte) (*rsa.PrivateKey, error) { + block, _ := pem.Decode(key) + if block != nil { + key = block.Bytes + } + parsedKey, err := x509.ParsePKCS8PrivateKey(key) + if err != nil { + parsedKey, err = x509.ParsePKCS1PrivateKey(key) + if err != nil { + return nil, fmt.Errorf("private key should be a PEM or plain PKSC1 or PKCS8; parse error: %v", err) + } + } + parsed, ok := parsedKey.(*rsa.PrivateKey) + if !ok { + return nil, errors.New("private key is invalid") + } + return parsed, nil +} + +func ParseINI(ini io.Reader) (map[string]map[string]string, error) { + result := map[string]map[string]string{ + "": map[string]string{}, // root section + } + scanner := bufio.NewScanner(ini) + currentSection := "" + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if strings.HasPrefix(line, ";") { + // comment. + continue + } + if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { + currentSection = strings.TrimSpace(line[1 : len(line)-1]) + result[currentSection] = map[string]string{} + continue + } + parts := strings.SplitN(line, "=", 2) + if len(parts) == 2 && parts[0] != "" { + result[currentSection][strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1]) + } + } + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("error scanning ini: %v", err) + } + return result, nil +} diff --git a/_third_party/golang.org/x/oauth2/internal/oauth2_test.go b/_third_party/golang.org/x/oauth2/internal/oauth2_test.go new file mode 100644 index 0000000000..014a351e00 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/internal/oauth2_test.go @@ -0,0 +1,62 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package internal contains support packages for oauth2 package. +package internal + +import ( + "reflect" + "strings" + "testing" +) + +func TestParseINI(t *testing.T) { + tests := []struct { + ini string + want map[string]map[string]string + }{ + { + `root = toor +[foo] +bar = hop +ini = nin +`, + map[string]map[string]string{ + "": map[string]string{"root": "toor"}, + "foo": map[string]string{"bar": "hop", "ini": "nin"}, + }, + }, + { + `[empty] +[section] +empty= +`, + map[string]map[string]string{ + "": map[string]string{}, + "empty": map[string]string{}, + "section": map[string]string{"empty": ""}, + }, + }, + { + `ignore +[invalid +=stuff +;comment=true +`, + map[string]map[string]string{ + "": map[string]string{}, + }, + }, + } + for _, tt := range tests { + result, err := ParseINI(strings.NewReader(tt.ini)) + if err != nil { + t.Errorf("ParseINI(%q) error %v, want: no error", tt.ini, err) + continue + } + if !reflect.DeepEqual(result, tt.want) { + t.Errorf("ParseINI(%q) = %#v, want: %#v", tt.ini, result, tt.want) + } + } +} diff --git a/_third_party/golang.org/x/oauth2/jws/jws.go b/_third_party/golang.org/x/oauth2/jws/jws.go new file mode 100644 index 0000000000..eab8454477 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/jws/jws.go @@ -0,0 +1,160 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package jws provides encoding and decoding utilities for +// signed JWS messages. +package jws // import "bosun.org/_third_party/golang.org/x/oauth2/jws" + +import ( + "bytes" + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "strings" + "time" +) + +// ClaimSet contains information about the JWT signature including the +// permissions being requested (scopes), the target of the token, the issuer, +// the time the token was issued, and the lifetime of the token. +type ClaimSet struct { + Iss string `json:"iss"` // email address of the client_id of the application making the access token request + Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests + Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional). + Exp int64 `json:"exp"` // the expiration time of the assertion + Iat int64 `json:"iat"` // the time the assertion was issued. + Typ string `json:"typ,omitempty"` // token type (Optional). + + // Email for which the application is requesting delegated access (Optional). + Sub string `json:"sub,omitempty"` + + // The old name of Sub. Client keeps setting Prn to be + // complaint with legacy OAuth 2.0 providers. (Optional) + Prn string `json:"prn,omitempty"` + + // See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3 + // This array is marshalled using custom code (see (c *ClaimSet) encode()). + PrivateClaims map[string]interface{} `json:"-"` + + exp time.Time + iat time.Time +} + +func (c *ClaimSet) encode() (string, error) { + if c.exp.IsZero() || c.iat.IsZero() { + // Reverting time back for machines whose time is not perfectly in sync. + // If client machine's time is in the future according + // to Google servers, an access token will not be issued. + now := time.Now().Add(-10 * time.Second) + c.iat = now + c.exp = now.Add(time.Hour) + } + + c.Exp = c.exp.Unix() + c.Iat = c.iat.Unix() + + b, err := json.Marshal(c) + if err != nil { + return "", err + } + + if len(c.PrivateClaims) == 0 { + return base64Encode(b), nil + } + + // Marshal private claim set and then append it to b. + prv, err := json.Marshal(c.PrivateClaims) + if err != nil { + return "", fmt.Errorf("jws: invalid map of private claims %v", c.PrivateClaims) + } + + // Concatenate public and private claim JSON objects. + if !bytes.HasSuffix(b, []byte{'}'}) { + return "", fmt.Errorf("jws: invalid JSON %s", b) + } + if !bytes.HasPrefix(prv, []byte{'{'}) { + return "", fmt.Errorf("jws: invalid JSON %s", prv) + } + b[len(b)-1] = ',' // Replace closing curly brace with a comma. + b = append(b, prv[1:]...) // Append private claims. + return base64Encode(b), nil +} + +// Header represents the header for the signed JWS payloads. +type Header struct { + // The algorithm used for signature. + Algorithm string `json:"alg"` + + // Represents the token type. + Typ string `json:"typ"` +} + +func (h *Header) encode() (string, error) { + b, err := json.Marshal(h) + if err != nil { + return "", err + } + return base64Encode(b), nil +} + +// Decode decodes a claim set from a JWS payload. +func Decode(payload string) (*ClaimSet, error) { + // decode returned id token to get expiry + s := strings.Split(payload, ".") + if len(s) < 2 { + // TODO(jbd): Provide more context about the error. + return nil, errors.New("jws: invalid token received") + } + decoded, err := base64Decode(s[1]) + if err != nil { + return nil, err + } + c := &ClaimSet{} + err = json.NewDecoder(bytes.NewBuffer(decoded)).Decode(c) + return c, err +} + +// Encode encodes a signed JWS with provided header and claim set. +func Encode(header *Header, c *ClaimSet, signature *rsa.PrivateKey) (string, error) { + head, err := header.encode() + if err != nil { + return "", err + } + cs, err := c.encode() + if err != nil { + return "", err + } + ss := fmt.Sprintf("%s.%s", head, cs) + h := sha256.New() + h.Write([]byte(ss)) + b, err := rsa.SignPKCS1v15(rand.Reader, signature, crypto.SHA256, h.Sum(nil)) + if err != nil { + return "", err + } + sig := base64Encode(b) + return fmt.Sprintf("%s.%s", ss, sig), nil +} + +// base64Encode returns and Base64url encoded version of the input string with any +// trailing "=" stripped. +func base64Encode(b []byte) string { + return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=") +} + +// base64Decode decodes the Base64url encoded string +func base64Decode(s string) ([]byte, error) { + // add back missing padding + switch len(s) % 4 { + case 2: + s += "==" + case 3: + s += "=" + } + return base64.URLEncoding.DecodeString(s) +} diff --git a/_third_party/golang.org/x/oauth2/jwt/example_test.go b/_third_party/golang.org/x/oauth2/jwt/example_test.go new file mode 100644 index 0000000000..de061539e0 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/jwt/example_test.go @@ -0,0 +1,31 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jwt_test + +import ( + "bosun.org/_third_party/golang.org/x/oauth2" + "bosun.org/_third_party/golang.org/x/oauth2/jwt" +) + +func ExampleJWTConfig() { + conf := &jwt.Config{ + Email: "xxx@developer.com", + // The contents of your RSA private key or your PEM file + // that contains a private key. + // If you have a p12 file instead, you + // can use `openssl` to export the private key into a pem file. + // + // $ openssl pkcs12 -in key.p12 -out key.pem -nodes + // + // It only supports PEM containers with no passphrase. + PrivateKey: []byte("-----BEGIN RSA PRIVATE KEY-----..."), + Subject: "user@example.com", + TokenURL: "https://provider.com/o/oauth2/token", + } + // Initiate an http.Client, the following GET request will be + // authorized and authenticated on the behalf of user@example.com. + client := conf.Client(oauth2.NoContext) + client.Get("...") +} diff --git a/_third_party/golang.org/x/oauth2/jwt/jwt.go b/_third_party/golang.org/x/oauth2/jwt/jwt.go new file mode 100644 index 0000000000..c6bf3f8d02 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/jwt/jwt.go @@ -0,0 +1,147 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package jwt implements the OAuth 2.0 JSON Web Token flow, commonly +// known as "two-legged OAuth 2.0". +// +// See: https://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12 +package jwt + +import ( + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strings" + "time" + + "bosun.org/_third_party/golang.org/x/net/context" + "bosun.org/_third_party/golang.org/x/oauth2" + "bosun.org/_third_party/golang.org/x/oauth2/internal" + "bosun.org/_third_party/golang.org/x/oauth2/jws" +) + +var ( + defaultGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer" + defaultHeader = &jws.Header{Algorithm: "RS256", Typ: "JWT"} +) + +// Config is the configuration for using JWT to fetch tokens, +// commonly known as "two-legged OAuth 2.0". +type Config struct { + // Email is the OAuth client identifier used when communicating with + // the configured OAuth provider. + Email string + + // PrivateKey contains the contents of an RSA private key or the + // contents of a PEM file that contains a private key. The provided + // private key is used to sign JWT payloads. + // PEM containers with a passphrase are not supported. + // Use the following command to convert a PKCS 12 file into a PEM. + // + // $ openssl pkcs12 -in key.p12 -out key.pem -nodes + // + PrivateKey []byte + + // Subject is the optional user to impersonate. + Subject string + + // Scopes optionally specifies a list of requested permission scopes. + Scopes []string + + // TokenURL is the endpoint required to complete the 2-legged JWT flow. + TokenURL string +} + +// TokenSource returns a JWT TokenSource using the configuration +// in c and the HTTP client from the provided context. +func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource { + return oauth2.ReuseTokenSource(nil, jwtSource{ctx, c}) +} + +// Client returns an HTTP client wrapping the context's +// HTTP transport and adding Authorization headers with tokens +// obtained from c. +// +// The returned client and its Transport should not be modified. +func (c *Config) Client(ctx context.Context) *http.Client { + return oauth2.NewClient(ctx, c.TokenSource(ctx)) +} + +// jwtSource is a source that always does a signed JWT request for a token. +// It should typically be wrapped with a reuseTokenSource. +type jwtSource struct { + ctx context.Context + conf *Config +} + +func (js jwtSource) Token() (*oauth2.Token, error) { + pk, err := internal.ParseKey(js.conf.PrivateKey) + if err != nil { + return nil, err + } + hc := oauth2.NewClient(js.ctx, nil) + claimSet := &jws.ClaimSet{ + Iss: js.conf.Email, + Scope: strings.Join(js.conf.Scopes, " "), + Aud: js.conf.TokenURL, + } + if subject := js.conf.Subject; subject != "" { + claimSet.Sub = subject + // prn is the old name of sub. Keep setting it + // to be compatible with legacy OAuth 2.0 providers. + claimSet.Prn = subject + } + payload, err := jws.Encode(defaultHeader, claimSet, pk) + if err != nil { + return nil, err + } + v := url.Values{} + v.Set("grant_type", defaultGrantType) + v.Set("assertion", payload) + resp, err := hc.PostForm(js.conf.TokenURL, v) + if err != nil { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) + } + if c := resp.StatusCode; c < 200 || c > 299 { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v\nResponse: %s", resp.Status, body) + } + // tokenRes is the JSON response body. + var tokenRes struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + IDToken string `json:"id_token"` + ExpiresIn int64 `json:"expires_in"` // relative seconds from now + } + if err := json.Unmarshal(body, &tokenRes); err != nil { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) + } + token := &oauth2.Token{ + AccessToken: tokenRes.AccessToken, + TokenType: tokenRes.TokenType, + } + raw := make(map[string]interface{}) + json.Unmarshal(body, &raw) // no error checks for optional fields + token = token.WithExtra(raw) + + if secs := tokenRes.ExpiresIn; secs > 0 { + token.Expiry = time.Now().Add(time.Duration(secs) * time.Second) + } + if v := tokenRes.IDToken; v != "" { + // decode returned id token to get expiry + claimSet, err := jws.Decode(v) + if err != nil { + return nil, fmt.Errorf("oauth2: error decoding JWT token: %v", err) + } + token.Expiry = time.Unix(claimSet.Exp, 0) + } + return token, nil +} diff --git a/_third_party/golang.org/x/oauth2/jwt/jwt_test.go b/_third_party/golang.org/x/oauth2/jwt/jwt_test.go new file mode 100644 index 0000000000..05fd32f63b --- /dev/null +++ b/_third_party/golang.org/x/oauth2/jwt/jwt_test.go @@ -0,0 +1,134 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jwt + +import ( + "net/http" + "net/http/httptest" + "testing" + + "bosun.org/_third_party/golang.org/x/oauth2" +) + +var dummyPrivateKey = []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAx4fm7dngEmOULNmAs1IGZ9Apfzh+BkaQ1dzkmbUgpcoghucE +DZRnAGd2aPyB6skGMXUytWQvNYav0WTR00wFtX1ohWTfv68HGXJ8QXCpyoSKSSFY +fuP9X36wBSkSX9J5DVgiuzD5VBdzUISSmapjKm+DcbRALjz6OUIPEWi1Tjl6p5RK +1w41qdbmt7E5/kGhKLDuT7+M83g4VWhgIvaAXtnhklDAggilPPa8ZJ1IFe31lNlr +k4DRk38nc6sEutdf3RL7QoH7FBusI7uXV03DC6dwN1kP4GE7bjJhcRb/7jYt7CQ9 +/E9Exz3c0yAp0yrTg0Fwh+qxfH9dKwN52S7SBwIDAQABAoIBAQCaCs26K07WY5Jt +3a2Cw3y2gPrIgTCqX6hJs7O5ByEhXZ8nBwsWANBUe4vrGaajQHdLj5OKfsIDrOvn +2NI1MqflqeAbu/kR32q3tq8/Rl+PPiwUsW3E6Pcf1orGMSNCXxeducF2iySySzh3 +nSIhCG5uwJDWI7a4+9KiieFgK1pt/Iv30q1SQS8IEntTfXYwANQrfKUVMmVF9aIK +6/WZE2yd5+q3wVVIJ6jsmTzoDCX6QQkkJICIYwCkglmVy5AeTckOVwcXL0jqw5Kf +5/soZJQwLEyBoQq7Kbpa26QHq+CJONetPP8Ssy8MJJXBT+u/bSseMb3Zsr5cr43e +DJOhwsThAoGBAPY6rPKl2NT/K7XfRCGm1sbWjUQyDShscwuWJ5+kD0yudnT/ZEJ1 +M3+KS/iOOAoHDdEDi9crRvMl0UfNa8MAcDKHflzxg2jg/QI+fTBjPP5GOX0lkZ9g +z6VePoVoQw2gpPFVNPPTxKfk27tEzbaffvOLGBEih0Kb7HTINkW8rIlzAoGBAM9y +1yr+jvfS1cGFtNU+Gotoihw2eMKtIqR03Yn3n0PK1nVCDKqwdUqCypz4+ml6cxRK +J8+Pfdh7D+ZJd4LEG6Y4QRDLuv5OA700tUoSHxMSNn3q9As4+T3MUyYxWKvTeu3U +f2NWP9ePU0lV8ttk7YlpVRaPQmc1qwooBA/z/8AdAoGAW9x0HWqmRICWTBnpjyxx +QGlW9rQ9mHEtUotIaRSJ6K/F3cxSGUEkX1a3FRnp6kPLcckC6NlqdNgNBd6rb2rA +cPl/uSkZP42Als+9YMoFPU/xrrDPbUhu72EDrj3Bllnyb168jKLa4VBOccUvggxr +Dm08I1hgYgdN5huzs7y6GeUCgYEAj+AZJSOJ6o1aXS6rfV3mMRve9bQ9yt8jcKXw +5HhOCEmMtaSKfnOF1Ziih34Sxsb7O2428DiX0mV/YHtBnPsAJidL0SdLWIapBzeg +KHArByIRkwE6IvJvwpGMdaex1PIGhx5i/3VZL9qiq/ElT05PhIb+UXgoWMabCp84 +OgxDK20CgYAeaFo8BdQ7FmVX2+EEejF+8xSge6WVLtkaon8bqcn6P0O8lLypoOhd +mJAYH8WU+UAy9pecUnDZj14LAGNVmYcse8HFX71MoshnvCTFEPVo4rZxIAGwMpeJ +5jgQ3slYLpqrGlcbLgUXBUgzEO684Wk/UV9DFPlHALVqCfXQ9dpJPg== +-----END RSA PRIVATE KEY-----`) + +func TestJWTFetch_JSONResponse(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{ + "access_token": "90d64460d14870c08c81352a05dedd3465940a7c", + "scope": "user", + "token_type": "bearer", + "expires_in": 3600 + }`)) + })) + defer ts.Close() + + conf := &Config{ + Email: "aaa@xxx.com", + PrivateKey: dummyPrivateKey, + TokenURL: ts.URL, + } + tok, err := conf.TokenSource(oauth2.NoContext).Token() + if err != nil { + t.Fatal(err) + } + if !tok.Valid() { + t.Errorf("Token invalid") + } + if tok.AccessToken != "90d64460d14870c08c81352a05dedd3465940a7c" { + t.Errorf("Unexpected access token, %#v", tok.AccessToken) + } + if tok.TokenType != "bearer" { + t.Errorf("Unexpected token type, %#v", tok.TokenType) + } + if tok.Expiry.IsZero() { + t.Errorf("Unexpected token expiry, %#v", tok.Expiry) + } + scope := tok.Extra("scope") + if scope != "user" { + t.Errorf("Unexpected value for scope: %v", scope) + } +} + +func TestJWTFetch_BadResponse(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"scope": "user", "token_type": "bearer"}`)) + })) + defer ts.Close() + + conf := &Config{ + Email: "aaa@xxx.com", + PrivateKey: dummyPrivateKey, + TokenURL: ts.URL, + } + tok, err := conf.TokenSource(oauth2.NoContext).Token() + if err != nil { + t.Fatal(err) + } + if tok == nil { + t.Fatalf("token is nil") + } + if tok.Valid() { + t.Errorf("token is valid. want invalid.") + } + if tok.AccessToken != "" { + t.Errorf("Unexpected non-empty access token %q.", tok.AccessToken) + } + if want := "bearer"; tok.TokenType != want { + t.Errorf("TokenType = %q; want %q", tok.TokenType, want) + } + scope := tok.Extra("scope") + if want := "user"; scope != want { + t.Errorf("token scope = %q; want %q", scope, want) + } +} + +func TestJWTFetch_BadResponseType(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"access_token":123, "scope": "user", "token_type": "bearer"}`)) + })) + defer ts.Close() + conf := &Config{ + Email: "aaa@xxx.com", + PrivateKey: dummyPrivateKey, + TokenURL: ts.URL, + } + tok, err := conf.TokenSource(oauth2.NoContext).Token() + if err == nil { + t.Error("got a token; expected error") + if tok.AccessToken != "" { + t.Errorf("Unexpected access token, %#v.", tok.AccessToken) + } + } +} diff --git a/_third_party/golang.org/x/oauth2/oauth2.go b/_third_party/golang.org/x/oauth2/oauth2.go new file mode 100644 index 0000000000..fccfd35260 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/oauth2.go @@ -0,0 +1,523 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package oauth2 provides support for making +// OAuth2 authorized and authenticated HTTP requests. +// It can additionally grant authorization with Bearer JWT. +package oauth2 // import "bosun.org/_third_party/golang.org/x/oauth2" + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "mime" + "net/http" + "net/url" + "strconv" + "strings" + "sync" + "time" + + "bosun.org/_third_party/golang.org/x/net/context" +) + +// NoContext is the default context you should supply if not using +// your own context.Context (see https://golang.org/x/net/context). +var NoContext = context.TODO() + +// Config describes a typical 3-legged OAuth2 flow, with both the +// client application information and the server's endpoint URLs. +type Config struct { + // ClientID is the application's ID. + ClientID string + + // ClientSecret is the application's secret. + ClientSecret string + + // Endpoint contains the resource server's token endpoint + // URLs. These are constants specific to each server and are + // often available via site-specific packages, such as + // google.Endpoint or github.Endpoint. + Endpoint Endpoint + + // RedirectURL is the URL to redirect users going through + // the OAuth flow, after the resource owner's URLs. + RedirectURL string + + // Scope specifies optional requested permissions. + Scopes []string +} + +// A TokenSource is anything that can return a token. +type TokenSource interface { + // Token returns a token or an error. + // Token must be safe for concurrent use by multiple goroutines. + // The returned Token must not be modified. + Token() (*Token, error) +} + +// Endpoint contains the OAuth 2.0 provider's authorization and token +// endpoint URLs. +type Endpoint struct { + AuthURL string + TokenURL string +} + +var ( + // AccessTypeOnline and AccessTypeOffline are options passed + // to the Options.AuthCodeURL method. They modify the + // "access_type" field that gets sent in the URL returned by + // AuthCodeURL. + // + // Online is the default if neither is specified. If your + // application needs to refresh access tokens when the user + // is not present at the browser, then use offline. This will + // result in your application obtaining a refresh token the + // first time your application exchanges an authorization + // code for a user. + AccessTypeOnline AuthCodeOption = SetParam("access_type", "online") + AccessTypeOffline AuthCodeOption = SetParam("access_type", "offline") + + // ApprovalForce forces the users to view the consent dialog + // and confirm the permissions request at the URL returned + // from AuthCodeURL, even if they've already done so. + ApprovalForce AuthCodeOption = SetParam("approval_prompt", "force") +) + +// An AuthCodeOption is passed to Config.AuthCodeURL. +type AuthCodeOption interface { + setValue(url.Values) +} + +type setParam struct{ k, v string } + +func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) } + +// SetParam builds an AuthCodeOption which passes key/value parameters +// to a provider's authorization endpoint. +func SetParam(key, value string) AuthCodeOption { + return setParam{key, value} +} + +// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page +// that asks for permissions for the required scopes explicitly. +// +// State is a token to protect the user from CSRF attacks. You must +// always provide a non-zero string and validate that it matches the +// the state query parameter on your redirect callback. +// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info. +// +// Opts may include AccessTypeOnline or AccessTypeOffline, as well +// as ApprovalForce. +func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string { + var buf bytes.Buffer + buf.WriteString(c.Endpoint.AuthURL) + v := url.Values{ + "response_type": {"code"}, + "client_id": {c.ClientID}, + "redirect_uri": condVal(c.RedirectURL), + "scope": condVal(strings.Join(c.Scopes, " ")), + "state": condVal(state), + } + for _, opt := range opts { + opt.setValue(v) + } + if strings.Contains(c.Endpoint.AuthURL, "?") { + buf.WriteByte('&') + } else { + buf.WriteByte('?') + } + buf.WriteString(v.Encode()) + return buf.String() +} + +// PasswordCredentialsToken converts a resource owner username and password +// pair into a token. +// +// Per the RFC, this grant type should only be used "when there is a high +// degree of trust between the resource owner and the client (e.g., the client +// is part of the device operating system or a highly privileged application), +// and when other authorization grant types are not available." +// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info. +// +// The HTTP client to use is derived from the context. +// If nil, http.DefaultClient is used. +func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) { + return retrieveToken(ctx, c, url.Values{ + "grant_type": {"password"}, + "username": {username}, + "password": {password}, + "scope": condVal(strings.Join(c.Scopes, " ")), + }) +} + +// Exchange converts an authorization code into a token. +// +// It is used after a resource provider redirects the user back +// to the Redirect URI (the URL obtained from AuthCodeURL). +// +// The HTTP client to use is derived from the context. +// If a client is not provided via the context, http.DefaultClient is used. +// +// The code will be in the *http.Request.FormValue("code"). Before +// calling Exchange, be sure to validate FormValue("state"). +func (c *Config) Exchange(ctx context.Context, code string) (*Token, error) { + return retrieveToken(ctx, c, url.Values{ + "grant_type": {"authorization_code"}, + "code": {code}, + "redirect_uri": condVal(c.RedirectURL), + "scope": condVal(strings.Join(c.Scopes, " ")), + }) +} + +// contextClientFunc is a func which tries to return an *http.Client +// given a Context value. If it returns an error, the search stops +// with that error. If it returns (nil, nil), the search continues +// down the list of registered funcs. +type contextClientFunc func(context.Context) (*http.Client, error) + +var contextClientFuncs []contextClientFunc + +func registerContextClientFunc(fn contextClientFunc) { + contextClientFuncs = append(contextClientFuncs, fn) +} + +func contextClient(ctx context.Context) (*http.Client, error) { + for _, fn := range contextClientFuncs { + c, err := fn(ctx) + if err != nil { + return nil, err + } + if c != nil { + return c, nil + } + } + if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok { + return hc, nil + } + return http.DefaultClient, nil +} + +func contextTransport(ctx context.Context) http.RoundTripper { + hc, err := contextClient(ctx) + if err != nil { + // This is a rare error case (somebody using nil on App Engine), + // so I'd rather not everybody do an error check on this Client + // method. They can get the error that they're doing it wrong + // later, at client.Get/PostForm time. + return errorTransport{err} + } + return hc.Transport +} + +// Client returns an HTTP client using the provided token. +// The token will auto-refresh as necessary. The underlying +// HTTP transport will be obtained using the provided context. +// The returned client and its Transport should not be modified. +func (c *Config) Client(ctx context.Context, t *Token) *http.Client { + return NewClient(ctx, c.TokenSource(ctx, t)) +} + +// TokenSource returns a TokenSource that returns t until t expires, +// automatically refreshing it as necessary using the provided context. +// +// Most users will use Config.Client instead. +func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource { + tkr := &tokenRefresher{ + ctx: ctx, + conf: c, + } + if t != nil { + tkr.refreshToken = t.RefreshToken + } + return &reuseTokenSource{ + t: t, + new: tkr, + } +} + +// tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token" +// HTTP requests to renew a token using a RefreshToken. +type tokenRefresher struct { + ctx context.Context // used to get HTTP requests + conf *Config + refreshToken string +} + +// WARNING: Token is not safe for concurrent access, as it +// updates the tokenRefresher's refreshToken field. +// Within this package, it is used by reuseTokenSource which +// synchronizes calls to this method with its own mutex. +func (tf *tokenRefresher) Token() (*Token, error) { + if tf.refreshToken == "" { + return nil, errors.New("oauth2: token expired and refresh token is not set") + } + + tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{ + "grant_type": {"refresh_token"}, + "refresh_token": {tf.refreshToken}, + }) + + if err != nil { + return nil, err + } + if tf.refreshToken != tk.RefreshToken { + tf.refreshToken = tk.RefreshToken + } + return tk, err +} + +// reuseTokenSource is a TokenSource that holds a single token in memory +// and validates its expiry before each call to retrieve it with +// Token. If it's expired, it will be auto-refreshed using the +// new TokenSource. +type reuseTokenSource struct { + new TokenSource // called when t is expired. + + mu sync.Mutex // guards t + t *Token +} + +// Token returns the current token if it's still valid, else will +// refresh the current token (using r.Context for HTTP client +// information) and return the new one. +func (s *reuseTokenSource) Token() (*Token, error) { + s.mu.Lock() + defer s.mu.Unlock() + if s.t.Valid() { + return s.t, nil + } + t, err := s.new.Token() + if err != nil { + return nil, err + } + s.t = t + return t, nil +} + +func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) { + hc, err := contextClient(ctx) + if err != nil { + return nil, err + } + v.Set("client_id", c.ClientID) + bustedAuth := !providerAuthHeaderWorks(c.Endpoint.TokenURL) + if bustedAuth && c.ClientSecret != "" { + v.Set("client_secret", c.ClientSecret) + } + req, err := http.NewRequest("POST", c.Endpoint.TokenURL, strings.NewReader(v.Encode())) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + if !bustedAuth { + req.SetBasicAuth(c.ClientID, c.ClientSecret) + } + r, err := hc.Do(req) + if err != nil { + return nil, err + } + defer r.Body.Close() + body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20)) + if err != nil { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) + } + if code := r.StatusCode; code < 200 || code > 299 { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v\nResponse: %s", r.Status, body) + } + + var token *Token + content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type")) + switch content { + case "application/x-www-form-urlencoded", "text/plain": + vals, err := url.ParseQuery(string(body)) + if err != nil { + return nil, err + } + token = &Token{ + AccessToken: vals.Get("access_token"), + TokenType: vals.Get("token_type"), + RefreshToken: vals.Get("refresh_token"), + raw: vals, + } + e := vals.Get("expires_in") + if e == "" { + // TODO(jbd): Facebook's OAuth2 implementation is broken and + // returns expires_in field in expires. Remove the fallback to expires, + // when Facebook fixes their implementation. + e = vals.Get("expires") + } + expires, _ := strconv.Atoi(e) + if expires != 0 { + token.Expiry = time.Now().Add(time.Duration(expires) * time.Second) + } + default: + var tj tokenJSON + if err = json.Unmarshal(body, &tj); err != nil { + return nil, err + } + token = &Token{ + AccessToken: tj.AccessToken, + TokenType: tj.TokenType, + RefreshToken: tj.RefreshToken, + Expiry: tj.expiry(), + raw: make(map[string]interface{}), + } + json.Unmarshal(body, &token.raw) // no error checks for optional fields + } + // Don't overwrite `RefreshToken` with an empty value + // if this was a token refreshing request. + if token.RefreshToken == "" { + token.RefreshToken = v.Get("refresh_token") + } + return token, nil +} + +// tokenJSON is the struct representing the HTTP response from OAuth2 +// providers returning a token in JSON form. +type tokenJSON struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + RefreshToken string `json:"refresh_token"` + ExpiresIn expirationTime `json:"expires_in"` // at least PayPal returns string, while most return number + Expires expirationTime `json:"expires"` // broken Facebook spelling of expires_in +} + +func (e *tokenJSON) expiry() (t time.Time) { + if v := e.ExpiresIn; v != 0 { + return time.Now().Add(time.Duration(v) * time.Second) + } + if v := e.Expires; v != 0 { + return time.Now().Add(time.Duration(v) * time.Second) + } + return +} + +type expirationTime int32 + +func (e *expirationTime) UnmarshalJSON(b []byte) error { + var n json.Number + err := json.Unmarshal(b, &n) + if err != nil { + return err + } + i, err := n.Int64() + if err != nil { + return err + } + *e = expirationTime(i) + return nil +} + +func condVal(v string) []string { + if v == "" { + return nil + } + return []string{v} +} + +var brokenAuthHeaderProviders = []string{ + "https://accounts.google.com/", + "https://www.googleapis.com/", + "https://github.com/", + "https://api.instagram.com/", + "https://www.douban.com/", + "https://api.dropbox.com/", + "https://api.soundcloud.com/", + "https://www.linkedin.com/", + "https://api.twitch.tv/", + "https://oauth.vk.com/", + "https://api.odnoklassniki.ru/", + "https://connect.stripe.com/", + "https://api.pushbullet.com/", + "https://oauth.sandbox.trainingpeaks.com/", + "https://oauth.trainingpeaks.com/", + "https://www.strava.com/oauth/", +} + +// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL +// implements the OAuth2 spec correctly +// See https://code.google.com/p/goauth2/issues/detail?id=31 for background. +// In summary: +// - Reddit only accepts client secret in the Authorization header +// - Dropbox accepts either it in URL param or Auth header, but not both. +// - Google only accepts URL param (not spec compliant?), not Auth header +// - Stripe only accepts client secret in Auth header with Bearer method, not Basic +func providerAuthHeaderWorks(tokenURL string) bool { + for _, s := range brokenAuthHeaderProviders { + if strings.HasPrefix(tokenURL, s) { + // Some sites fail to implement the OAuth2 spec fully. + return false + } + } + + // Assume the provider implements the spec properly + // otherwise. We can add more exceptions as they're + // discovered. We will _not_ be adding configurable hooks + // to this package to let users select server bugs. + return true +} + +// HTTPClient is the context key to use with golang.org/x/net/context's +// WithValue function to associate an *http.Client value with a context. +var HTTPClient contextKey + +// contextKey is just an empty struct. It exists so HTTPClient can be +// an immutable public variable with a unique type. It's immutable +// because nobody else can create a contextKey, being unexported. +type contextKey struct{} + +// NewClient creates an *http.Client from a Context and TokenSource. +// The returned client is not valid beyond the lifetime of the context. +// +// As a special case, if src is nil, a non-OAuth2 client is returned +// using the provided context. This exists to support related OAuth2 +// packages. +func NewClient(ctx context.Context, src TokenSource) *http.Client { + if src == nil { + c, err := contextClient(ctx) + if err != nil { + return &http.Client{Transport: errorTransport{err}} + } + return c + } + return &http.Client{ + Transport: &Transport{ + Base: contextTransport(ctx), + Source: ReuseTokenSource(nil, src), + }, + } +} + +// ReuseTokenSource returns a TokenSource which repeatedly returns the +// same token as long as it's valid, starting with t. +// When its cached token is invalid, a new token is obtained from src. +// +// ReuseTokenSource is typically used to reuse tokens from a cache +// (such as a file on disk) between runs of a program, rather than +// obtaining new tokens unnecessarily. +// +// The initial token t may be nil, in which case the TokenSource is +// wrapped in a caching version if it isn't one already. This also +// means it's always safe to wrap ReuseTokenSource around any other +// TokenSource without adverse effects. +func ReuseTokenSource(t *Token, src TokenSource) TokenSource { + // Don't wrap a reuseTokenSource in itself. That would work, + // but cause an unnecessary number of mutex operations. + // Just build the equivalent one. + if rt, ok := src.(*reuseTokenSource); ok { + if t == nil { + // Just use it directly. + return rt + } + src = rt.new + } + return &reuseTokenSource{ + t: t, + new: src, + } +} diff --git a/_third_party/golang.org/x/oauth2/oauth2_test.go b/_third_party/golang.org/x/oauth2/oauth2_test.go new file mode 100644 index 0000000000..1e96e0009d --- /dev/null +++ b/_third_party/golang.org/x/oauth2/oauth2_test.go @@ -0,0 +1,439 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package oauth2 + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "reflect" + "strconv" + "testing" + "time" + + "bosun.org/_third_party/golang.org/x/net/context" +) + +type mockTransport struct { + rt func(req *http.Request) (resp *http.Response, err error) +} + +func (t *mockTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) { + return t.rt(req) +} + +type mockCache struct { + token *Token + readErr error +} + +func (c *mockCache) ReadToken() (*Token, error) { + return c.token, c.readErr +} + +func (c *mockCache) WriteToken(*Token) { + // do nothing +} + +func newConf(url string) *Config { + return &Config{ + ClientID: "CLIENT_ID", + ClientSecret: "CLIENT_SECRET", + RedirectURL: "REDIRECT_URL", + Scopes: []string{"scope1", "scope2"}, + Endpoint: Endpoint{ + AuthURL: url + "/auth", + TokenURL: url + "/token", + }, + } +} + +func TestAuthCodeURL(t *testing.T) { + conf := newConf("server") + url := conf.AuthCodeURL("foo", AccessTypeOffline, ApprovalForce) + if url != "server/auth?access_type=offline&approval_prompt=force&client_id=CLIENT_ID&redirect_uri=REDIRECT_URL&response_type=code&scope=scope1+scope2&state=foo" { + t.Errorf("Auth code URL doesn't match the expected, found: %v", url) + } +} + +func TestAuthCodeURL_CustomParam(t *testing.T) { + conf := newConf("server") + param := SetParam("foo", "bar") + url := conf.AuthCodeURL("baz", param) + if url != "server/auth?client_id=CLIENT_ID&foo=bar&redirect_uri=REDIRECT_URL&response_type=code&scope=scope1+scope2&state=baz" { + t.Errorf("Auth code URL doesn't match the expected, found: %v", url) + } +} + +func TestAuthCodeURL_Optional(t *testing.T) { + conf := &Config{ + ClientID: "CLIENT_ID", + Endpoint: Endpoint{ + AuthURL: "/auth-url", + TokenURL: "/token-url", + }, + } + url := conf.AuthCodeURL("") + if url != "/auth-url?client_id=CLIENT_ID&response_type=code" { + t.Fatalf("Auth code URL doesn't match the expected, found: %v", url) + } +} + +func TestExchangeRequest(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.String() != "/token" { + t.Errorf("Unexpected exchange request URL, %v is found.", r.URL) + } + headerAuth := r.Header.Get("Authorization") + if headerAuth != "Basic Q0xJRU5UX0lEOkNMSUVOVF9TRUNSRVQ=" { + t.Errorf("Unexpected authorization header, %v is found.", headerAuth) + } + headerContentType := r.Header.Get("Content-Type") + if headerContentType != "application/x-www-form-urlencoded" { + t.Errorf("Unexpected Content-Type header, %v is found.", headerContentType) + } + body, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Errorf("Failed reading request body: %s.", err) + } + if string(body) != "client_id=CLIENT_ID&code=exchange-code&grant_type=authorization_code&redirect_uri=REDIRECT_URL&scope=scope1+scope2" { + t.Errorf("Unexpected exchange payload, %v is found.", string(body)) + } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.Write([]byte("access_token=90d64460d14870c08c81352a05dedd3465940a7c&scope=user&token_type=bearer")) + })) + defer ts.Close() + conf := newConf(ts.URL) + tok, err := conf.Exchange(NoContext, "exchange-code") + if err != nil { + t.Error(err) + } + if !tok.Valid() { + t.Fatalf("Token invalid. Got: %#v", tok) + } + if tok.AccessToken != "90d64460d14870c08c81352a05dedd3465940a7c" { + t.Errorf("Unexpected access token, %#v.", tok.AccessToken) + } + if tok.TokenType != "bearer" { + t.Errorf("Unexpected token type, %#v.", tok.TokenType) + } + scope := tok.Extra("scope") + if scope != "user" { + t.Errorf("Unexpected value for scope: %v", scope) + } +} + +func TestExchangeRequest_JSONResponse(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.String() != "/token" { + t.Errorf("Unexpected exchange request URL, %v is found.", r.URL) + } + headerAuth := r.Header.Get("Authorization") + if headerAuth != "Basic Q0xJRU5UX0lEOkNMSUVOVF9TRUNSRVQ=" { + t.Errorf("Unexpected authorization header, %v is found.", headerAuth) + } + headerContentType := r.Header.Get("Content-Type") + if headerContentType != "application/x-www-form-urlencoded" { + t.Errorf("Unexpected Content-Type header, %v is found.", headerContentType) + } + body, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Errorf("Failed reading request body: %s.", err) + } + if string(body) != "client_id=CLIENT_ID&code=exchange-code&grant_type=authorization_code&redirect_uri=REDIRECT_URL&scope=scope1+scope2" { + t.Errorf("Unexpected exchange payload, %v is found.", string(body)) + } + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"access_token": "90d64460d14870c08c81352a05dedd3465940a7c", "scope": "user", "token_type": "bearer", "expires_in": 86400}`)) + })) + defer ts.Close() + conf := newConf(ts.URL) + tok, err := conf.Exchange(NoContext, "exchange-code") + if err != nil { + t.Error(err) + } + if !tok.Valid() { + t.Fatalf("Token invalid. Got: %#v", tok) + } + if tok.AccessToken != "90d64460d14870c08c81352a05dedd3465940a7c" { + t.Errorf("Unexpected access token, %#v.", tok.AccessToken) + } + if tok.TokenType != "bearer" { + t.Errorf("Unexpected token type, %#v.", tok.TokenType) + } + scope := tok.Extra("scope") + if scope != "user" { + t.Errorf("Unexpected value for scope: %v", scope) + } +} + +const day = 24 * time.Hour + +func TestExchangeRequest_JSONResponse_Expiry(t *testing.T) { + seconds := int32(day.Seconds()) + jsonNumberType := reflect.TypeOf(json.Number("0")) + for _, c := range []struct { + expires string + expect error + }{ + {fmt.Sprintf(`"expires_in": %d`, seconds), nil}, + {fmt.Sprintf(`"expires_in": "%d"`, seconds), nil}, // PayPal case + {fmt.Sprintf(`"expires": %d`, seconds), nil}, // Facebook case + {`"expires": false`, &json.UnmarshalTypeError{Value: "bool", Type: jsonNumberType}}, // wrong type + {`"expires": {}`, &json.UnmarshalTypeError{Value: "object", Type: jsonNumberType}}, // wrong type + {`"expires": "zzz"`, &strconv.NumError{Func: "ParseInt", Num: "zzz", Err: strconv.ErrSyntax}}, // wrong value + } { + testExchangeRequest_JSONResponse_expiry(t, c.expires, c.expect) + } +} + +func testExchangeRequest_JSONResponse_expiry(t *testing.T, exp string, expect error) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(fmt.Sprintf(`{"access_token": "90d", "scope": "user", "token_type": "bearer", %s}`, exp))) + })) + defer ts.Close() + conf := newConf(ts.URL) + t1 := time.Now().Add(day) + tok, err := conf.Exchange(NoContext, "exchange-code") + t2 := time.Now().Add(day) + // Do a fmt.Sprint comparison so either side can be + // nil. fmt.Sprint just stringifies them to "", and no + // non-nil expected error ever stringifies as "", so this + // isn't terribly disgusting. We do this because Go 1.4 and + // Go 1.5 return a different deep value for + // json.UnmarshalTypeError. In Go 1.5, the + // json.UnmarshalTypeError contains a new field with a new + // non-zero value. Rather than ignore it here with reflect or + // add new files and +build tags, just look at the strings. + if fmt.Sprint(err) != fmt.Sprint(expect) { + t.Errorf("Error = %v; want %v", err, expect) + } + if err != nil { + return + } + if !tok.Valid() { + t.Fatalf("Token invalid. Got: %#v", tok) + } + expiry := tok.Expiry + if expiry.Before(t1) || expiry.After(t2) { + t.Errorf("Unexpected value for Expiry: %v (shold be between %v and %v)", expiry, t1, t2) + } +} + +func TestExchangeRequest_BadResponse(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"scope": "user", "token_type": "bearer"}`)) + })) + defer ts.Close() + conf := newConf(ts.URL) + tok, err := conf.Exchange(NoContext, "code") + if err != nil { + t.Fatal(err) + } + if tok.AccessToken != "" { + t.Errorf("Unexpected access token, %#v.", tok.AccessToken) + } +} + +func TestExchangeRequest_BadResponseType(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"access_token":123, "scope": "user", "token_type": "bearer"}`)) + })) + defer ts.Close() + conf := newConf(ts.URL) + _, err := conf.Exchange(NoContext, "exchange-code") + if err == nil { + t.Error("expected error from invalid access_token type") + } +} + +func TestExchangeRequest_NonBasicAuth(t *testing.T) { + tr := &mockTransport{ + rt: func(r *http.Request) (w *http.Response, err error) { + headerAuth := r.Header.Get("Authorization") + if headerAuth != "" { + t.Errorf("Unexpected authorization header, %v is found.", headerAuth) + } + return nil, errors.New("no response") + }, + } + c := &http.Client{Transport: tr} + conf := &Config{ + ClientID: "CLIENT_ID", + Endpoint: Endpoint{ + AuthURL: "https://accounts.google.com/auth", + TokenURL: "https://accounts.google.com/token", + }, + } + + ctx := context.WithValue(context.Background(), HTTPClient, c) + conf.Exchange(ctx, "code") +} + +func TestPasswordCredentialsTokenRequest(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer r.Body.Close() + expected := "/token" + if r.URL.String() != expected { + t.Errorf("URL = %q; want %q", r.URL, expected) + } + headerAuth := r.Header.Get("Authorization") + expected = "Basic Q0xJRU5UX0lEOkNMSUVOVF9TRUNSRVQ=" + if headerAuth != expected { + t.Errorf("Authorization header = %q; want %q", headerAuth, expected) + } + headerContentType := r.Header.Get("Content-Type") + expected = "application/x-www-form-urlencoded" + if headerContentType != expected { + t.Errorf("Content-Type header = %q; want %q", headerContentType, expected) + } + body, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Errorf("Failed reading request body: %s.", err) + } + expected = "client_id=CLIENT_ID&grant_type=password&password=password1&scope=scope1+scope2&username=user1" + if string(body) != expected { + t.Errorf("res.Body = %q; want %q", string(body), expected) + } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.Write([]byte("access_token=90d64460d14870c08c81352a05dedd3465940a7c&scope=user&token_type=bearer")) + })) + defer ts.Close() + conf := newConf(ts.URL) + tok, err := conf.PasswordCredentialsToken(NoContext, "user1", "password1") + if err != nil { + t.Error(err) + } + if !tok.Valid() { + t.Fatalf("Token invalid. Got: %#v", tok) + } + expected := "90d64460d14870c08c81352a05dedd3465940a7c" + if tok.AccessToken != expected { + t.Errorf("AccessToken = %q; want %q", tok.AccessToken, expected) + } + expected = "bearer" + if tok.TokenType != expected { + t.Errorf("TokenType = %q; want %q", tok.TokenType, expected) + } +} + +func TestTokenRefreshRequest(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.String() == "/somethingelse" { + return + } + if r.URL.String() != "/token" { + t.Errorf("Unexpected token refresh request URL, %v is found.", r.URL) + } + headerContentType := r.Header.Get("Content-Type") + if headerContentType != "application/x-www-form-urlencoded" { + t.Errorf("Unexpected Content-Type header, %v is found.", headerContentType) + } + body, _ := ioutil.ReadAll(r.Body) + if string(body) != "client_id=CLIENT_ID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN" { + t.Errorf("Unexpected refresh token payload, %v is found.", string(body)) + } + })) + defer ts.Close() + conf := newConf(ts.URL) + c := conf.Client(NoContext, &Token{RefreshToken: "REFRESH_TOKEN"}) + c.Get(ts.URL + "/somethingelse") +} + +func TestFetchWithNoRefreshToken(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.String() == "/somethingelse" { + return + } + if r.URL.String() != "/token" { + t.Errorf("Unexpected token refresh request URL, %v is found.", r.URL) + } + headerContentType := r.Header.Get("Content-Type") + if headerContentType != "application/x-www-form-urlencoded" { + t.Errorf("Unexpected Content-Type header, %v is found.", headerContentType) + } + body, _ := ioutil.ReadAll(r.Body) + if string(body) != "client_id=CLIENT_ID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN" { + t.Errorf("Unexpected refresh token payload, %v is found.", string(body)) + } + })) + defer ts.Close() + conf := newConf(ts.URL) + c := conf.Client(NoContext, nil) + _, err := c.Get(ts.URL + "/somethingelse") + if err == nil { + t.Errorf("Fetch should return an error if no refresh token is set") + } +} + +func TestRefreshToken_RefreshTokenReplacement(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"access_token":"ACCESS TOKEN", "scope": "user", "token_type": "bearer", "refresh_token": "NEW REFRESH TOKEN"}`)) + return + })) + defer ts.Close() + conf := newConf(ts.URL) + tkr := tokenRefresher{ + conf: conf, + ctx: NoContext, + refreshToken: "OLD REFRESH TOKEN", + } + tk, err := tkr.Token() + if err != nil { + t.Errorf("Unexpected refreshToken error returned: %v", err) + return + } + if tk.RefreshToken != tkr.refreshToken { + t.Errorf("tokenRefresher.refresh_token = %s; want %s", tkr.refreshToken, tk.RefreshToken) + } +} + +func TestConfigClientWithToken(t *testing.T) { + tok := &Token{ + AccessToken: "abc123", + } + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if got, want := r.Header.Get("Authorization"), fmt.Sprintf("Bearer %s", tok.AccessToken); got != want { + t.Errorf("Authorization header = %q; want %q", got, want) + } + return + })) + defer ts.Close() + conf := newConf(ts.URL) + + c := conf.Client(NoContext, tok) + req, err := http.NewRequest("GET", ts.URL, nil) + if err != nil { + t.Error(err) + } + _, err = c.Do(req) + if err != nil { + t.Error(err) + } +} + +func Test_providerAuthHeaderWorks(t *testing.T) { + for _, p := range brokenAuthHeaderProviders { + if providerAuthHeaderWorks(p) { + t.Errorf("URL: %s not found in list", p) + } + p := fmt.Sprintf("%ssomesuffix", p) + if providerAuthHeaderWorks(p) { + t.Errorf("URL: %s not found in list", p) + } + } + p := "https://api.not-in-the-list-example.com/" + if !providerAuthHeaderWorks(p) { + t.Errorf("URL: %s found in list", p) + } + +} diff --git a/_third_party/golang.org/x/oauth2/token.go b/_third_party/golang.org/x/oauth2/token.go new file mode 100644 index 0000000000..9852ceb4a6 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/token.go @@ -0,0 +1,104 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package oauth2 + +import ( + "net/http" + "net/url" + "time" +) + +// expiryDelta determines how earlier a token should be considered +// expired than its actual expiration time. It is used to avoid late +// expirations due to client-server time mismatches. +const expiryDelta = 10 * time.Second + +// Token represents the crendentials used to authorize +// the requests to access protected resources on the OAuth 2.0 +// provider's backend. +// +// Most users of this package should not access fields of Token +// directly. They're exported mostly for use by related packages +// implementing derivative OAuth2 flows. +type Token struct { + // AccessToken is the token that authorizes and authenticates + // the requests. + AccessToken string `json:"access_token"` + + // TokenType is the type of token. + // The Type method returns either this or "Bearer", the default. + TokenType string `json:"token_type,omitempty"` + + // RefreshToken is a token that's used by the application + // (as opposed to the user) to refresh the access token + // if it expires. + RefreshToken string `json:"refresh_token,omitempty"` + + // Expiry is the optional expiration time of the access token. + // + // If zero, TokenSource implementations will reuse the same + // token forever and RefreshToken or equivalent + // mechanisms for that TokenSource will not be used. + Expiry time.Time `json:"expiry,omitempty"` + + // raw optionally contains extra metadata from the server + // when updating a token. + raw interface{} +} + +// Type returns t.TokenType if non-empty, else "Bearer". +func (t *Token) Type() string { + if t.TokenType != "" { + return t.TokenType + } + return "Bearer" +} + +// SetAuthHeader sets the Authorization header to r using the access +// token in t. +// +// This method is unnecessary when using Transport or an HTTP Client +// returned by this package. +func (t *Token) SetAuthHeader(r *http.Request) { + r.Header.Set("Authorization", t.Type()+" "+t.AccessToken) +} + +// WithExtra returns a new Token that's a clone of t, but using the +// provided raw extra map. This is only intended for use by packages +// implementing derivative OAuth2 flows. +func (t *Token) WithExtra(extra interface{}) *Token { + t2 := new(Token) + *t2 = *t + t2.raw = extra + return t2 +} + +// Extra returns an extra field. +// Extra fields are key-value pairs returned by the server as a +// part of the token retrieval response. +func (t *Token) Extra(key string) interface{} { + if vals, ok := t.raw.(url.Values); ok { + // TODO(jbd): Cast numeric values to int64 or float64. + return vals.Get(key) + } + if raw, ok := t.raw.(map[string]interface{}); ok { + return raw[key] + } + return nil +} + +// expired reports whether the token is expired. +// t must be non-nil. +func (t *Token) expired() bool { + if t.Expiry.IsZero() { + return false + } + return t.Expiry.Add(-expiryDelta).Before(time.Now()) +} + +// Valid reports whether t is non-nil, has an AccessToken, and is not expired. +func (t *Token) Valid() bool { + return t != nil && t.AccessToken != "" && !t.expired() +} diff --git a/_third_party/golang.org/x/oauth2/token_test.go b/_third_party/golang.org/x/oauth2/token_test.go new file mode 100644 index 0000000000..739eeb2a20 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/token_test.go @@ -0,0 +1,50 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package oauth2 + +import ( + "testing" + "time" +) + +func TestTokenExtra(t *testing.T) { + type testCase struct { + key string + val interface{} + want interface{} + } + const key = "extra-key" + cases := []testCase{ + {key: key, val: "abc", want: "abc"}, + {key: key, val: 123, want: 123}, + {key: key, val: "", want: ""}, + {key: "other-key", val: "def", want: nil}, + } + for _, tc := range cases { + extra := make(map[string]interface{}) + extra[tc.key] = tc.val + tok := &Token{raw: extra} + if got, want := tok.Extra(key), tc.want; got != want { + t.Errorf("Extra(%q) = %q; want %q", key, got, want) + } + } +} + +func TestTokenExpiry(t *testing.T) { + now := time.Now() + cases := []struct { + name string + tok *Token + want bool + }{ + {name: "12 seconds", tok: &Token{Expiry: now.Add(12 * time.Second)}, want: false}, + {name: "10 seconds", tok: &Token{Expiry: now.Add(expiryDelta)}, want: true}, + } + for _, tc := range cases { + if got, want := tc.tok.expired(), tc.want; got != want { + t.Errorf("expired (%q) = %v; want %v", tc.name, got, want) + } + } +} diff --git a/_third_party/golang.org/x/oauth2/transport.go b/_third_party/golang.org/x/oauth2/transport.go new file mode 100644 index 0000000000..10339a0be7 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/transport.go @@ -0,0 +1,138 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package oauth2 + +import ( + "errors" + "io" + "net/http" + "sync" +) + +// Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests, +// wrapping a base RoundTripper and adding an Authorization header +// with a token from the supplied Sources. +// +// Transport is a low-level mechanism. Most code will use the +// higher-level Config.Client method instead. +type Transport struct { + // Source supplies the token to add to outgoing requests' + // Authorization headers. + Source TokenSource + + // Base is the base RoundTripper used to make HTTP requests. + // If nil, http.DefaultTransport is used. + Base http.RoundTripper + + mu sync.Mutex // guards modReq + modReq map[*http.Request]*http.Request // original -> modified +} + +// RoundTrip authorizes and authenticates the request with an +// access token. If no token exists or token is expired, +// tries to refresh/fetch a new token. +func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { + if t.Source == nil { + return nil, errors.New("oauth2: Transport's Source is nil") + } + token, err := t.Source.Token() + if err != nil { + return nil, err + } + + req2 := cloneRequest(req) // per RoundTripper contract + token.SetAuthHeader(req2) + t.setModReq(req, req2) + res, err := t.base().RoundTrip(req2) + if err != nil { + t.setModReq(req, nil) + return nil, err + } + res.Body = &onEOFReader{ + rc: res.Body, + fn: func() { t.setModReq(req, nil) }, + } + return res, nil +} + +// CancelRequest cancels an in-flight request by closing its connection. +func (t *Transport) CancelRequest(req *http.Request) { + type canceler interface { + CancelRequest(*http.Request) + } + if cr, ok := t.base().(canceler); ok { + t.mu.Lock() + modReq := t.modReq[req] + delete(t.modReq, req) + t.mu.Unlock() + cr.CancelRequest(modReq) + } +} + +func (t *Transport) base() http.RoundTripper { + if t.Base != nil { + return t.Base + } + return http.DefaultTransport +} + +func (t *Transport) setModReq(orig, mod *http.Request) { + t.mu.Lock() + defer t.mu.Unlock() + if t.modReq == nil { + t.modReq = make(map[*http.Request]*http.Request) + } + if mod == nil { + delete(t.modReq, orig) + } else { + t.modReq[orig] = mod + } +} + +// cloneRequest returns a clone of the provided *http.Request. +// The clone is a shallow copy of the struct and its Header map. +func cloneRequest(r *http.Request) *http.Request { + // shallow copy of the struct + r2 := new(http.Request) + *r2 = *r + // deep copy of the Header + r2.Header = make(http.Header, len(r.Header)) + for k, s := range r.Header { + r2.Header[k] = append([]string(nil), s...) + } + return r2 +} + +type onEOFReader struct { + rc io.ReadCloser + fn func() +} + +func (r *onEOFReader) Read(p []byte) (n int, err error) { + n, err = r.rc.Read(p) + if err == io.EOF { + r.runFunc() + } + return +} + +func (r *onEOFReader) Close() error { + err := r.rc.Close() + r.runFunc() + return err +} + +func (r *onEOFReader) runFunc() { + if fn := r.fn; fn != nil { + fn() + r.fn = nil + } +} + +type errorTransport struct{ err error } + +func (t errorTransport) RoundTrip(*http.Request) (*http.Response, error) { + return nil, t.err +} diff --git a/_third_party/golang.org/x/oauth2/transport_test.go b/_third_party/golang.org/x/oauth2/transport_test.go new file mode 100644 index 0000000000..efb8232ac4 --- /dev/null +++ b/_third_party/golang.org/x/oauth2/transport_test.go @@ -0,0 +1,53 @@ +package oauth2 + +import ( + "net/http" + "net/http/httptest" + "testing" + "time" +) + +type tokenSource struct{ token *Token } + +func (t *tokenSource) Token() (*Token, error) { + return t.token, nil +} + +func TestTransportTokenSource(t *testing.T) { + ts := &tokenSource{ + token: &Token{ + AccessToken: "abc", + }, + } + tr := &Transport{ + Source: ts, + } + server := newMockServer(func(w http.ResponseWriter, r *http.Request) { + if r.Header.Get("Authorization") != "Bearer abc" { + t.Errorf("Transport doesn't set the Authorization header from the fetched token") + } + }) + defer server.Close() + client := http.Client{Transport: tr} + client.Get(server.URL) +} + +func TestTokenValidNoAccessToken(t *testing.T) { + token := &Token{} + if token.Valid() { + t.Errorf("Token should not be valid with no access token") + } +} + +func TestExpiredWithExpiry(t *testing.T) { + token := &Token{ + Expiry: time.Now().Add(-5 * time.Hour), + } + if token.Valid() { + t.Errorf("Token should not be valid if it expired in the past") + } +} + +func newMockServer(handler func(w http.ResponseWriter, r *http.Request)) *httptest.Server { + return httptest.NewServer(http.HandlerFunc(handler)) +} diff --git a/_third_party/google.golang.org/api/analytics/v3/analytics-api.json b/_third_party/google.golang.org/api/analytics/v3/analytics-api.json new file mode 100644 index 0000000000..ce2af4b946 --- /dev/null +++ b/_third_party/google.golang.org/api/analytics/v3/analytics-api.json @@ -0,0 +1,6675 @@ +{ + "kind": "discovery#restDescription", + "etag": "\"ye6orv2F-1npMW3u9suM3a7C5Bo/tkvvUCeQm-DiyKpCr0Y-A0UaVuo\"", + "discoveryVersion": "v1", + "id": "analytics:v3", + "name": "analytics", + "version": "v3", + "revision": "20150814", + "title": "Google Analytics API", + "description": "View and manage your Google Analytics data", + "ownerDomain": "google.com", + "ownerName": "Google", + "icons": { + "x16": "https://www.google.com/images/icons/product/analytics-16.png", + "x32": "https://www.google.com/images/icons/product/analytics-32.png" + }, + "documentationLink": "https://developers.google.com/analytics/", + "protocol": "rest", + "baseUrl": "https://www.googleapis.com/analytics/v3/", + "basePath": "/analytics/v3/", + "rootUrl": "https://www.googleapis.com/", + "servicePath": "analytics/v3/", + "batchPath": "batch", + "parameters": { + "alt": { + "type": "string", + "description": "Data format for the response.", + "default": "json", + "enum": [ + "json" + ], + "enumDescriptions": [ + "Responses with Content-Type of application/json" + ], + "location": "query" + }, + "fields": { + "type": "string", + "description": "Selector specifying which fields to include in a partial response.", + "location": "query" + }, + "key": { + "type": "string", + "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", + "location": "query" + }, + "oauth_token": { + "type": "string", + "description": "OAuth 2.0 token for the current user.", + "location": "query" + }, + "prettyPrint": { + "type": "boolean", + "description": "Returns response with indentations and line breaks.", + "default": "false", + "location": "query" + }, + "quotaUser": { + "type": "string", + "description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters. Overrides userIp if both are provided.", + "location": "query" + }, + "userIp": { + "type": "string", + "description": "IP address of the site where the request originates. Use this if you want to enforce per-user limits.", + "location": "query" + } + }, + "auth": { + "oauth2": { + "scopes": { + "https://www.googleapis.com/auth/analytics": { + "description": "View and manage your Google Analytics data" + }, + "https://www.googleapis.com/auth/analytics.edit": { + "description": "Edit Google Analytics management entities" + }, + "https://www.googleapis.com/auth/analytics.manage.users": { + "description": "Manage Google Analytics Account users by email address" + }, + "https://www.googleapis.com/auth/analytics.manage.users.readonly": { + "description": "View Google Analytics user permissions" + }, + "https://www.googleapis.com/auth/analytics.provision": { + "description": "Create a new Google Analytics account along with its default property and view" + }, + "https://www.googleapis.com/auth/analytics.readonly": { + "description": "View your Google Analytics data" + } + } + } + }, + "schemas": { + "Account": { + "id": "Account", + "type": "object", + "description": "JSON template for Analytics account entry.", + "properties": { + "childLink": { + "type": "object", + "description": "Child link for an account entry. Points to the list of web properties for this account.", + "properties": { + "href": { + "type": "string", + "description": "Link to the list of web properties for this account." + }, + "type": { + "type": "string", + "description": "Type of the child link. Its value is \"analytics#webproperties\".", + "default": "analytics#webproperties" + } + } + }, + "created": { + "type": "string", + "description": "Time the account was created.", + "format": "date-time" + }, + "id": { + "type": "string", + "description": "Account ID." + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics account.", + "default": "analytics#account" + }, + "name": { + "type": "string", + "description": "Account name." + }, + "permissions": { + "type": "object", + "description": "Permissions the user has for this account.", + "properties": { + "effective": { + "type": "array", + "description": "All the permissions that the user has for this account. These include any implied permissions (e.g., EDIT implies VIEW).", + "readOnly": true, + "items": { + "type": "string" + } + } + } + }, + "selfLink": { + "type": "string", + "description": "Link for this account." + }, + "updated": { + "type": "string", + "description": "Time the account was last modified.", + "format": "date-time" + } + } + }, + "AccountRef": { + "id": "AccountRef", + "type": "object", + "description": "JSON template for a linked account.", + "properties": { + "href": { + "type": "string", + "description": "Link for this account." + }, + "id": { + "type": "string", + "description": "Account ID." + }, + "kind": { + "type": "string", + "description": "Analytics account reference.", + "default": "analytics#accountRef" + }, + "name": { + "type": "string", + "description": "Account name." + } + } + }, + "AccountSummaries": { + "id": "AccountSummaries", + "type": "object", + "description": "An AccountSummary collection lists a summary of accounts, properties and views (profiles) to which the user has access. Each resource in the collection corresponds to a single AccountSummary.", + "properties": { + "items": { + "type": "array", + "description": "A list of AccountSummaries.", + "items": { + "$ref": "AccountSummary" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#accountSummaries" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this AccountSummary collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this AccountSummary collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "AccountSummary": { + "id": "AccountSummary", + "type": "object", + "description": "JSON template for an Analytics AccountSummary. An AccountSummary is a lightweight tree comprised of properties/profiles.", + "properties": { + "id": { + "type": "string", + "description": "Account ID." + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics AccountSummary.", + "default": "analytics#accountSummary" + }, + "name": { + "type": "string", + "description": "Account name." + }, + "webProperties": { + "type": "array", + "description": "List of web properties under this account.", + "items": { + "$ref": "WebPropertySummary" + } + } + } + }, + "AccountTicket": { + "id": "AccountTicket", + "type": "object", + "description": "JSON template for an Analytics account ticket. The account ticket consists of the ticket ID and the basic information for the account, property and profile.", + "properties": { + "account": { + "$ref": "Account", + "description": "Account for this ticket." + }, + "id": { + "type": "string", + "description": "Account ticket ID used to access the account ticket." + }, + "kind": { + "type": "string", + "description": "Resource type for account ticket.", + "default": "analytics#accountTicket" + }, + "profile": { + "$ref": "Profile", + "description": "View (Profile) for the account." + }, + "redirectUri": { + "type": "string", + "description": "Redirect URI where the user will be sent after accepting Terms of Service. Must be configured in APIs console as a callback URL." + }, + "webproperty": { + "$ref": "Webproperty", + "description": "Web property for the account." + } + } + }, + "Accounts": { + "id": "Accounts", + "type": "object", + "description": "An account collection provides a list of Analytics accounts to which a user has access. The account collection is the entry point to all management information. Each resource in the collection corresponds to a single Analytics account.", + "properties": { + "items": { + "type": "array", + "description": "A list of accounts.", + "items": { + "$ref": "Account" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of entries the response can contain, regardless of the actual number of entries returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#accounts" + }, + "nextLink": { + "type": "string", + "description": "Next link for this account collection." + }, + "previousLink": { + "type": "string", + "description": "Previous link for this account collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the entries, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "AdWordsAccount": { + "id": "AdWordsAccount", + "type": "object", + "description": "JSON template for an AdWords account.", + "properties": { + "autoTaggingEnabled": { + "type": "boolean", + "description": "True if auto-tagging is enabled on the AdWords account. Read-only after the insert operation." + }, + "customerId": { + "type": "string", + "description": "Customer ID. This field is required when creating an AdWords link.", + "annotations": { + "required": [ + "analytics.management.webPropertyAdWordsLinks.insert", + "analytics.management.webPropertyAdWordsLinks.update" + ] + } + }, + "kind": { + "type": "string", + "description": "Resource type for AdWords account.", + "default": "analytics#adWordsAccount" + } + } + }, + "AnalyticsDataimportDeleteUploadDataRequest": { + "id": "AnalyticsDataimportDeleteUploadDataRequest", + "type": "object", + "description": "Request template for the delete upload data request.", + "properties": { + "customDataImportUids": { + "type": "array", + "description": "A list of upload UIDs.", + "items": { + "type": "string" + } + } + } + }, + "Column": { + "id": "Column", + "type": "object", + "description": "JSON template for a metadata column.", + "properties": { + "attributes": { + "type": "object", + "description": "Map of attribute name and value for this column.", + "additionalProperties": { + "type": "string", + "description": "The name of the attribute." + } + }, + "id": { + "type": "string", + "description": "Column id." + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics column.", + "default": "analytics#column" + } + } + }, + "Columns": { + "id": "Columns", + "type": "object", + "description": "Lists columns (dimensions and metrics) for a particular report type.", + "properties": { + "attributeNames": { + "type": "array", + "description": "List of attributes names returned by columns.", + "items": { + "type": "string" + } + }, + "etag": { + "type": "string", + "description": "Etag of collection. This etag can be compared with the last response etag to check if response has changed." + }, + "items": { + "type": "array", + "description": "List of columns for a report type.", + "items": { + "$ref": "Column" + } + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#columns" + }, + "totalResults": { + "type": "integer", + "description": "Total number of columns returned in the response.", + "format": "int32" + } + } + }, + "CustomDataSource": { + "id": "CustomDataSource", + "type": "object", + "description": "JSON template for an Analytics custom data source.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this custom data source belongs." + }, + "childLink": { + "type": "object", + "properties": { + "href": { + "type": "string", + "description": "Link to the list of daily uploads for this custom data source. Link to the list of uploads for this custom data source." + }, + "type": { + "type": "string", + "description": "Value is \"analytics#dailyUploads\". Value is \"analytics#uploads\"." + } + } + }, + "created": { + "type": "string", + "description": "Time this custom data source was created.", + "format": "date-time" + }, + "description": { + "type": "string", + "description": "Description of custom data source." + }, + "id": { + "type": "string", + "description": "Custom data source ID." + }, + "importBehavior": { + "type": "string" + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics custom data source.", + "default": "analytics#customDataSource" + }, + "name": { + "type": "string", + "description": "Name of this custom data source." + }, + "parentLink": { + "type": "object", + "description": "Parent link for this custom data source. Points to the web property to which this custom data source belongs.", + "properties": { + "href": { + "type": "string", + "description": "Link to the web property to which this custom data source belongs." + }, + "type": { + "type": "string", + "description": "Value is \"analytics#webproperty\".", + "default": "analytics#webproperty" + } + } + }, + "profilesLinked": { + "type": "array", + "description": "IDs of views (profiles) linked to the custom data source.", + "items": { + "type": "string" + } + }, + "selfLink": { + "type": "string", + "description": "Link for this Analytics custom data source." + }, + "type": { + "type": "string", + "description": "Type of the custom data source." + }, + "updated": { + "type": "string", + "description": "Time this custom data source was last modified.", + "format": "date-time" + }, + "uploadType": { + "type": "string" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID of the form UA-XXXXX-YY to which this custom data source belongs." + } + } + }, + "CustomDataSources": { + "id": "CustomDataSources", + "type": "object", + "description": "Lists Analytics custom data sources to which the user has access. Each resource in the collection corresponds to a single Analytics custom data source.", + "properties": { + "items": { + "type": "array", + "description": "Collection of custom data sources.", + "items": { + "$ref": "CustomDataSource" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#customDataSources" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this custom data source collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this custom data source collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "CustomDimension": { + "id": "CustomDimension", + "type": "object", + "description": "JSON template for Analytics Custom Dimension.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID." + }, + "active": { + "type": "boolean", + "description": "Boolean indicating whether the custom dimension is active." + }, + "created": { + "type": "string", + "description": "Time the custom dimension was created.", + "format": "date-time", + "readOnly": true + }, + "id": { + "type": "string", + "description": "Custom dimension ID." + }, + "index": { + "type": "integer", + "description": "Index of the custom dimension.", + "format": "int32", + "readOnly": true + }, + "kind": { + "type": "string", + "description": "Kind value for a custom dimension. Set to \"analytics#customDimension\". It is a read-only field.", + "default": "analytics#customDimension", + "readOnly": true + }, + "name": { + "type": "string", + "description": "Name of the custom dimension." + }, + "parentLink": { + "type": "object", + "description": "Parent link for the custom dimension. Points to the property to which the custom dimension belongs.", + "properties": { + "href": { + "type": "string", + "description": "Link to the property to which the custom dimension belongs." + }, + "type": { + "type": "string", + "description": "Type of the parent link. Set to \"analytics#webproperty\".", + "default": "analytics#webproperty" + } + } + }, + "scope": { + "type": "string", + "description": "Scope of the custom dimension: HIT, SESSION, USER or PRODUCT." + }, + "selfLink": { + "type": "string", + "description": "Link for the custom dimension", + "readOnly": true + }, + "updated": { + "type": "string", + "description": "Time the custom dimension was last modified.", + "format": "date-time", + "readOnly": true + }, + "webPropertyId": { + "type": "string", + "description": "Property ID." + } + } + }, + "CustomDimensions": { + "id": "CustomDimensions", + "type": "object", + "description": "A custom dimension collection lists Analytics custom dimensions to which the user has access. Each resource in the collection corresponds to a single Analytics custom dimension.", + "properties": { + "items": { + "type": "array", + "description": "Collection of custom dimensions.", + "items": { + "$ref": "CustomDimension" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#customDimensions" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this custom dimension collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this custom dimension collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "CustomMetric": { + "id": "CustomMetric", + "type": "object", + "description": "JSON template for Analytics Custom Metric.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID." + }, + "active": { + "type": "boolean", + "description": "Boolean indicating whether the custom metric is active." + }, + "created": { + "type": "string", + "description": "Time the custom metric was created.", + "format": "date-time", + "readOnly": true + }, + "id": { + "type": "string", + "description": "Custom metric ID." + }, + "index": { + "type": "integer", + "description": "Index of the custom metric.", + "format": "int32", + "readOnly": true + }, + "kind": { + "type": "string", + "description": "Kind value for a custom metric. Set to \"analytics#customMetric\". It is a read-only field.", + "default": "analytics#customMetric", + "readOnly": true + }, + "max_value": { + "type": "string", + "description": "Max value of custom metric." + }, + "min_value": { + "type": "string", + "description": "Min value of custom metric." + }, + "name": { + "type": "string", + "description": "Name of the custom metric." + }, + "parentLink": { + "type": "object", + "description": "Parent link for the custom metric. Points to the property to which the custom metric belongs.", + "properties": { + "href": { + "type": "string", + "description": "Link to the property to which the custom metric belongs." + }, + "type": { + "type": "string", + "description": "Type of the parent link. Set to \"analytics#webproperty\".", + "default": "analytics#webproperty" + } + } + }, + "scope": { + "type": "string", + "description": "Scope of the custom metric: HIT or PRODUCT." + }, + "selfLink": { + "type": "string", + "description": "Link for the custom metric", + "readOnly": true + }, + "type": { + "type": "string", + "description": "Data type of custom metric." + }, + "updated": { + "type": "string", + "description": "Time the custom metric was last modified.", + "format": "date-time", + "readOnly": true + }, + "webPropertyId": { + "type": "string", + "description": "Property ID." + } + } + }, + "CustomMetrics": { + "id": "CustomMetrics", + "type": "object", + "description": "A custom metric collection lists Analytics custom metrics to which the user has access. Each resource in the collection corresponds to a single Analytics custom metric.", + "properties": { + "items": { + "type": "array", + "description": "Collection of custom metrics.", + "items": { + "$ref": "CustomMetric" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#customMetrics" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this custom metric collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this custom metric collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "EntityAdWordsLink": { + "id": "EntityAdWordsLink", + "type": "object", + "description": "JSON template for Analytics Entity AdWords Link.", + "properties": { + "adWordsAccounts": { + "type": "array", + "description": "A list of AdWords client accounts. These cannot be MCC accounts. This field is required when creating an AdWords link. It cannot be empty.", + "items": { + "$ref": "AdWordsAccount" + }, + "annotations": { + "required": [ + "analytics.management.webPropertyAdWordsLinks.insert", + "analytics.management.webPropertyAdWordsLinks.update" + ] + } + }, + "entity": { + "type": "object", + "description": "Web property being linked.", + "properties": { + "webPropertyRef": { + "$ref": "WebPropertyRef" + } + } + }, + "id": { + "type": "string", + "description": "Entity AdWords link ID" + }, + "kind": { + "type": "string", + "description": "Resource type for entity AdWords link.", + "default": "analytics#entityAdWordsLink" + }, + "name": { + "type": "string", + "description": "Name of the link. This field is required when creating an AdWords link.", + "annotations": { + "required": [ + "analytics.management.webPropertyAdWordsLinks.insert", + "analytics.management.webPropertyAdWordsLinks.update" + ] + } + }, + "profileIds": { + "type": "array", + "description": "IDs of linked Views (Profiles) represented as strings.", + "items": { + "type": "string" + } + }, + "selfLink": { + "type": "string", + "description": "URL link for this Google Analytics - Google AdWords link." + } + } + }, + "EntityAdWordsLinks": { + "id": "EntityAdWordsLinks", + "type": "object", + "description": "An entity AdWords link collection provides a list of GA-AdWords links Each resource in this collection corresponds to a single link.", + "properties": { + "items": { + "type": "array", + "description": "A list of entity AdWords links.", + "items": { + "$ref": "EntityAdWordsLink" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of entries the response can contain, regardless of the actual number of entries returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#entityAdWordsLinks" + }, + "nextLink": { + "type": "string", + "description": "Next link for this AdWords link collection." + }, + "previousLink": { + "type": "string", + "description": "Previous link for this AdWords link collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the entries, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + } + } + }, + "EntityUserLink": { + "id": "EntityUserLink", + "type": "object", + "description": "JSON template for an Analytics Entity-User Link. Returns permissions that a user has for an entity.", + "properties": { + "entity": { + "type": "object", + "description": "Entity for this link. It can be an account, a web property, or a view (profile).", + "properties": { + "accountRef": { + "$ref": "AccountRef", + "description": "Account for this link." + }, + "profileRef": { + "$ref": "ProfileRef", + "description": "View (Profile) for this link." + }, + "webPropertyRef": { + "$ref": "WebPropertyRef", + "description": "Web property for this link." + } + } + }, + "id": { + "type": "string", + "description": "Entity user link ID" + }, + "kind": { + "type": "string", + "description": "Resource type for entity user link.", + "default": "analytics#entityUserLink" + }, + "permissions": { + "type": "object", + "description": "Permissions the user has for this entity.", + "properties": { + "effective": { + "type": "array", + "description": "Effective permissions represent all the permissions that a user has for this entity. These include any implied permissions (e.g., EDIT implies VIEW) or inherited permissions from the parent entity. Effective permissions are read-only.", + "readOnly": true, + "items": { + "type": "string" + } + }, + "local": { + "type": "array", + "description": "Permissions that a user has been assigned at this very level. Does not include any implied or inherited permissions. Local permissions are modifiable.", + "items": { + "type": "string" + } + } + } + }, + "selfLink": { + "type": "string", + "description": "Self link for this resource." + }, + "userRef": { + "$ref": "UserRef", + "description": "User reference." + } + } + }, + "EntityUserLinks": { + "id": "EntityUserLinks", + "type": "object", + "description": "An entity user link collection provides a list of Analytics ACL links Each resource in this collection corresponds to a single link.", + "properties": { + "items": { + "type": "array", + "description": "A list of entity user links.", + "items": { + "$ref": "EntityUserLink" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of entries the response can contain, regardless of the actual number of entries returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#entityUserLinks" + }, + "nextLink": { + "type": "string", + "description": "Next link for this account collection." + }, + "previousLink": { + "type": "string", + "description": "Previous link for this account collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the entries, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + } + } + }, + "Experiment": { + "id": "Experiment", + "type": "object", + "description": "JSON template for Analytics experiment resource.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this experiment belongs. This field is read-only." + }, + "created": { + "type": "string", + "description": "Time the experiment was created. This field is read-only.", + "format": "date-time" + }, + "description": { + "type": "string", + "description": "Notes about this experiment." + }, + "editableInGaUi": { + "type": "boolean", + "description": "If true, the end user will be able to edit the experiment via the Google Analytics user interface." + }, + "endTime": { + "type": "string", + "description": "The ending time of the experiment (the time the status changed from RUNNING to ENDED). This field is present only if the experiment has ended. This field is read-only.", + "format": "date-time" + }, + "equalWeighting": { + "type": "boolean", + "description": "Boolean specifying whether to distribute traffic evenly across all variations. If the value is False, content experiments follows the default behavior of adjusting traffic dynamically based on variation performance. Optional -- defaults to False. This field may not be changed for an experiment whose status is ENDED." + }, + "id": { + "type": "string", + "description": "Experiment ID. Required for patch and update. Disallowed for create.", + "annotations": { + "required": [ + "analytics.management.experiments.patch", + "analytics.management.experiments.update" + ] + } + }, + "internalWebPropertyId": { + "type": "string", + "description": "Internal ID for the web property to which this experiment belongs. This field is read-only." + }, + "kind": { + "type": "string", + "description": "Resource type for an Analytics experiment. This field is read-only.", + "default": "analytics#experiment" + }, + "minimumExperimentLengthInDays": { + "type": "integer", + "description": "An integer number in [3, 90]. Specifies the minimum length of the experiment. Can be changed for a running experiment. This field may not be changed for an experiments whose status is ENDED.", + "format": "int32" + }, + "name": { + "type": "string", + "description": "Experiment name. This field may not be changed for an experiment whose status is ENDED. This field is required when creating an experiment.", + "annotations": { + "required": [ + "analytics.management.experiments.insert", + "analytics.management.experiments.update" + ] + } + }, + "objectiveMetric": { + "type": "string", + "description": "The metric that the experiment is optimizing. Valid values: \"ga:goal(n)Completions\", \"ga:adsenseAdsClicks\", \"ga:adsenseAdsViewed\", \"ga:adsenseRevenue\", \"ga:bounces\", \"ga:pageviews\", \"ga:sessionDuration\", \"ga:transactions\", \"ga:transactionRevenue\". This field is required if status is \"RUNNING\" and servingFramework is one of \"REDIRECT\" or \"API\"." + }, + "optimizationType": { + "type": "string", + "description": "Whether the objectiveMetric should be minimized or maximized. Possible values: \"MAXIMUM\", \"MINIMUM\". Optional--defaults to \"MAXIMUM\". Cannot be specified without objectiveMetric. Cannot be modified when status is \"RUNNING\" or \"ENDED\"." + }, + "parentLink": { + "type": "object", + "description": "Parent link for an experiment. Points to the view (profile) to which this experiment belongs.", + "properties": { + "href": { + "type": "string", + "description": "Link to the view (profile) to which this experiment belongs. This field is read-only." + }, + "type": { + "type": "string", + "description": "Value is \"analytics#profile\". This field is read-only.", + "default": "analytics#profile" + } + } + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to which this experiment belongs. This field is read-only." + }, + "reasonExperimentEnded": { + "type": "string", + "description": "Why the experiment ended. Possible values: \"STOPPED_BY_USER\", \"WINNER_FOUND\", \"EXPERIMENT_EXPIRED\", \"ENDED_WITH_NO_WINNER\", \"GOAL_OBJECTIVE_CHANGED\". \"ENDED_WITH_NO_WINNER\" means that the experiment didn't expire but no winner was projected to be found. If the experiment status is changed via the API to ENDED this field is set to STOPPED_BY_USER. This field is read-only." + }, + "rewriteVariationUrlsAsOriginal": { + "type": "boolean", + "description": "Boolean specifying whether variations URLS are rewritten to match those of the original. This field may not be changed for an experiments whose status is ENDED." + }, + "selfLink": { + "type": "string", + "description": "Link for this experiment. This field is read-only." + }, + "servingFramework": { + "type": "string", + "description": "The framework used to serve the experiment variations and evaluate the results. One of: \n- REDIRECT: Google Analytics redirects traffic to different variation pages, reports the chosen variation and evaluates the results.\n- API: Google Analytics chooses and reports the variation to serve and evaluates the results; the caller is responsible for serving the selected variation.\n- EXTERNAL: The variations will be served externally and the chosen variation reported to Google Analytics. The caller is responsible for serving the selected variation and evaluating the results." + }, + "snippet": { + "type": "string", + "description": "The snippet of code to include on the control page(s). This field is read-only." + }, + "startTime": { + "type": "string", + "description": "The starting time of the experiment (the time the status changed from READY_TO_RUN to RUNNING). This field is present only if the experiment has started. This field is read-only.", + "format": "date-time" + }, + "status": { + "type": "string", + "description": "Experiment status. Possible values: \"DRAFT\", \"READY_TO_RUN\", \"RUNNING\", \"ENDED\". Experiments can be created in the \"DRAFT\", \"READY_TO_RUN\" or \"RUNNING\" state. This field is required when creating an experiment.", + "annotations": { + "required": [ + "analytics.management.experiments.insert", + "analytics.management.experiments.update" + ] + } + }, + "trafficCoverage": { + "type": "number", + "description": "A floating-point number in (0, 1]. Specifies the fraction of the traffic that participates in the experiment. Can be changed for a running experiment. This field may not be changed for an experiments whose status is ENDED.", + "format": "double" + }, + "updated": { + "type": "string", + "description": "Time the experiment was last modified. This field is read-only.", + "format": "date-time" + }, + "variations": { + "type": "array", + "description": "Array of variations. The first variation in the array is the original. The number of variations may not change once an experiment is in the RUNNING state. At least two variations are required before status can be set to RUNNING.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the variation. This field is required when creating an experiment. This field may not be changed for an experiment whose status is ENDED.", + "annotations": { + "required": [ + "analytics.management.experiments.insert", + "analytics.management.experiments.update" + ] + } + }, + "status": { + "type": "string", + "description": "Status of the variation. Possible values: \"ACTIVE\", \"INACTIVE\". INACTIVE variations are not served. This field may not be changed for an experiment whose status is ENDED." + }, + "url": { + "type": "string", + "description": "The URL of the variation. This field may not be changed for an experiment whose status is RUNNING or ENDED." + }, + "weight": { + "type": "number", + "description": "Weight that this variation should receive. Only present if the experiment is running. This field is read-only.", + "format": "double" + }, + "won": { + "type": "boolean", + "description": "True if the experiment has ended and this variation performed (statistically) significantly better than the original. This field is read-only." + } + } + } + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to which this experiment belongs. The web property ID is of the form UA-XXXXX-YY. This field is read-only." + }, + "winnerConfidenceLevel": { + "type": "number", + "description": "A floating-point number in (0, 1). Specifies the necessary confidence level to choose a winner. This field may not be changed for an experiments whose status is ENDED.", + "format": "double" + }, + "winnerFound": { + "type": "boolean", + "description": "Boolean specifying whether a winner has been found for this experiment. This field is read-only." + } + } + }, + "Experiments": { + "id": "Experiments", + "type": "object", + "description": "An experiment collection lists Analytics experiments to which the user has access. Each view (profile) can have a set of experiments. Each resource in the Experiment collection corresponds to a single Analytics experiment.", + "properties": { + "items": { + "type": "array", + "description": "A list of experiments.", + "items": { + "$ref": "Experiment" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#experiments" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this experiment collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this experiment collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of resources in the result.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "Filter": { + "id": "Filter", + "type": "object", + "description": "JSON template for an Analytics account filter.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this filter belongs." + }, + "advancedDetails": { + "type": "object", + "description": "Details for the filter of the type ADVANCED.", + "properties": { + "caseSensitive": { + "type": "boolean", + "description": "Indicates if the filter expressions are case sensitive." + }, + "extractA": { + "type": "string", + "description": "Expression to extract from field A." + }, + "extractB": { + "type": "string", + "description": "Expression to extract from field B." + }, + "fieldA": { + "type": "string", + "description": "Field A." + }, + "fieldAIndex": { + "type": "integer", + "description": "The Index of the custom dimension. Required if field is a CUSTOM_DIMENSION.", + "format": "int32" + }, + "fieldARequired": { + "type": "boolean", + "description": "Indicates if field A is required to match." + }, + "fieldB": { + "type": "string", + "description": "Field B." + }, + "fieldBIndex": { + "type": "integer", + "description": "The Index of the custom dimension. Required if field is a CUSTOM_DIMENSION.", + "format": "int32" + }, + "fieldBRequired": { + "type": "boolean", + "description": "Indicates if field B is required to match." + }, + "outputConstructor": { + "type": "string", + "description": "Expression used to construct the output value." + }, + "outputToField": { + "type": "string", + "description": "Output field." + }, + "outputToFieldIndex": { + "type": "integer", + "description": "The Index of the custom dimension. Required if field is a CUSTOM_DIMENSION.", + "format": "int32" + }, + "overrideOutputField": { + "type": "boolean", + "description": "Indicates if the existing value of the output field, if any, should be overridden by the output expression." + } + } + }, + "created": { + "type": "string", + "description": "Time this filter was created.", + "format": "date-time", + "readOnly": true + }, + "excludeDetails": { + "$ref": "FilterExpression", + "description": "Details for the filter of the type EXCLUDE." + }, + "id": { + "type": "string", + "description": "Filter ID." + }, + "includeDetails": { + "$ref": "FilterExpression", + "description": "Details for the filter of the type INCLUDE." + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics filter.", + "default": "analytics#filter", + "readOnly": true + }, + "lowercaseDetails": { + "type": "object", + "description": "Details for the filter of the type LOWER.", + "properties": { + "field": { + "type": "string", + "description": "Field to use in the filter." + }, + "fieldIndex": { + "type": "integer", + "description": "The Index of the custom dimension. Required if field is a CUSTOM_DIMENSION.", + "format": "int32" + } + } + }, + "name": { + "type": "string", + "description": "Name of this filter.", + "annotations": { + "required": [ + "analytics.management.filters.insert", + "analytics.management.filters.update" + ] + } + }, + "parentLink": { + "type": "object", + "description": "Parent link for this filter. Points to the account to which this filter belongs.", + "properties": { + "href": { + "type": "string", + "description": "Link to the account to which this filter belongs." + }, + "type": { + "type": "string", + "description": "Value is \"analytics#account\".", + "default": "analytics#account" + } + } + }, + "searchAndReplaceDetails": { + "type": "object", + "description": "Details for the filter of the type SEARCH_AND_REPLACE.", + "properties": { + "caseSensitive": { + "type": "boolean", + "description": "Determines if the filter is case sensitive." + }, + "field": { + "type": "string", + "description": "Field to use in the filter." + }, + "fieldIndex": { + "type": "integer", + "description": "The Index of the custom dimension. Required if field is a CUSTOM_DIMENSION.", + "format": "int32" + }, + "replaceString": { + "type": "string", + "description": "Term to replace the search term with." + }, + "searchString": { + "type": "string", + "description": "Term to search." + } + } + }, + "selfLink": { + "type": "string", + "description": "Link for this filter.", + "readOnly": true + }, + "type": { + "type": "string", + "description": "Type of this filter. Possible values are INCLUDE, EXCLUDE, LOWERCASE, UPPERCASE, SEARCH_AND_REPLACE and ADVANCED.", + "annotations": { + "required": [ + "analytics.management.filters.insert", + "analytics.management.filters.update" + ] + } + }, + "updated": { + "type": "string", + "description": "Time this filter was last modified.", + "format": "date-time", + "readOnly": true + }, + "uppercaseDetails": { + "type": "object", + "description": "Details for the filter of the type UPPER.", + "properties": { + "field": { + "type": "string", + "description": "Field to use in the filter." + }, + "fieldIndex": { + "type": "integer", + "description": "The Index of the custom dimension. Required if field is a CUSTOM_DIMENSION.", + "format": "int32" + } + } + } + } + }, + "FilterExpression": { + "id": "FilterExpression", + "type": "object", + "description": "JSON template for an Analytics filter expression.", + "properties": { + "caseSensitive": { + "type": "boolean", + "description": "Determines if the filter is case sensitive." + }, + "expressionValue": { + "type": "string", + "description": "Filter expression value" + }, + "field": { + "type": "string", + "description": "Field to filter. Possible values: \n- Content and Traffic \n- PAGE_REQUEST_URI, \n- PAGE_HOSTNAME, \n- PAGE_TITLE, \n- REFERRAL, \n- COST_DATA_URI (Campaign target URL), \n- HIT_TYPE, \n- INTERNAL_SEARCH_TERM, \n- INTERNAL_SEARCH_TYPE, \n- SOURCE_PROPERTY_TRACKING_ID, \n- Campaign or AdGroup \n- CAMPAIGN_SOURCE, \n- CAMPAIGN_MEDIUM, \n- CAMPAIGN_NAME, \n- CAMPAIGN_AD_GROUP, \n- CAMPAIGN_TERM, \n- CAMPAIGN_CONTENT, \n- CAMPAIGN_CODE, \n- CAMPAIGN_REFERRAL_PATH, \n- E-Commerce \n- TRANSACTION_COUNTRY, \n- TRANSACTION_REGION, \n- TRANSACTION_CITY, \n- TRANSACTION_AFFILIATION (Store or order location), \n- ITEM_NAME, \n- ITEM_CODE, \n- ITEM_VARIATION, \n- TRANSACTION_ID, \n- TRANSACTION_CURRENCY_CODE, \n- PRODUCT_ACTION_TYPE, \n- Audience/Users \n- BROWSER, \n- BROWSER_VERSION, \n- BROWSER_SIZE, \n- PLATFORM, \n- PLATFORM_VERSION, \n- LANGUAGE, \n- SCREEN_RESOLUTION, \n- SCREEN_COLORS, \n- JAVA_ENABLED (Boolean Field), \n- FLASH_VERSION, \n- GEO_SPEED (Connection speed), \n- VISITOR_TYPE, \n- GEO_ORGANIZATION (ISP organization), \n- GEO_DOMAIN, \n- GEO_IP_ADDRESS, \n- GEO_IP_VERSION, \n- Location \n- GEO_COUNTRY, \n- GEO_REGION, \n- GEO_CITY, \n- Event \n- EVENT_CATEGORY, \n- EVENT_ACTION, \n- EVENT_LABEL, \n- Other \n- CUSTOM_FIELD_1, \n- CUSTOM_FIELD_2, \n- USER_DEFINED_VALUE, \n- Application \n- APP_ID, \n- APP_INSTALLER_ID, \n- APP_NAME, \n- APP_VERSION, \n- SCREEN, \n- IS_APP (Boolean Field), \n- IS_FATAL_EXCEPTION (Boolean Field), \n- EXCEPTION_DESCRIPTION, \n- Mobile device \n- IS_MOBILE (Boolean Field, Deprecated. Use DEVICE_CATEGORY=mobile), \n- IS_TABLET (Boolean Field, Deprecated. Use DEVICE_CATEGORY=tablet), \n- DEVICE_CATEGORY, \n- MOBILE_HAS_QWERTY_KEYBOARD (Boolean Field), \n- MOBILE_HAS_NFC_SUPPORT (Boolean Field), \n- MOBILE_HAS_CELLULAR_RADIO (Boolean Field), \n- MOBILE_HAS_WIFI_SUPPORT (Boolean Field), \n- MOBILE_BRAND_NAME, \n- MOBILE_MODEL_NAME, \n- MOBILE_MARKETING_NAME, \n- MOBILE_POINTING_METHOD, \n- Social \n- SOCIAL_NETWORK, \n- SOCIAL_ACTION, \n- SOCIAL_ACTION_TARGET, \n- Custom dimension \n- CUSTOM_DIMENSION (See accompanying field index)," + }, + "fieldIndex": { + "type": "integer", + "description": "The Index of the custom dimension. Set only if the field is a is CUSTOM_DIMENSION.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Kind value for filter expression", + "default": "analytics#filterExpression" + }, + "matchType": { + "type": "string", + "description": "Match type for this filter. Possible values are BEGINS_WITH, EQUAL, ENDS_WITH, CONTAINS, or MATCHES. GEO_DOMAIN, GEO_IP_ADDRESS, PAGE_REQUEST_URI, or PAGE_HOSTNAME filters can use any match type; all other filters must use MATCHES." + } + } + }, + "FilterRef": { + "id": "FilterRef", + "type": "object", + "description": "JSON template for a profile filter link.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this filter belongs.", + "readOnly": true + }, + "href": { + "type": "string", + "description": "Link for this filter." + }, + "id": { + "type": "string", + "description": "Filter ID.", + "annotations": { + "required": [ + "analytics.management.profileFilterLinks.insert" + ] + } + }, + "kind": { + "type": "string", + "description": "Kind value for filter reference.", + "default": "analytics#filterRef" + }, + "name": { + "type": "string", + "description": "Name of this filter.", + "readOnly": true + } + } + }, + "Filters": { + "id": "Filters", + "type": "object", + "description": "A filter collection lists filters created by users in an Analytics account. Each resource in the collection corresponds to a filter.", + "properties": { + "items": { + "type": "array", + "description": "A list of filters.", + "items": { + "$ref": "Filter" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1,000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#filters" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this filter collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this filter collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "GaData": { + "id": "GaData", + "type": "object", + "description": "Analytics data for a given view (profile).", + "properties": { + "columnHeaders": { + "type": "array", + "description": "Column headers that list dimension names followed by the metric names. The order of dimensions and metrics is same as specified in the request.", + "items": { + "type": "object", + "properties": { + "columnType": { + "type": "string", + "description": "Column Type. Either DIMENSION or METRIC." + }, + "dataType": { + "type": "string", + "description": "Data type. Dimension column headers have only STRING as the data type. Metric column headers have data types for metric values such as INTEGER, DOUBLE, CURRENCY etc." + }, + "name": { + "type": "string", + "description": "Column name." + } + } + } + }, + "containsSampledData": { + "type": "boolean", + "description": "Determines if Analytics data contains samples." + }, + "dataTable": { + "type": "object", + "properties": { + "cols": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "type": { + "type": "string" + } + } + } + }, + "rows": { + "type": "array", + "items": { + "type": "object", + "properties": { + "c": { + "type": "array", + "items": { + "type": "object", + "properties": { + "v": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "id": { + "type": "string", + "description": "Unique ID for this data response." + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of rows the response can contain, regardless of the actual number of rows returned. Its value ranges from 1 to 10,000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Resource type.", + "default": "analytics#gaData" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this Analytics data query." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this Analytics data query." + }, + "profileInfo": { + "type": "object", + "description": "Information for the view (profile), for which the Analytics data was requested.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this view (profile) belongs." + }, + "internalWebPropertyId": { + "type": "string", + "description": "Internal ID for the web property to which this view (profile) belongs." + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID." + }, + "profileName": { + "type": "string", + "description": "View (Profile) name." + }, + "tableId": { + "type": "string", + "description": "Table ID for view (profile)." + }, + "webPropertyId": { + "type": "string", + "description": "Web Property ID to which this view (profile) belongs." + } + } + }, + "query": { + "type": "object", + "description": "Analytics data request query parameters.", + "properties": { + "dimensions": { + "type": "string", + "description": "List of analytics dimensions." + }, + "end-date": { + "type": "string", + "description": "End date." + }, + "filters": { + "type": "string", + "description": "Comma-separated list of dimension or metric filters." + }, + "ids": { + "type": "string", + "description": "Unique table ID." + }, + "max-results": { + "type": "integer", + "description": "Maximum results per page.", + "format": "int32" + }, + "metrics": { + "type": "array", + "description": "List of analytics metrics.", + "items": { + "type": "string" + } + }, + "samplingLevel": { + "type": "string", + "description": "Desired sampling level" + }, + "segment": { + "type": "string", + "description": "Analytics advanced segment." + }, + "sort": { + "type": "array", + "description": "List of dimensions or metrics based on which Analytics data is sorted.", + "items": { + "type": "string" + } + }, + "start-date": { + "type": "string", + "description": "Start date." + }, + "start-index": { + "type": "integer", + "description": "Start index.", + "format": "int32" + } + } + }, + "rows": { + "type": "array", + "description": "Analytics data rows, where each row contains a list of dimension values followed by the metric values. The order of dimensions and metrics is same as specified in the request.", + "items": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "sampleSize": { + "type": "string", + "description": "The number of samples used to calculate the result.", + "format": "int64" + }, + "sampleSpace": { + "type": "string", + "description": "Total size of the sample space from which the samples were selected.", + "format": "int64" + }, + "selfLink": { + "type": "string", + "description": "Link to this page." + }, + "totalResults": { + "type": "integer", + "description": "The total number of rows for the query, regardless of the number of rows in the response.", + "format": "int32" + }, + "totalsForAllResults": { + "type": "object", + "description": "Total values for the requested metrics over all the results, not just the results returned in this response. The order of the metric totals is same as the metric order specified in the request.", + "additionalProperties": { + "type": "string", + "description": "Key-value pair for the total value of a metric. Key is the metric name and the value is the total value for that metric." + } + } + } + }, + "Goal": { + "id": "Goal", + "type": "object", + "description": "JSON template for Analytics goal resource.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this goal belongs." + }, + "active": { + "type": "boolean", + "description": "Determines whether this goal is active." + }, + "created": { + "type": "string", + "description": "Time this goal was created.", + "format": "date-time" + }, + "eventDetails": { + "type": "object", + "description": "Details for the goal of the type EVENT.", + "properties": { + "eventConditions": { + "type": "array", + "description": "List of event conditions.", + "items": { + "type": "object", + "properties": { + "comparisonType": { + "type": "string", + "description": "Type of comparison. Possible values are LESS_THAN, GREATER_THAN or EQUAL." + }, + "comparisonValue": { + "type": "string", + "description": "Value used for this comparison.", + "format": "int64" + }, + "expression": { + "type": "string", + "description": "Expression used for this match." + }, + "matchType": { + "type": "string", + "description": "Type of the match to be performed. Possible values are REGEXP, BEGINS_WITH, or EXACT." + }, + "type": { + "type": "string", + "description": "Type of this event condition. Possible values are CATEGORY, ACTION, LABEL, or VALUE." + } + } + } + }, + "useEventValue": { + "type": "boolean", + "description": "Determines if the event value should be used as the value for this goal." + } + } + }, + "id": { + "type": "string", + "description": "Goal ID." + }, + "internalWebPropertyId": { + "type": "string", + "description": "Internal ID for the web property to which this goal belongs." + }, + "kind": { + "type": "string", + "description": "Resource type for an Analytics goal.", + "default": "analytics#goal" + }, + "name": { + "type": "string", + "description": "Goal name." + }, + "parentLink": { + "type": "object", + "description": "Parent link for a goal. Points to the view (profile) to which this goal belongs.", + "properties": { + "href": { + "type": "string", + "description": "Link to the view (profile) to which this goal belongs." + }, + "type": { + "type": "string", + "description": "Value is \"analytics#profile\".", + "default": "analytics#profile" + } + } + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to which this goal belongs." + }, + "selfLink": { + "type": "string", + "description": "Link for this goal." + }, + "type": { + "type": "string", + "description": "Goal type. Possible values are URL_DESTINATION, VISIT_TIME_ON_SITE, VISIT_NUM_PAGES, AND EVENT." + }, + "updated": { + "type": "string", + "description": "Time this goal was last modified.", + "format": "date-time" + }, + "urlDestinationDetails": { + "type": "object", + "description": "Details for the goal of the type URL_DESTINATION.", + "properties": { + "caseSensitive": { + "type": "boolean", + "description": "Determines if the goal URL must exactly match the capitalization of visited URLs." + }, + "firstStepRequired": { + "type": "boolean", + "description": "Determines if the first step in this goal is required." + }, + "matchType": { + "type": "string", + "description": "Match type for the goal URL. Possible values are HEAD, EXACT, or REGEX." + }, + "steps": { + "type": "array", + "description": "List of steps configured for this goal funnel.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Step name." + }, + "number": { + "type": "integer", + "description": "Step number.", + "format": "int32" + }, + "url": { + "type": "string", + "description": "URL for this step." + } + } + } + }, + "url": { + "type": "string", + "description": "URL for this goal." + } + } + }, + "value": { + "type": "number", + "description": "Goal value.", + "format": "float" + }, + "visitNumPagesDetails": { + "type": "object", + "description": "Details for the goal of the type VISIT_NUM_PAGES.", + "properties": { + "comparisonType": { + "type": "string", + "description": "Type of comparison. Possible values are LESS_THAN, GREATER_THAN, or EQUAL." + }, + "comparisonValue": { + "type": "string", + "description": "Value used for this comparison.", + "format": "int64" + } + } + }, + "visitTimeOnSiteDetails": { + "type": "object", + "description": "Details for the goal of the type VISIT_TIME_ON_SITE.", + "properties": { + "comparisonType": { + "type": "string", + "description": "Type of comparison. Possible values are LESS_THAN or GREATER_THAN." + }, + "comparisonValue": { + "type": "string", + "description": "Value used for this comparison.", + "format": "int64" + } + } + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to which this goal belongs. The web property ID is of the form UA-XXXXX-YY." + } + } + }, + "Goals": { + "id": "Goals", + "type": "object", + "description": "A goal collection lists Analytics goals to which the user has access. Each view (profile) can have a set of goals. Each resource in the Goal collection corresponds to a single Analytics goal.", + "properties": { + "items": { + "type": "array", + "description": "A list of goals.", + "items": { + "$ref": "Goal" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#goals" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this goal collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this goal collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of resources in the result.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "McfData": { + "id": "McfData", + "type": "object", + "description": "Multi-Channel Funnels data for a given view (profile).", + "properties": { + "columnHeaders": { + "type": "array", + "description": "Column headers that list dimension names followed by the metric names. The order of dimensions and metrics is same as specified in the request.", + "items": { + "type": "object", + "properties": { + "columnType": { + "type": "string", + "description": "Column Type. Either DIMENSION or METRIC." + }, + "dataType": { + "type": "string", + "description": "Data type. Dimension and metric values data types such as INTEGER, DOUBLE, CURRENCY, MCF_SEQUENCE etc." + }, + "name": { + "type": "string", + "description": "Column name." + } + } + } + }, + "containsSampledData": { + "type": "boolean", + "description": "Determines if the Analytics data contains sampled data." + }, + "id": { + "type": "string", + "description": "Unique ID for this data response." + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of rows the response can contain, regardless of the actual number of rows returned. Its value ranges from 1 to 10,000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Resource type.", + "default": "analytics#mcfData" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this Analytics data query." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this Analytics data query." + }, + "profileInfo": { + "type": "object", + "description": "Information for the view (profile), for which the Analytics data was requested.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this view (profile) belongs." + }, + "internalWebPropertyId": { + "type": "string", + "description": "Internal ID for the web property to which this view (profile) belongs." + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID." + }, + "profileName": { + "type": "string", + "description": "View (Profile) name." + }, + "tableId": { + "type": "string", + "description": "Table ID for view (profile)." + }, + "webPropertyId": { + "type": "string", + "description": "Web Property ID to which this view (profile) belongs." + } + } + }, + "query": { + "type": "object", + "description": "Analytics data request query parameters.", + "properties": { + "dimensions": { + "type": "string", + "description": "List of analytics dimensions." + }, + "end-date": { + "type": "string", + "description": "End date." + }, + "filters": { + "type": "string", + "description": "Comma-separated list of dimension or metric filters." + }, + "ids": { + "type": "string", + "description": "Unique table ID." + }, + "max-results": { + "type": "integer", + "description": "Maximum results per page.", + "format": "int32" + }, + "metrics": { + "type": "array", + "description": "List of analytics metrics.", + "items": { + "type": "string" + } + }, + "samplingLevel": { + "type": "string", + "description": "Desired sampling level" + }, + "segment": { + "type": "string", + "description": "Analytics advanced segment." + }, + "sort": { + "type": "array", + "description": "List of dimensions or metrics based on which Analytics data is sorted.", + "items": { + "type": "string" + } + }, + "start-date": { + "type": "string", + "description": "Start date." + }, + "start-index": { + "type": "integer", + "description": "Start index.", + "format": "int32" + } + } + }, + "rows": { + "type": "array", + "description": "Analytics data rows, where each row contains a list of dimension values followed by the metric values. The order of dimensions and metrics is same as specified in the request.", + "items": { + "type": "array", + "items": { + "type": "object", + "description": "A union object representing a dimension or metric value. Only one of \"primitiveValue\" or \"conversionPathValue\" attribute will be populated.", + "properties": { + "conversionPathValue": { + "type": "array", + "description": "A conversion path dimension value, containing a list of interactions with their attributes.", + "items": { + "type": "object", + "properties": { + "interactionType": { + "type": "string", + "description": "Type of an interaction on conversion path. Such as CLICK, IMPRESSION etc." + }, + "nodeValue": { + "type": "string", + "description": "Node value of an interaction on conversion path. Such as source, medium etc." + } + } + } + }, + "primitiveValue": { + "type": "string", + "description": "A primitive dimension value. A primitive metric value." + } + } + } + } + }, + "sampleSize": { + "type": "string", + "description": "The number of samples used to calculate the result.", + "format": "int64" + }, + "sampleSpace": { + "type": "string", + "description": "Total size of the sample space from which the samples were selected.", + "format": "int64" + }, + "selfLink": { + "type": "string", + "description": "Link to this page." + }, + "totalResults": { + "type": "integer", + "description": "The total number of rows for the query, regardless of the number of rows in the response.", + "format": "int32" + }, + "totalsForAllResults": { + "type": "object", + "description": "Total values for the requested metrics over all the results, not just the results returned in this response. The order of the metric totals is same as the metric order specified in the request.", + "additionalProperties": { + "type": "string", + "description": "Key-value pair for the total value of a metric. Key is the metric name and the value is the total value for that metric." + } + } + } + }, + "Profile": { + "id": "Profile", + "type": "object", + "description": "JSON template for an Analytics view (profile).", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this view (profile) belongs." + }, + "childLink": { + "type": "object", + "description": "Child link for this view (profile). Points to the list of goals for this view (profile).", + "properties": { + "href": { + "type": "string", + "description": "Link to the list of goals for this view (profile)." + }, + "type": { + "type": "string", + "description": "Value is \"analytics#goals\".", + "default": "analytics#goals" + } + } + }, + "created": { + "type": "string", + "description": "Time this view (profile) was created.", + "format": "date-time", + "readOnly": true + }, + "currency": { + "type": "string", + "description": "The currency type associated with this view (profile), defaults to USD. The supported values are:\nARS, AUD, BGN, BRL, CAD, CHF, CNY, CZK, DKK, EUR, GBP, HKD, HUF, IDR, INR, JPY, KRW, LTL, MXN, NOK, NZD, PHP, PLN, RUB, SEK, THB, TRY, TWD, USD, VND, ZAR" + }, + "defaultPage": { + "type": "string", + "description": "Default page for this view (profile)." + }, + "eCommerceTracking": { + "type": "boolean", + "description": "Indicates whether ecommerce tracking is enabled for this view (profile)." + }, + "enhancedECommerceTracking": { + "type": "boolean", + "description": "Indicates whether enhanced ecommerce tracking is enabled for this view (profile). This property can only be enabled if ecommerce tracking is enabled." + }, + "excludeQueryParameters": { + "type": "string", + "description": "The query parameters that are excluded from this view (profile)." + }, + "id": { + "type": "string", + "description": "View (Profile) ID." + }, + "internalWebPropertyId": { + "type": "string", + "description": "Internal ID for the web property to which this view (profile) belongs.", + "readOnly": true + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics view (profile).", + "default": "analytics#profile", + "readOnly": true + }, + "name": { + "type": "string", + "description": "Name of this view (profile)." + }, + "parentLink": { + "type": "object", + "description": "Parent link for this view (profile). Points to the web property to which this view (profile) belongs.", + "properties": { + "href": { + "type": "string", + "description": "Link to the web property to which this view (profile) belongs." + }, + "type": { + "type": "string", + "description": "Value is \"analytics#webproperty\".", + "default": "analytics#webproperty" + } + } + }, + "permissions": { + "type": "object", + "description": "Permissions the user has for this view (profile).", + "properties": { + "effective": { + "type": "array", + "description": "All the permissions that the user has for this view (profile). These include any implied permissions (e.g., EDIT implies VIEW) or inherited permissions from the parent web property.", + "readOnly": true, + "items": { + "type": "string" + } + } + } + }, + "selfLink": { + "type": "string", + "description": "Link for this view (profile).", + "readOnly": true + }, + "siteSearchCategoryParameters": { + "type": "string", + "description": "Site search category parameters for this view (profile)." + }, + "siteSearchQueryParameters": { + "type": "string", + "description": "The site search query parameters for this view (profile)." + }, + "stripSiteSearchCategoryParameters": { + "type": "boolean", + "description": "Whether or not Analytics will strip search category parameters from the URLs in your reports." + }, + "stripSiteSearchQueryParameters": { + "type": "boolean", + "description": "Whether or not Analytics will strip search query parameters from the URLs in your reports." + }, + "timezone": { + "type": "string", + "description": "Time zone for which this view (profile) has been configured. Time zones are identified by strings from the TZ database." + }, + "type": { + "type": "string", + "description": "View (Profile) type. Supported types: WEB or APP." + }, + "updated": { + "type": "string", + "description": "Time this view (profile) was last modified.", + "format": "date-time", + "readOnly": true + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID of the form UA-XXXXX-YY to which this view (profile) belongs.", + "readOnly": true + }, + "websiteUrl": { + "type": "string", + "description": "Website URL for this view (profile)." + } + } + }, + "ProfileFilterLink": { + "id": "ProfileFilterLink", + "type": "object", + "description": "JSON template for an Analytics profile filter link.", + "properties": { + "filterRef": { + "$ref": "FilterRef", + "description": "Filter for this link." + }, + "id": { + "type": "string", + "description": "Profile filter link ID." + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics filter.", + "default": "analytics#profileFilterLink", + "readOnly": true + }, + "profileRef": { + "$ref": "ProfileRef", + "description": "View (Profile) for this link." + }, + "rank": { + "type": "integer", + "description": "The rank of this profile filter link relative to the other filters linked to the same profile.\nFor readonly (i.e., list and get) operations, the rank always starts at 1.\nFor write (i.e., create, update, or delete) operations, you may specify a value between 0 and 255 inclusively, [0, 255]. In order to insert a link at the end of the list, either don't specify a rank or set a rank to a number greater than the largest rank in the list. In order to insert a link to the beginning of the list specify a rank that is less than or equal to 1. The new link will move all existing filters with the same or lower rank down the list. After the link is inserted/updated/deleted all profile filter links will be renumbered starting at 1.", + "format": "int32" + }, + "selfLink": { + "type": "string", + "description": "Link for this profile filter link.", + "readOnly": true + } + } + }, + "ProfileFilterLinks": { + "id": "ProfileFilterLinks", + "type": "object", + "description": "A profile filter link collection lists profile filter links between profiles and filters. Each resource in the collection corresponds to a profile filter link.", + "properties": { + "items": { + "type": "array", + "description": "A list of profile filter links.", + "items": { + "$ref": "ProfileFilterLink" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1,000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#profileFilterLinks" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this profile filter link collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this profile filter link collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "ProfileRef": { + "id": "ProfileRef", + "type": "object", + "description": "JSON template for a linked view (profile).", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this view (profile) belongs." + }, + "href": { + "type": "string", + "description": "Link for this view (profile)." + }, + "id": { + "type": "string", + "description": "View (Profile) ID." + }, + "internalWebPropertyId": { + "type": "string", + "description": "Internal ID for the web property to which this view (profile) belongs." + }, + "kind": { + "type": "string", + "description": "Analytics view (profile) reference.", + "default": "analytics#profileRef" + }, + "name": { + "type": "string", + "description": "Name of this view (profile)." + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID of the form UA-XXXXX-YY to which this view (profile) belongs." + } + } + }, + "ProfileSummary": { + "id": "ProfileSummary", + "type": "object", + "description": "JSON template for an Analytics ProfileSummary. ProfileSummary returns basic information (i.e., summary) for a profile.", + "properties": { + "id": { + "type": "string", + "description": "View (profile) ID." + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics ProfileSummary.", + "default": "analytics#profileSummary" + }, + "name": { + "type": "string", + "description": "View (profile) name." + }, + "type": { + "type": "string", + "description": "View (Profile) type. Supported types: WEB or APP." + } + } + }, + "Profiles": { + "id": "Profiles", + "type": "object", + "description": "A view (profile) collection lists Analytics views (profiles) to which the user has access. Each resource in the collection corresponds to a single Analytics view (profile).", + "properties": { + "items": { + "type": "array", + "description": "A list of views (profiles).", + "items": { + "$ref": "Profile" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#profiles" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this view (profile) collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this view (profile) collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "RealtimeData": { + "id": "RealtimeData", + "type": "object", + "description": "Real time data for a given view (profile).", + "properties": { + "columnHeaders": { + "type": "array", + "description": "Column headers that list dimension names followed by the metric names. The order of dimensions and metrics is same as specified in the request.", + "items": { + "type": "object", + "properties": { + "columnType": { + "type": "string", + "description": "Column Type. Either DIMENSION or METRIC." + }, + "dataType": { + "type": "string", + "description": "Data type. Dimension column headers have only STRING as the data type. Metric column headers have data types for metric values such as INTEGER, DOUBLE, CURRENCY etc." + }, + "name": { + "type": "string", + "description": "Column name." + } + } + } + }, + "id": { + "type": "string", + "description": "Unique ID for this data response." + }, + "kind": { + "type": "string", + "description": "Resource type.", + "default": "analytics#realtimeData" + }, + "profileInfo": { + "type": "object", + "description": "Information for the view (profile), for which the real time data was requested.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this view (profile) belongs." + }, + "internalWebPropertyId": { + "type": "string", + "description": "Internal ID for the web property to which this view (profile) belongs." + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID." + }, + "profileName": { + "type": "string", + "description": "View (Profile) name." + }, + "tableId": { + "type": "string", + "description": "Table ID for view (profile)." + }, + "webPropertyId": { + "type": "string", + "description": "Web Property ID to which this view (profile) belongs." + } + } + }, + "query": { + "type": "object", + "description": "Real time data request query parameters.", + "properties": { + "dimensions": { + "type": "string", + "description": "List of real time dimensions." + }, + "filters": { + "type": "string", + "description": "Comma-separated list of dimension or metric filters." + }, + "ids": { + "type": "string", + "description": "Unique table ID." + }, + "max-results": { + "type": "integer", + "description": "Maximum results per page.", + "format": "int32" + }, + "metrics": { + "type": "array", + "description": "List of real time metrics.", + "items": { + "type": "string" + } + }, + "sort": { + "type": "array", + "description": "List of dimensions or metrics based on which real time data is sorted.", + "items": { + "type": "string" + } + } + } + }, + "rows": { + "type": "array", + "description": "Real time data rows, where each row contains a list of dimension values followed by the metric values. The order of dimensions and metrics is same as specified in the request.", + "items": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "selfLink": { + "type": "string", + "description": "Link to this page." + }, + "totalResults": { + "type": "integer", + "description": "The total number of rows for the query, regardless of the number of rows in the response.", + "format": "int32" + }, + "totalsForAllResults": { + "type": "object", + "description": "Total values for the requested metrics over all the results, not just the results returned in this response. The order of the metric totals is same as the metric order specified in the request.", + "additionalProperties": { + "type": "string", + "description": "Key-value pair for the total value of a metric. Key is the metric name and the value is the total value for that metric." + } + } + } + }, + "Segment": { + "id": "Segment", + "type": "object", + "description": "JSON template for an Analytics segment.", + "properties": { + "created": { + "type": "string", + "description": "Time the segment was created.", + "format": "date-time" + }, + "definition": { + "type": "string", + "description": "Segment definition." + }, + "id": { + "type": "string", + "description": "Segment ID." + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics segment.", + "default": "analytics#segment" + }, + "name": { + "type": "string", + "description": "Segment name." + }, + "segmentId": { + "type": "string", + "description": "Segment ID. Can be used with the 'segment' parameter in Core Reporting API." + }, + "selfLink": { + "type": "string", + "description": "Link for this segment." + }, + "type": { + "type": "string", + "description": "Type for a segment. Possible values are \"BUILT_IN\" or \"CUSTOM\"." + }, + "updated": { + "type": "string", + "description": "Time the segment was last modified.", + "format": "date-time" + } + } + }, + "Segments": { + "id": "Segments", + "type": "object", + "description": "An segment collection lists Analytics segments that the user has access to. Each resource in the collection corresponds to a single Analytics segment.", + "properties": { + "items": { + "type": "array", + "description": "A list of segments.", + "items": { + "$ref": "Segment" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type for segments.", + "default": "analytics#segments" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this segment collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this segment collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "UnsampledReport": { + "id": "UnsampledReport", + "type": "object", + "description": "JSON template for Analytics unsampled report resource.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this unsampled report belongs." + }, + "cloudStorageDownloadDetails": { + "type": "object", + "description": "Download details for a file stored in Google Cloud Storage.", + "readOnly": true, + "properties": { + "bucketId": { + "type": "string", + "description": "Id of the bucket the file object is stored in." + }, + "objectId": { + "type": "string", + "description": "Id of the file object containing the report data." + } + } + }, + "created": { + "type": "string", + "description": "Time this unsampled report was created.", + "format": "date-time", + "readOnly": true + }, + "dimensions": { + "type": "string", + "description": "The dimensions for the unsampled report." + }, + "downloadType": { + "type": "string", + "description": "The type of download you need to use for the report data file.", + "readOnly": true + }, + "driveDownloadDetails": { + "type": "object", + "description": "Download details for a file stored in Google Drive.", + "readOnly": true, + "properties": { + "documentId": { + "type": "string", + "description": "Id of the document/file containing the report data." + } + } + }, + "end-date": { + "type": "string", + "description": "The end date for the unsampled report.", + "annotations": { + "required": [ + "analytics.management.filters.insert", + "analytics.management.unsampledReports.insert" + ] + } + }, + "filters": { + "type": "string", + "description": "The filters for the unsampled report." + }, + "id": { + "type": "string", + "description": "Unsampled report ID." + }, + "kind": { + "type": "string", + "description": "Resource type for an Analytics unsampled report.", + "default": "analytics#unsampledReport", + "readOnly": true + }, + "metrics": { + "type": "string", + "description": "The metrics for the unsampled report.", + "annotations": { + "required": [ + "analytics.management.filters.insert", + "analytics.management.unsampledReports.insert" + ] + } + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to which this unsampled report belongs." + }, + "segment": { + "type": "string", + "description": "The segment for the unsampled report." + }, + "selfLink": { + "type": "string", + "description": "Link for this unsampled report.", + "readOnly": true + }, + "start-date": { + "type": "string", + "description": "The start date for the unsampled report.", + "annotations": { + "required": [ + "analytics.management.filters.insert", + "analytics.management.unsampledReports.insert" + ] + } + }, + "status": { + "type": "string", + "description": "Status of this unsampled report. Possible values are PENDING, COMPLETED, or FAILED.", + "readOnly": true + }, + "title": { + "type": "string", + "description": "Title of the unsampled report.", + "annotations": { + "required": [ + "analytics.management.filters.insert", + "analytics.management.unsampledReports.insert" + ] + } + }, + "updated": { + "type": "string", + "description": "Time this unsampled report was last modified.", + "format": "date-time", + "readOnly": true + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to which this unsampled report belongs. The web property ID is of the form UA-XXXXX-YY." + } + } + }, + "UnsampledReports": { + "id": "UnsampledReports", + "type": "object", + "description": "An unsampled report collection lists Analytics unsampled reports to which the user has access. Each view (profile) can have a set of unsampled reports. Each resource in the unsampled report collection corresponds to a single Analytics unsampled report.", + "properties": { + "items": { + "type": "array", + "description": "A list of unsampled reports.", + "items": { + "$ref": "UnsampledReport" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#unsampledReports" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this unsampled report collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this unsampled report collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of resources in the result.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "Upload": { + "id": "Upload", + "type": "object", + "description": "Metadata returned for an upload operation.", + "properties": { + "accountId": { + "type": "string", + "description": "Account Id to which this upload belongs.", + "format": "int64" + }, + "customDataSourceId": { + "type": "string", + "description": "Custom data source Id to which this data import belongs." + }, + "errors": { + "type": "array", + "description": "Data import errors collection.", + "items": { + "type": "string" + } + }, + "id": { + "type": "string", + "description": "A unique ID for this upload." + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics upload.", + "default": "analytics#upload" + }, + "status": { + "type": "string", + "description": "Upload status. Possible values: PENDING, COMPLETED, FAILED, DELETING, DELETED." + } + } + }, + "Uploads": { + "id": "Uploads", + "type": "object", + "description": "Upload collection lists Analytics uploads to which the user has access. Each custom data source can have a set of uploads. Each resource in the upload collection corresponds to a single Analytics data upload.", + "properties": { + "items": { + "type": "array", + "description": "A list of uploads.", + "items": { + "$ref": "Upload" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#uploads" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this upload collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this upload collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of resources in the result.", + "format": "int32" + } + } + }, + "UserRef": { + "id": "UserRef", + "type": "object", + "description": "JSON template for a user reference.", + "properties": { + "email": { + "type": "string", + "description": "Email ID of this user." + }, + "id": { + "type": "string", + "description": "User ID." + }, + "kind": { + "type": "string", + "default": "analytics#userRef" + } + } + }, + "WebPropertyRef": { + "id": "WebPropertyRef", + "type": "object", + "description": "JSON template for a web property reference.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this web property belongs." + }, + "href": { + "type": "string", + "description": "Link for this web property." + }, + "id": { + "type": "string", + "description": "Web property ID of the form UA-XXXXX-YY." + }, + "internalWebPropertyId": { + "type": "string", + "description": "Internal ID for this web property." + }, + "kind": { + "type": "string", + "description": "Analytics web property reference.", + "default": "analytics#webPropertyRef" + }, + "name": { + "type": "string", + "description": "Name of this web property." + } + } + }, + "WebPropertySummary": { + "id": "WebPropertySummary", + "type": "object", + "description": "JSON template for an Analytics WebPropertySummary. WebPropertySummary returns basic information (i.e., summary) for a web property.", + "properties": { + "id": { + "type": "string", + "description": "Web property ID of the form UA-XXXXX-YY." + }, + "internalWebPropertyId": { + "type": "string", + "description": "Internal ID for this web property." + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics WebPropertySummary.", + "default": "analytics#webPropertySummary" + }, + "level": { + "type": "string", + "description": "Level for this web property. Possible values are STANDARD or PREMIUM." + }, + "name": { + "type": "string", + "description": "Web property name." + }, + "profiles": { + "type": "array", + "description": "List of profiles under this web property.", + "items": { + "$ref": "ProfileSummary" + } + }, + "websiteUrl": { + "type": "string", + "description": "Website url for this web property." + } + } + }, + "Webproperties": { + "id": "Webproperties", + "type": "object", + "description": "A web property collection lists Analytics web properties to which the user has access. Each resource in the collection corresponds to a single Analytics web property.", + "properties": { + "items": { + "type": "array", + "description": "A list of web properties.", + "items": { + "$ref": "Webproperty" + } + }, + "itemsPerPage": { + "type": "integer", + "description": "The maximum number of resources the response can contain, regardless of the actual number of resources returned. Its value ranges from 1 to 1000 with a value of 1000 by default, or otherwise specified by the max-results query parameter.", + "format": "int32" + }, + "kind": { + "type": "string", + "description": "Collection type.", + "default": "analytics#webproperties" + }, + "nextLink": { + "type": "string", + "description": "Link to next page for this web property collection." + }, + "previousLink": { + "type": "string", + "description": "Link to previous page for this web property collection." + }, + "startIndex": { + "type": "integer", + "description": "The starting index of the resources, which is 1 by default or otherwise specified by the start-index query parameter.", + "format": "int32" + }, + "totalResults": { + "type": "integer", + "description": "The total number of results for the query, regardless of the number of results in the response.", + "format": "int32" + }, + "username": { + "type": "string", + "description": "Email ID of the authenticated user" + } + } + }, + "Webproperty": { + "id": "Webproperty", + "type": "object", + "description": "JSON template for an Analytics web property.", + "properties": { + "accountId": { + "type": "string", + "description": "Account ID to which this web property belongs." + }, + "childLink": { + "type": "object", + "description": "Child link for this web property. Points to the list of views (profiles) for this web property.", + "properties": { + "href": { + "type": "string", + "description": "Link to the list of views (profiles) for this web property." + }, + "type": { + "type": "string", + "description": "Type of the parent link. Its value is \"analytics#profiles\".", + "default": "analytics#profiles" + } + } + }, + "created": { + "type": "string", + "description": "Time this web property was created.", + "format": "date-time", + "readOnly": true + }, + "defaultProfileId": { + "type": "string", + "description": "Default view (profile) ID.", + "format": "int64" + }, + "id": { + "type": "string", + "description": "Web property ID of the form UA-XXXXX-YY." + }, + "industryVertical": { + "type": "string", + "description": "The industry vertical/category selected for this web property." + }, + "internalWebPropertyId": { + "type": "string", + "description": "Internal ID for this web property.", + "readOnly": true + }, + "kind": { + "type": "string", + "description": "Resource type for Analytics WebProperty.", + "default": "analytics#webproperty", + "readOnly": true + }, + "level": { + "type": "string", + "description": "Level for this web property. Possible values are STANDARD or PREMIUM.", + "readOnly": true + }, + "name": { + "type": "string", + "description": "Name of this web property." + }, + "parentLink": { + "type": "object", + "description": "Parent link for this web property. Points to the account to which this web property belongs.", + "properties": { + "href": { + "type": "string", + "description": "Link to the account for this web property." + }, + "type": { + "type": "string", + "description": "Type of the parent link. Its value is \"analytics#account\".", + "default": "analytics#account" + } + } + }, + "permissions": { + "type": "object", + "description": "Permissions the user has for this web property.", + "properties": { + "effective": { + "type": "array", + "description": "All the permissions that the user has for this web property. These include any implied permissions (e.g., EDIT implies VIEW) or inherited permissions from the parent account.", + "readOnly": true, + "items": { + "type": "string" + } + } + } + }, + "profileCount": { + "type": "integer", + "description": "View (Profile) count for this web property.", + "format": "int32", + "readOnly": true + }, + "selfLink": { + "type": "string", + "description": "Link for this web property.", + "readOnly": true + }, + "updated": { + "type": "string", + "description": "Time this web property was last modified.", + "format": "date-time", + "readOnly": true + }, + "websiteUrl": { + "type": "string", + "description": "Website url for this web property." + } + } + } + }, + "resources": { + "data": { + "resources": { + "ga": { + "methods": { + "get": { + "id": "analytics.data.ga.get", + "path": "data/ga", + "httpMethod": "GET", + "description": "Returns Analytics data for a view (profile).", + "parameters": { + "dimensions": { + "type": "string", + "description": "A comma-separated list of Analytics dimensions. E.g., 'ga:browser,ga:city'.", + "pattern": "(ga:.+)?", + "location": "query" + }, + "end-date": { + "type": "string", + "description": "End date for fetching Analytics data. Request can should specify an end date formatted as YYYY-MM-DD, or as a relative date (e.g., today, yesterday, or 7daysAgo). The default value is yesterday.", + "required": true, + "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)", + "location": "query" + }, + "filters": { + "type": "string", + "description": "A comma-separated list of dimension or metric filters to be applied to Analytics data.", + "pattern": "ga:.+", + "location": "query" + }, + "ids": { + "type": "string", + "description": "Unique table ID for retrieving Analytics data. Table ID is of the form ga:XXXX, where XXXX is the Analytics view (profile) ID.", + "required": true, + "pattern": "ga:[0-9]+", + "location": "query" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of entries to include in this feed.", + "format": "int32", + "location": "query" + }, + "metrics": { + "type": "string", + "description": "A comma-separated list of Analytics metrics. E.g., 'ga:sessions,ga:pageviews'. At least one metric must be specified.", + "required": true, + "pattern": "ga:.+", + "location": "query" + }, + "output": { + "type": "string", + "description": "The selected format for the response. Default format is JSON.", + "enum": [ + "dataTable", + "json" + ], + "enumDescriptions": [ + "Returns the response in Google Charts Data Table format. This is useful in creating visualization using Google Charts.", + "Returns the response in standard JSON format." + ], + "location": "query" + }, + "samplingLevel": { + "type": "string", + "description": "The desired sampling level.", + "enum": [ + "DEFAULT", + "FASTER", + "HIGHER_PRECISION" + ], + "enumDescriptions": [ + "Returns response with a sample size that balances speed and accuracy.", + "Returns a fast response with a smaller sample size.", + "Returns a more accurate response using a large sample size, but this may result in the response being slower." + ], + "location": "query" + }, + "segment": { + "type": "string", + "description": "An Analytics segment to be applied to data.", + "location": "query" + }, + "sort": { + "type": "string", + "description": "A comma-separated list of dimensions or metrics that determine the sort order for Analytics data.", + "pattern": "(-)?ga:.+", + "location": "query" + }, + "start-date": { + "type": "string", + "description": "Start date for fetching Analytics data. Requests can specify a start date formatted as YYYY-MM-DD, or as a relative date (e.g., today, yesterday, or 7daysAgo). The default value is 7daysAgo.", + "required": true, + "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + } + }, + "parameterOrder": [ + "ids", + "start-date", + "end-date", + "metrics" + ], + "response": { + "$ref": "GaData" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly" + ] + } + } + }, + "mcf": { + "methods": { + "get": { + "id": "analytics.data.mcf.get", + "path": "data/mcf", + "httpMethod": "GET", + "description": "Returns Analytics Multi-Channel Funnels data for a view (profile).", + "parameters": { + "dimensions": { + "type": "string", + "description": "A comma-separated list of Multi-Channel Funnels dimensions. E.g., 'mcf:source,mcf:medium'.", + "pattern": "(mcf:.+)?", + "location": "query" + }, + "end-date": { + "type": "string", + "description": "End date for fetching Analytics data. Requests can specify a start date formatted as YYYY-MM-DD, or as a relative date (e.g., today, yesterday, or 7daysAgo). The default value is 7daysAgo.", + "required": true, + "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)", + "location": "query" + }, + "filters": { + "type": "string", + "description": "A comma-separated list of dimension or metric filters to be applied to the Analytics data.", + "pattern": "mcf:.+", + "location": "query" + }, + "ids": { + "type": "string", + "description": "Unique table ID for retrieving Analytics data. Table ID is of the form ga:XXXX, where XXXX is the Analytics view (profile) ID.", + "required": true, + "pattern": "ga:[0-9]+", + "location": "query" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of entries to include in this feed.", + "format": "int32", + "location": "query" + }, + "metrics": { + "type": "string", + "description": "A comma-separated list of Multi-Channel Funnels metrics. E.g., 'mcf:totalConversions,mcf:totalConversionValue'. At least one metric must be specified.", + "required": true, + "pattern": "mcf:.+", + "location": "query" + }, + "samplingLevel": { + "type": "string", + "description": "The desired sampling level.", + "enum": [ + "DEFAULT", + "FASTER", + "HIGHER_PRECISION" + ], + "enumDescriptions": [ + "Returns response with a sample size that balances speed and accuracy.", + "Returns a fast response with a smaller sample size.", + "Returns a more accurate response using a large sample size, but this may result in the response being slower." + ], + "location": "query" + }, + "sort": { + "type": "string", + "description": "A comma-separated list of dimensions or metrics that determine the sort order for the Analytics data.", + "pattern": "(-)?mcf:.+", + "location": "query" + }, + "start-date": { + "type": "string", + "description": "Start date for fetching Analytics data. Requests can specify a start date formatted as YYYY-MM-DD, or as a relative date (e.g., today, yesterday, or 7daysAgo). The default value is 7daysAgo.", + "required": true, + "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + } + }, + "parameterOrder": [ + "ids", + "start-date", + "end-date", + "metrics" + ], + "response": { + "$ref": "McfData" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly" + ] + } + } + }, + "realtime": { + "methods": { + "get": { + "id": "analytics.data.realtime.get", + "path": "data/realtime", + "httpMethod": "GET", + "description": "Returns real time data for a view (profile).", + "parameters": { + "dimensions": { + "type": "string", + "description": "A comma-separated list of real time dimensions. E.g., 'rt:medium,rt:city'.", + "pattern": "(ga:.+)|(rt:.+)", + "location": "query" + }, + "filters": { + "type": "string", + "description": "A comma-separated list of dimension or metric filters to be applied to real time data.", + "pattern": "(ga:.+)|(rt:.+)", + "location": "query" + }, + "ids": { + "type": "string", + "description": "Unique table ID for retrieving real time data. Table ID is of the form ga:XXXX, where XXXX is the Analytics view (profile) ID.", + "required": true, + "pattern": "ga:[0-9]+", + "location": "query" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of entries to include in this feed.", + "format": "int32", + "location": "query" + }, + "metrics": { + "type": "string", + "description": "A comma-separated list of real time metrics. E.g., 'rt:activeUsers'. At least one metric must be specified.", + "required": true, + "pattern": "(ga:.+)|(rt:.+)", + "location": "query" + }, + "sort": { + "type": "string", + "description": "A comma-separated list of dimensions or metrics that determine the sort order for real time data.", + "pattern": "(-)?((ga:.+)|(rt:.+))", + "location": "query" + } + }, + "parameterOrder": [ + "ids", + "metrics" + ], + "response": { + "$ref": "RealtimeData" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly" + ] + } + } + } + } + }, + "management": { + "resources": { + "accountSummaries": { + "methods": { + "list": { + "id": "analytics.management.accountSummaries.list", + "path": "management/accountSummaries", + "httpMethod": "GET", + "description": "Lists account summaries (lightweight tree comprised of accounts/properties/profiles) to which the user has access.", + "parameters": { + "max-results": { + "type": "integer", + "description": "The maximum number of account summaries to include in this response, where the largest acceptable value is 1000.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + } + }, + "response": { + "$ref": "AccountSummaries" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + } + } + }, + "accountUserLinks": { + "methods": { + "delete": { + "id": "analytics.management.accountUserLinks.delete", + "path": "management/accounts/{accountId}/entityUserLinks/{linkId}", + "httpMethod": "DELETE", + "description": "Removes a user from the given account.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to delete the user link for.", + "required": true, + "location": "path" + }, + "linkId": { + "type": "string", + "description": "Link ID to delete the user link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "linkId" + ], + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users" + ] + }, + "insert": { + "id": "analytics.management.accountUserLinks.insert", + "path": "management/accounts/{accountId}/entityUserLinks", + "httpMethod": "POST", + "description": "Adds a new user to the given account.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to create the user link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId" + ], + "request": { + "$ref": "EntityUserLink" + }, + "response": { + "$ref": "EntityUserLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users" + ] + }, + "list": { + "id": "analytics.management.accountUserLinks.list", + "path": "management/accounts/{accountId}/entityUserLinks", + "httpMethod": "GET", + "description": "Lists account-user links for a given account.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve the user links for.", + "required": true, + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of account-user links to include in this response.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first account-user link to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + } + }, + "parameterOrder": [ + "accountId" + ], + "response": { + "$ref": "EntityUserLinks" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users", + "https://www.googleapis.com/auth/analytics.manage.users.readonly" + ] + }, + "update": { + "id": "analytics.management.accountUserLinks.update", + "path": "management/accounts/{accountId}/entityUserLinks/{linkId}", + "httpMethod": "PUT", + "description": "Updates permissions for an existing user on the given account.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to update the account-user link for.", + "required": true, + "location": "path" + }, + "linkId": { + "type": "string", + "description": "Link ID to update the account-user link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "linkId" + ], + "request": { + "$ref": "EntityUserLink" + }, + "response": { + "$ref": "EntityUserLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users" + ] + } + } + }, + "accounts": { + "methods": { + "list": { + "id": "analytics.management.accounts.list", + "path": "management/accounts", + "httpMethod": "GET", + "description": "Lists all accounts to which the user has access.", + "parameters": { + "max-results": { + "type": "integer", + "description": "The maximum number of accounts to include in this response.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first account to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + } + }, + "response": { + "$ref": "Accounts" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + } + } + }, + "customDataSources": { + "methods": { + "list": { + "id": "analytics.management.customDataSources.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources", + "httpMethod": "GET", + "description": "List custom data sources to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account Id for the custom data sources to retrieve.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of custom data sources to include in this response.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "A 1-based index of the first custom data source to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property Id for the custom data sources to retrieve.", + "required": true, + "pattern": "UA-(\\d+)-(\\d+)", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "response": { + "$ref": "CustomDataSources" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + } + } + }, + "customDimensions": { + "methods": { + "get": { + "id": "analytics.management.customDimensions.get", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions/{customDimensionId}", + "httpMethod": "GET", + "description": "Get a custom dimension to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the custom dimension to retrieve.", + "required": true, + "location": "path" + }, + "customDimensionId": { + "type": "string", + "description": "The ID of the custom dimension to retrieve.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the custom dimension to retrieve.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "customDimensionId" + ], + "response": { + "$ref": "CustomDimension" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "insert": { + "id": "analytics.management.customDimensions.insert", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions", + "httpMethod": "POST", + "description": "Create a new custom dimension.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the custom dimension to create.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the custom dimension to create.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "request": { + "$ref": "CustomDimension" + }, + "response": { + "$ref": "CustomDimension" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "list": { + "id": "analytics.management.customDimensions.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions", + "httpMethod": "GET", + "description": "Lists custom dimensions to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the custom dimensions to retrieve.", + "required": true, + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of custom dimensions to include in this response.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the custom dimensions to retrieve.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "response": { + "$ref": "CustomDimensions" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "patch": { + "id": "analytics.management.customDimensions.patch", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions/{customDimensionId}", + "httpMethod": "PATCH", + "description": "Updates an existing custom dimension. This method supports patch semantics.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the custom dimension to update.", + "required": true, + "location": "path" + }, + "customDimensionId": { + "type": "string", + "description": "Custom dimension ID for the custom dimension to update.", + "required": true, + "location": "path" + }, + "ignoreCustomDataSourceLinks": { + "type": "boolean", + "description": "Force the update and ignore any warnings related to the custom dimension being linked to a custom data source / data set.", + "default": "false", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the custom dimension to update.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "customDimensionId" + ], + "request": { + "$ref": "CustomDimension" + }, + "response": { + "$ref": "CustomDimension" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "update": { + "id": "analytics.management.customDimensions.update", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions/{customDimensionId}", + "httpMethod": "PUT", + "description": "Updates an existing custom dimension.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the custom dimension to update.", + "required": true, + "location": "path" + }, + "customDimensionId": { + "type": "string", + "description": "Custom dimension ID for the custom dimension to update.", + "required": true, + "location": "path" + }, + "ignoreCustomDataSourceLinks": { + "type": "boolean", + "description": "Force the update and ignore any warnings related to the custom dimension being linked to a custom data source / data set.", + "default": "false", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the custom dimension to update.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "customDimensionId" + ], + "request": { + "$ref": "CustomDimension" + }, + "response": { + "$ref": "CustomDimension" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + } + } + }, + "customMetrics": { + "methods": { + "get": { + "id": "analytics.management.customMetrics.get", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics/{customMetricId}", + "httpMethod": "GET", + "description": "Get a custom metric to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the custom metric to retrieve.", + "required": true, + "location": "path" + }, + "customMetricId": { + "type": "string", + "description": "The ID of the custom metric to retrieve.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the custom metric to retrieve.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "customMetricId" + ], + "response": { + "$ref": "CustomMetric" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "insert": { + "id": "analytics.management.customMetrics.insert", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics", + "httpMethod": "POST", + "description": "Create a new custom metric.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the custom metric to create.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the custom dimension to create.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "request": { + "$ref": "CustomMetric" + }, + "response": { + "$ref": "CustomMetric" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "list": { + "id": "analytics.management.customMetrics.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics", + "httpMethod": "GET", + "description": "Lists custom metrics to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the custom metrics to retrieve.", + "required": true, + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of custom metrics to include in this response.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the custom metrics to retrieve.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "response": { + "$ref": "CustomMetrics" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "patch": { + "id": "analytics.management.customMetrics.patch", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics/{customMetricId}", + "httpMethod": "PATCH", + "description": "Updates an existing custom metric. This method supports patch semantics.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the custom metric to update.", + "required": true, + "location": "path" + }, + "customMetricId": { + "type": "string", + "description": "Custom metric ID for the custom metric to update.", + "required": true, + "location": "path" + }, + "ignoreCustomDataSourceLinks": { + "type": "boolean", + "description": "Force the update and ignore any warnings related to the custom metric being linked to a custom data source / data set.", + "default": "false", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the custom metric to update.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "customMetricId" + ], + "request": { + "$ref": "CustomMetric" + }, + "response": { + "$ref": "CustomMetric" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "update": { + "id": "analytics.management.customMetrics.update", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics/{customMetricId}", + "httpMethod": "PUT", + "description": "Updates an existing custom metric.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the custom metric to update.", + "required": true, + "location": "path" + }, + "customMetricId": { + "type": "string", + "description": "Custom metric ID for the custom metric to update.", + "required": true, + "location": "path" + }, + "ignoreCustomDataSourceLinks": { + "type": "boolean", + "description": "Force the update and ignore any warnings related to the custom metric being linked to a custom data source / data set.", + "default": "false", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the custom metric to update.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "customMetricId" + ], + "request": { + "$ref": "CustomMetric" + }, + "response": { + "$ref": "CustomMetric" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + } + } + }, + "experiments": { + "methods": { + "delete": { + "id": "analytics.management.experiments.delete", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}", + "httpMethod": "DELETE", + "description": "Delete an experiment.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to which the experiment belongs", + "required": true, + "location": "path" + }, + "experimentId": { + "type": "string", + "description": "ID of the experiment to delete", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to which the experiment belongs", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to which the experiment belongs", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "experimentId" + ], + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "get": { + "id": "analytics.management.experiments.get", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}", + "httpMethod": "GET", + "description": "Returns an experiment to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve the experiment for.", + "required": true, + "location": "path" + }, + "experimentId": { + "type": "string", + "description": "Experiment ID to retrieve the experiment for.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to retrieve the experiment for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve the experiment for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "experimentId" + ], + "response": { + "$ref": "Experiment" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "insert": { + "id": "analytics.management.experiments.insert", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments", + "httpMethod": "POST", + "description": "Create a new experiment.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to create the experiment for.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to create the experiment for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to create the experiment for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "request": { + "$ref": "Experiment" + }, + "response": { + "$ref": "Experiment" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "list": { + "id": "analytics.management.experiments.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments", + "httpMethod": "GET", + "description": "Lists experiments to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve experiments for.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of experiments to include in this response.", + "format": "int32", + "location": "query" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to retrieve experiments for.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "start-index": { + "type": "integer", + "description": "An index of the first experiment to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve experiments for.", + "required": true, + "pattern": "UA-(\\d+)-(\\d+)", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "response": { + "$ref": "Experiments" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "patch": { + "id": "analytics.management.experiments.patch", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}", + "httpMethod": "PATCH", + "description": "Update an existing experiment. This method supports patch semantics.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID of the experiment to update.", + "required": true, + "location": "path" + }, + "experimentId": { + "type": "string", + "description": "Experiment ID of the experiment to update.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID of the experiment to update.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID of the experiment to update.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "experimentId" + ], + "request": { + "$ref": "Experiment" + }, + "response": { + "$ref": "Experiment" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "update": { + "id": "analytics.management.experiments.update", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}", + "httpMethod": "PUT", + "description": "Update an existing experiment.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID of the experiment to update.", + "required": true, + "location": "path" + }, + "experimentId": { + "type": "string", + "description": "Experiment ID of the experiment to update.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID of the experiment to update.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID of the experiment to update.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "experimentId" + ], + "request": { + "$ref": "Experiment" + }, + "response": { + "$ref": "Experiment" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit" + ] + } + } + }, + "filters": { + "methods": { + "delete": { + "id": "analytics.management.filters.delete", + "path": "management/accounts/{accountId}/filters/{filterId}", + "httpMethod": "DELETE", + "description": "Delete a filter.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to delete the filter for.", + "required": true, + "location": "path" + }, + "filterId": { + "type": "string", + "description": "ID of the filter to be deleted.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "filterId" + ], + "response": { + "$ref": "Filter" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "get": { + "id": "analytics.management.filters.get", + "path": "management/accounts/{accountId}/filters/{filterId}", + "httpMethod": "GET", + "description": "Returns a filters to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve filters for.", + "required": true, + "location": "path" + }, + "filterId": { + "type": "string", + "description": "Filter ID to retrieve filters for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "filterId" + ], + "response": { + "$ref": "Filter" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "insert": { + "id": "analytics.management.filters.insert", + "path": "management/accounts/{accountId}/filters", + "httpMethod": "POST", + "description": "Create a new filter.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to create filter for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId" + ], + "request": { + "$ref": "Filter" + }, + "response": { + "$ref": "Filter" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "list": { + "id": "analytics.management.filters.list", + "path": "management/accounts/{accountId}/filters", + "httpMethod": "GET", + "description": "Lists all filters for an account", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve filters for.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of filters to include in this response.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + } + }, + "parameterOrder": [ + "accountId" + ], + "response": { + "$ref": "Filters" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "patch": { + "id": "analytics.management.filters.patch", + "path": "management/accounts/{accountId}/filters/{filterId}", + "httpMethod": "PATCH", + "description": "Updates an existing filter. This method supports patch semantics.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to which the filter belongs.", + "required": true, + "location": "path" + }, + "filterId": { + "type": "string", + "description": "ID of the filter to be updated.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "filterId" + ], + "request": { + "$ref": "Filter" + }, + "response": { + "$ref": "Filter" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "update": { + "id": "analytics.management.filters.update", + "path": "management/accounts/{accountId}/filters/{filterId}", + "httpMethod": "PUT", + "description": "Updates an existing filter.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to which the filter belongs.", + "required": true, + "location": "path" + }, + "filterId": { + "type": "string", + "description": "ID of the filter to be updated.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "filterId" + ], + "request": { + "$ref": "Filter" + }, + "response": { + "$ref": "Filter" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + } + } + }, + "goals": { + "methods": { + "get": { + "id": "analytics.management.goals.get", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals/{goalId}", + "httpMethod": "GET", + "description": "Gets a goal to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve the goal for.", + "required": true, + "location": "path" + }, + "goalId": { + "type": "string", + "description": "Goal ID to retrieve the goal for.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to retrieve the goal for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve the goal for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "goalId" + ], + "response": { + "$ref": "Goal" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "insert": { + "id": "analytics.management.goals.insert", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals", + "httpMethod": "POST", + "description": "Create a new goal.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to create the goal for.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to create the goal for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to create the goal for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "request": { + "$ref": "Goal" + }, + "response": { + "$ref": "Goal" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "list": { + "id": "analytics.management.goals.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals", + "httpMethod": "GET", + "description": "Lists goals to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve goals for. Can either be a specific account ID or '~all', which refers to all the accounts that user has access to.", + "required": true, + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of goals to include in this response.", + "format": "int32", + "location": "query" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to retrieve goals for. Can either be a specific view (profile) ID or '~all', which refers to all the views (profiles) that user has access to.", + "required": true, + "location": "path" + }, + "start-index": { + "type": "integer", + "description": "An index of the first goal to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve goals for. Can either be a specific web property ID or '~all', which refers to all the web properties that user has access to.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "response": { + "$ref": "Goals" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "patch": { + "id": "analytics.management.goals.patch", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals/{goalId}", + "httpMethod": "PATCH", + "description": "Updates an existing view (profile). This method supports patch semantics.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to update the goal.", + "required": true, + "location": "path" + }, + "goalId": { + "type": "string", + "description": "Index of the goal to be updated.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to update the goal.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to update the goal.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "goalId" + ], + "request": { + "$ref": "Goal" + }, + "response": { + "$ref": "Goal" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "update": { + "id": "analytics.management.goals.update", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals/{goalId}", + "httpMethod": "PUT", + "description": "Updates an existing view (profile).", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to update the goal.", + "required": true, + "location": "path" + }, + "goalId": { + "type": "string", + "description": "Index of the goal to be updated.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to update the goal.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to update the goal.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "goalId" + ], + "request": { + "$ref": "Goal" + }, + "response": { + "$ref": "Goal" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + } + } + }, + "profileFilterLinks": { + "methods": { + "delete": { + "id": "analytics.management.profileFilterLinks.delete", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}", + "httpMethod": "DELETE", + "description": "Delete a profile filter link.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to which the profile filter link belongs.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "linkId": { + "type": "string", + "description": "ID of the profile filter link to delete.", + "required": true, + "pattern": "\\d+:\\d+", + "location": "path" + }, + "profileId": { + "type": "string", + "description": "Profile ID to which the filter link belongs.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property Id to which the profile filter link belongs.", + "required": true, + "pattern": "UA-(\\d+)-(\\d+)", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "linkId" + ], + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "get": { + "id": "analytics.management.profileFilterLinks.get", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}", + "httpMethod": "GET", + "description": "Returns a single profile filter link.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve profile filter link for.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "linkId": { + "type": "string", + "description": "ID of the profile filter link.", + "required": true, + "pattern": "\\d+:\\d+", + "location": "path" + }, + "profileId": { + "type": "string", + "description": "Profile ID to retrieve filter link for.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property Id to retrieve profile filter link for.", + "required": true, + "pattern": "UA-(\\d+)-(\\d+)", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "linkId" + ], + "response": { + "$ref": "ProfileFilterLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "insert": { + "id": "analytics.management.profileFilterLinks.insert", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks", + "httpMethod": "POST", + "description": "Create a new profile filter link.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to create profile filter link for.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "profileId": { + "type": "string", + "description": "Profile ID to create filter link for.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property Id to create profile filter link for.", + "required": true, + "pattern": "UA-(\\d+)-(\\d+)", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "request": { + "$ref": "ProfileFilterLink" + }, + "response": { + "$ref": "ProfileFilterLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "list": { + "id": "analytics.management.profileFilterLinks.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks", + "httpMethod": "GET", + "description": "Lists all profile filter links for a profile.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve profile filter links for.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of profile filter links to include in this response.", + "format": "int32", + "location": "query" + }, + "profileId": { + "type": "string", + "description": "Profile ID to retrieve filter links for. Can either be a specific profile ID or '~all', which refers to all the profiles that user has access to.", + "required": true, + "location": "path" + }, + "start-index": { + "type": "integer", + "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property Id for profile filter links for. Can either be a specific web property ID or '~all', which refers to all the web properties that user has access to.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "response": { + "$ref": "ProfileFilterLinks" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "patch": { + "id": "analytics.management.profileFilterLinks.patch", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}", + "httpMethod": "PATCH", + "description": "Update an existing profile filter link. This method supports patch semantics.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to which profile filter link belongs.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "linkId": { + "type": "string", + "description": "ID of the profile filter link to be updated.", + "required": true, + "pattern": "\\d+:\\d+", + "location": "path" + }, + "profileId": { + "type": "string", + "description": "Profile ID to which filter link belongs", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property Id to which profile filter link belongs", + "required": true, + "pattern": "UA-(\\d+)-(\\d+)", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "linkId" + ], + "request": { + "$ref": "ProfileFilterLink" + }, + "response": { + "$ref": "ProfileFilterLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "update": { + "id": "analytics.management.profileFilterLinks.update", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}", + "httpMethod": "PUT", + "description": "Update an existing profile filter link.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to which profile filter link belongs.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "linkId": { + "type": "string", + "description": "ID of the profile filter link to be updated.", + "required": true, + "pattern": "\\d+:\\d+", + "location": "path" + }, + "profileId": { + "type": "string", + "description": "Profile ID to which filter link belongs", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property Id to which profile filter link belongs", + "required": true, + "pattern": "UA-(\\d+)-(\\d+)", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "linkId" + ], + "request": { + "$ref": "ProfileFilterLink" + }, + "response": { + "$ref": "ProfileFilterLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + } + } + }, + "profileUserLinks": { + "methods": { + "delete": { + "id": "analytics.management.profileUserLinks.delete", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks/{linkId}", + "httpMethod": "DELETE", + "description": "Removes a user from the given view (profile).", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to delete the user link for.", + "required": true, + "location": "path" + }, + "linkId": { + "type": "string", + "description": "Link ID to delete the user link for.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to delete the user link for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web Property ID to delete the user link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "linkId" + ], + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users" + ] + }, + "insert": { + "id": "analytics.management.profileUserLinks.insert", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks", + "httpMethod": "POST", + "description": "Adds a new user to the given view (profile).", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to create the user link for.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to create the user link for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web Property ID to create the user link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "request": { + "$ref": "EntityUserLink" + }, + "response": { + "$ref": "EntityUserLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users" + ] + }, + "list": { + "id": "analytics.management.profileUserLinks.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks", + "httpMethod": "GET", + "description": "Lists profile-user links for a given view (profile).", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID which the given view (profile) belongs to.", + "required": true, + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of profile-user links to include in this response.", + "format": "int32", + "location": "query" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to retrieve the profile-user links for. Can either be a specific profile ID or '~all', which refers to all the profiles that user has access to.", + "required": true, + "location": "path" + }, + "start-index": { + "type": "integer", + "description": "An index of the first profile-user link to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web Property ID which the given view (profile) belongs to. Can either be a specific web property ID or '~all', which refers to all the web properties that user has access to.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "response": { + "$ref": "EntityUserLinks" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users", + "https://www.googleapis.com/auth/analytics.manage.users.readonly" + ] + }, + "update": { + "id": "analytics.management.profileUserLinks.update", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks/{linkId}", + "httpMethod": "PUT", + "description": "Updates permissions for an existing user on the given view (profile).", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to update the user link for.", + "required": true, + "location": "path" + }, + "linkId": { + "type": "string", + "description": "Link ID to update the user link for.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile ID) to update the user link for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web Property ID to update the user link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "linkId" + ], + "request": { + "$ref": "EntityUserLink" + }, + "response": { + "$ref": "EntityUserLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users" + ] + } + } + }, + "profiles": { + "methods": { + "delete": { + "id": "analytics.management.profiles.delete", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}", + "httpMethod": "DELETE", + "description": "Deletes a view (profile).", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to delete the view (profile) for.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "ID of the view (profile) to be deleted.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to delete the view (profile) for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "get": { + "id": "analytics.management.profiles.get", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}", + "httpMethod": "GET", + "description": "Gets a view (profile) to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve the goal for.", + "required": true, + "pattern": "[0-9]+", + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to retrieve the goal for.", + "required": true, + "pattern": "[0-9]+", + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve the goal for.", + "required": true, + "pattern": "UA-[0-9]+-[0-9]+", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "response": { + "$ref": "Profile" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "insert": { + "id": "analytics.management.profiles.insert", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles", + "httpMethod": "POST", + "description": "Create a new view (profile).", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to create the view (profile) for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to create the view (profile) for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "request": { + "$ref": "Profile" + }, + "response": { + "$ref": "Profile" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "list": { + "id": "analytics.management.profiles.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles", + "httpMethod": "GET", + "description": "Lists views (profiles) to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID for the view (profiles) to retrieve. Can either be a specific account ID or '~all', which refers to all the accounts to which the user has access.", + "required": true, + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of views (profiles) to include in this response.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID for the views (profiles) to retrieve. Can either be a specific web property ID or '~all', which refers to all the web properties to which the user has access.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "response": { + "$ref": "Profiles" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "patch": { + "id": "analytics.management.profiles.patch", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}", + "httpMethod": "PATCH", + "description": "Updates an existing view (profile). This method supports patch semantics.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to which the view (profile) belongs", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "ID of the view (profile) to be updated.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to which the view (profile) belongs", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "request": { + "$ref": "Profile" + }, + "response": { + "$ref": "Profile" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "update": { + "id": "analytics.management.profiles.update", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}", + "httpMethod": "PUT", + "description": "Updates an existing view (profile).", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to which the view (profile) belongs", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "ID of the view (profile) to be updated.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to which the view (profile) belongs", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "request": { + "$ref": "Profile" + }, + "response": { + "$ref": "Profile" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + } + } + }, + "segments": { + "methods": { + "list": { + "id": "analytics.management.segments.list", + "path": "management/segments", + "httpMethod": "GET", + "description": "Lists segments to which the user has access.", + "parameters": { + "max-results": { + "type": "integer", + "description": "The maximum number of segments to include in this response.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first segment to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + } + }, + "response": { + "$ref": "Segments" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + } + } + }, + "unsampledReports": { + "methods": { + "get": { + "id": "analytics.management.unsampledReports.get", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/unsampledReports/{unsampledReportId}", + "httpMethod": "GET", + "description": "Returns a single unsampled report.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve unsampled report for.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to retrieve unsampled report for.", + "required": true, + "location": "path" + }, + "unsampledReportId": { + "type": "string", + "description": "ID of the unsampled report to retrieve.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve unsampled reports for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId", + "unsampledReportId" + ], + "response": { + "$ref": "UnsampledReport" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "insert": { + "id": "analytics.management.unsampledReports.insert", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/unsampledReports", + "httpMethod": "POST", + "description": "Create a new unsampled report.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to create the unsampled report for.", + "required": true, + "location": "path" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to create the unsampled report for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to create the unsampled report for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "request": { + "$ref": "UnsampledReport" + }, + "response": { + "$ref": "UnsampledReport" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "list": { + "id": "analytics.management.unsampledReports.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/unsampledReports", + "httpMethod": "GET", + "description": "Lists unsampled reports to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve unsampled reports for. Must be a specific account ID, ~all is not supported.", + "required": true, + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of unsampled reports to include in this response.", + "format": "int32", + "location": "query" + }, + "profileId": { + "type": "string", + "description": "View (Profile) ID to retrieve unsampled reports for. Must be a specific view (profile) ID, ~all is not supported.", + "required": true, + "location": "path" + }, + "start-index": { + "type": "integer", + "description": "An index of the first unsampled report to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve unsampled reports for. Must be a specific web property ID, ~all is not supported.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "profileId" + ], + "response": { + "$ref": "UnsampledReports" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + } + } + }, + "uploads": { + "methods": { + "deleteUploadData": { + "id": "analytics.management.uploads.deleteUploadData", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/deleteUploadData", + "httpMethod": "POST", + "description": "Delete data associated with a previous upload.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account Id for the uploads to be deleted.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "customDataSourceId": { + "type": "string", + "description": "Custom data source Id for the uploads to be deleted.", + "required": true, + "pattern": ".{22}", + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property Id for the uploads to be deleted.", + "required": true, + "pattern": "UA-(\\d+)-(\\d+)", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "customDataSourceId" + ], + "request": { + "$ref": "AnalyticsDataimportDeleteUploadDataRequest" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "get": { + "id": "analytics.management.uploads.get", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads/{uploadId}", + "httpMethod": "GET", + "description": "List uploads to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account Id for the upload to retrieve.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "customDataSourceId": { + "type": "string", + "description": "Custom data source Id for upload to retrieve.", + "required": true, + "pattern": ".{22}", + "location": "path" + }, + "uploadId": { + "type": "string", + "description": "Upload Id to retrieve.", + "required": true, + "pattern": ".{22}", + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property Id for the upload to retrieve.", + "required": true, + "pattern": "UA-(\\d+)-(\\d+)", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "customDataSourceId", + "uploadId" + ], + "response": { + "$ref": "Upload" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "list": { + "id": "analytics.management.uploads.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads", + "httpMethod": "GET", + "description": "List uploads to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account Id for the uploads to retrieve.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "customDataSourceId": { + "type": "string", + "description": "Custom data source Id for uploads to retrieve.", + "required": true, + "pattern": ".{22}", + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of uploads to include in this response.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "A 1-based index of the first upload to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property Id for the uploads to retrieve.", + "required": true, + "pattern": "UA-(\\d+)-(\\d+)", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "customDataSourceId" + ], + "response": { + "$ref": "Uploads" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "uploadData": { + "id": "analytics.management.uploads.uploadData", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads", + "httpMethod": "POST", + "description": "Upload data for a custom data source.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account Id associated with the upload.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "customDataSourceId": { + "type": "string", + "description": "Custom data source Id to which the data being uploaded belongs.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property UA-string associated with the upload.", + "required": true, + "pattern": "UA-\\d+-\\d+", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "customDataSourceId" + ], + "response": { + "$ref": "Upload" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit" + ], + "supportsMediaUpload": true, + "mediaUpload": { + "accept": [ + "application/octet-stream" + ], + "maxSize": "1GB", + "protocols": { + "simple": { + "multipart": true, + "path": "/upload/analytics/v3/management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads" + }, + "resumable": { + "multipart": true, + "path": "/resumable/upload/analytics/v3/management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads" + } + } + } + } + } + }, + "webPropertyAdWordsLinks": { + "methods": { + "delete": { + "id": "analytics.management.webPropertyAdWordsLinks.delete", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}", + "httpMethod": "DELETE", + "description": "Deletes a web property-AdWords link.", + "parameters": { + "accountId": { + "type": "string", + "description": "ID of the account which the given web property belongs to.", + "required": true, + "location": "path" + }, + "webPropertyAdWordsLinkId": { + "type": "string", + "description": "Web property AdWords link ID.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to delete the AdWords link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "webPropertyAdWordsLinkId" + ], + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "get": { + "id": "analytics.management.webPropertyAdWordsLinks.get", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}", + "httpMethod": "GET", + "description": "Returns a web property-AdWords link to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "ID of the account which the given web property belongs to.", + "required": true, + "location": "path" + }, + "webPropertyAdWordsLinkId": { + "type": "string", + "description": "Web property-AdWords link ID.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve the AdWords link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "webPropertyAdWordsLinkId" + ], + "response": { + "$ref": "EntityAdWordsLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "insert": { + "id": "analytics.management.webPropertyAdWordsLinks.insert", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks", + "httpMethod": "POST", + "description": "Creates a webProperty-AdWords link.", + "parameters": { + "accountId": { + "type": "string", + "description": "ID of the Google Analytics account to create the link for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to create the link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "request": { + "$ref": "EntityAdWordsLink" + }, + "response": { + "$ref": "EntityAdWordsLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "list": { + "id": "analytics.management.webPropertyAdWordsLinks.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks", + "httpMethod": "GET", + "description": "Lists webProperty-AdWords links for a given web property.", + "parameters": { + "accountId": { + "type": "string", + "description": "ID of the account which the given web property belongs to.", + "required": true, + "pattern": "\\d+", + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of webProperty-AdWords links to include in this response.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first webProperty-AdWords link to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve the AdWords links for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "response": { + "$ref": "EntityAdWordsLinks" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "patch": { + "id": "analytics.management.webPropertyAdWordsLinks.patch", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}", + "httpMethod": "PATCH", + "description": "Updates an existing webProperty-AdWords link. This method supports patch semantics.", + "parameters": { + "accountId": { + "type": "string", + "description": "ID of the account which the given web property belongs to.", + "required": true, + "location": "path" + }, + "webPropertyAdWordsLinkId": { + "type": "string", + "description": "Web property-AdWords link ID.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve the AdWords link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "webPropertyAdWordsLinkId" + ], + "request": { + "$ref": "EntityAdWordsLink" + }, + "response": { + "$ref": "EntityAdWordsLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "update": { + "id": "analytics.management.webPropertyAdWordsLinks.update", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}", + "httpMethod": "PUT", + "description": "Updates an existing webProperty-AdWords link.", + "parameters": { + "accountId": { + "type": "string", + "description": "ID of the account which the given web property belongs to.", + "required": true, + "location": "path" + }, + "webPropertyAdWordsLinkId": { + "type": "string", + "description": "Web property-AdWords link ID.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to retrieve the AdWords link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "webPropertyAdWordsLinkId" + ], + "request": { + "$ref": "EntityAdWordsLink" + }, + "response": { + "$ref": "EntityAdWordsLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + } + } + }, + "webproperties": { + "methods": { + "get": { + "id": "analytics.management.webproperties.get", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}", + "httpMethod": "GET", + "description": "Gets a web property to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve the web property for.", + "required": true, + "pattern": "[0-9]+", + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "ID to retrieve the web property for.", + "required": true, + "pattern": "UA-[0-9]+-[0-9]+", + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "response": { + "$ref": "Webproperty" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "insert": { + "id": "analytics.management.webproperties.insert", + "path": "management/accounts/{accountId}/webproperties", + "httpMethod": "POST", + "description": "Create a new property if the account has fewer than 20 properties. Web properties are visible in the Google Analytics interface only if they have at least one profile.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to create the web property for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId" + ], + "request": { + "$ref": "Webproperty" + }, + "response": { + "$ref": "Webproperty" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "list": { + "id": "analytics.management.webproperties.list", + "path": "management/accounts/{accountId}/webproperties", + "httpMethod": "GET", + "description": "Lists web properties to which the user has access.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to retrieve web properties for. Can either be a specific account ID or '~all', which refers to all the accounts that user has access to.", + "required": true, + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of web properties to include in this response.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + } + }, + "parameterOrder": [ + "accountId" + ], + "response": { + "$ref": "Webproperties" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + }, + "patch": { + "id": "analytics.management.webproperties.patch", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}", + "httpMethod": "PATCH", + "description": "Updates an existing web property. This method supports patch semantics.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to which the web property belongs", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "request": { + "$ref": "Webproperty" + }, + "response": { + "$ref": "Webproperty" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + }, + "update": { + "id": "analytics.management.webproperties.update", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}", + "httpMethod": "PUT", + "description": "Updates an existing web property.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to which the web property belongs", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "request": { + "$ref": "Webproperty" + }, + "response": { + "$ref": "Webproperty" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.edit" + ] + } + } + }, + "webpropertyUserLinks": { + "methods": { + "delete": { + "id": "analytics.management.webpropertyUserLinks.delete", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks/{linkId}", + "httpMethod": "DELETE", + "description": "Removes a user from the given web property.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to delete the user link for.", + "required": true, + "location": "path" + }, + "linkId": { + "type": "string", + "description": "Link ID to delete the user link for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web Property ID to delete the user link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "linkId" + ], + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users" + ] + }, + "insert": { + "id": "analytics.management.webpropertyUserLinks.insert", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks", + "httpMethod": "POST", + "description": "Adds a new user to the given web property.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to create the user link for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web Property ID to create the user link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "request": { + "$ref": "EntityUserLink" + }, + "response": { + "$ref": "EntityUserLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users" + ] + }, + "list": { + "id": "analytics.management.webpropertyUserLinks.list", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks", + "httpMethod": "GET", + "description": "Lists webProperty-user links for a given web property.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID which the given web property belongs to.", + "required": true, + "location": "path" + }, + "max-results": { + "type": "integer", + "description": "The maximum number of webProperty-user Links to include in this response.", + "format": "int32", + "location": "query" + }, + "start-index": { + "type": "integer", + "description": "An index of the first webProperty-user link to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "webPropertyId": { + "type": "string", + "description": "Web Property ID for the webProperty-user links to retrieve. Can either be a specific web property ID or '~all', which refers to all the web properties that user has access to.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId" + ], + "response": { + "$ref": "EntityUserLinks" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users", + "https://www.googleapis.com/auth/analytics.manage.users.readonly" + ] + }, + "update": { + "id": "analytics.management.webpropertyUserLinks.update", + "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks/{linkId}", + "httpMethod": "PUT", + "description": "Updates permissions for an existing user on the given web property.", + "parameters": { + "accountId": { + "type": "string", + "description": "Account ID to update the account-user link for.", + "required": true, + "location": "path" + }, + "linkId": { + "type": "string", + "description": "Link ID to update the account-user link for.", + "required": true, + "location": "path" + }, + "webPropertyId": { + "type": "string", + "description": "Web property ID to update the account-user link for.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "accountId", + "webPropertyId", + "linkId" + ], + "request": { + "$ref": "EntityUserLink" + }, + "response": { + "$ref": "EntityUserLink" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.manage.users" + ] + } + } + } + } + }, + "metadata": { + "resources": { + "columns": { + "methods": { + "list": { + "id": "analytics.metadata.columns.list", + "path": "metadata/{reportType}/columns", + "httpMethod": "GET", + "description": "Lists all columns for a report type", + "parameters": { + "reportType": { + "type": "string", + "description": "Report type. Allowed Values: 'ga'. Where 'ga' corresponds to the Core Reporting API", + "required": true, + "pattern": "ga", + "location": "path" + } + }, + "parameterOrder": [ + "reportType" + ], + "response": { + "$ref": "Columns" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.edit", + "https://www.googleapis.com/auth/analytics.readonly" + ] + } + } + } + } + }, + "provisioning": { + "methods": { + "createAccountTicket": { + "id": "analytics.provisioning.createAccountTicket", + "path": "provisioning/createAccountTicket", + "httpMethod": "POST", + "description": "Creates an account ticket.", + "request": { + "$ref": "AccountTicket" + }, + "response": { + "$ref": "AccountTicket" + }, + "scopes": [ + "https://www.googleapis.com/auth/analytics.provision" + ] + } + } + } + } +} diff --git a/_third_party/google.golang.org/api/analytics/v3/analytics-gen.go b/_third_party/google.golang.org/api/analytics/v3/analytics-gen.go new file mode 100644 index 0000000000..7b712f5d2b --- /dev/null +++ b/_third_party/google.golang.org/api/analytics/v3/analytics-gen.go @@ -0,0 +1,16243 @@ +// Package analytics provides access to the Google Analytics API. +// +// See https://developers.google.com/analytics/ +// +// Usage example: +// +// import "google.golang.org/api/analytics/v3" +// ... +// analyticsService, err := analytics.New(oauthHttpClient) +package analytics // import "bosun.org/_third_party/google.golang.org/api/analytics/v3" + +import ( + "bosun.org/_third_party/golang.org/x/net/context" + "bosun.org/_third_party/golang.org/x/net/context/ctxhttp" + "bosun.org/_third_party/google.golang.org/api/googleapi" + "bosun.org/_third_party/google.golang.org/api/internal" + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" +) + +// Always reference these packages, just in case the auto-generated code +// below doesn't. +var _ = bytes.NewBuffer +var _ = strconv.Itoa +var _ = fmt.Sprintf +var _ = json.NewDecoder +var _ = io.Copy +var _ = url.Parse +var _ = googleapi.Version +var _ = errors.New +var _ = strings.Replace +var _ = internal.MarshalJSON +var _ = context.Canceled +var _ = ctxhttp.Do + +const apiId = "analytics:v3" +const apiName = "analytics" +const apiVersion = "v3" +const basePath = "https://www.googleapis.com/analytics/v3/" + +// OAuth2 scopes used by this API. +const ( + // View and manage your Google Analytics data + AnalyticsScope = "https://www.googleapis.com/auth/analytics" + + // Edit Google Analytics management entities + AnalyticsEditScope = "https://www.googleapis.com/auth/analytics.edit" + + // Manage Google Analytics Account users by email address + AnalyticsManageUsersScope = "https://www.googleapis.com/auth/analytics.manage.users" + + // View Google Analytics user permissions + AnalyticsManageUsersReadonlyScope = "https://www.googleapis.com/auth/analytics.manage.users.readonly" + + // Create a new Google Analytics account along with its default property + // and view + AnalyticsProvisionScope = "https://www.googleapis.com/auth/analytics.provision" + + // View your Google Analytics data + AnalyticsReadonlyScope = "https://www.googleapis.com/auth/analytics.readonly" +) + +func New(client *http.Client) (*Service, error) { + if client == nil { + return nil, errors.New("client is nil") + } + s := &Service{client: client, BasePath: basePath} + s.Data = NewDataService(s) + s.Management = NewManagementService(s) + s.Metadata = NewMetadataService(s) + s.Provisioning = NewProvisioningService(s) + return s, nil +} + +type Service struct { + client *http.Client + BasePath string // API endpoint base URL + UserAgent string // optional additional User-Agent fragment + + Data *DataService + + Management *ManagementService + + Metadata *MetadataService + + Provisioning *ProvisioningService +} + +func (s *Service) userAgent() string { + if s.UserAgent == "" { + return googleapi.UserAgent + } + return googleapi.UserAgent + " " + s.UserAgent +} + +func NewDataService(s *Service) *DataService { + rs := &DataService{s: s} + rs.Ga = NewDataGaService(s) + rs.Mcf = NewDataMcfService(s) + rs.Realtime = NewDataRealtimeService(s) + return rs +} + +type DataService struct { + s *Service + + Ga *DataGaService + + Mcf *DataMcfService + + Realtime *DataRealtimeService +} + +func NewDataGaService(s *Service) *DataGaService { + rs := &DataGaService{s: s} + return rs +} + +type DataGaService struct { + s *Service +} + +func NewDataMcfService(s *Service) *DataMcfService { + rs := &DataMcfService{s: s} + return rs +} + +type DataMcfService struct { + s *Service +} + +func NewDataRealtimeService(s *Service) *DataRealtimeService { + rs := &DataRealtimeService{s: s} + return rs +} + +type DataRealtimeService struct { + s *Service +} + +func NewManagementService(s *Service) *ManagementService { + rs := &ManagementService{s: s} + rs.AccountSummaries = NewManagementAccountSummariesService(s) + rs.AccountUserLinks = NewManagementAccountUserLinksService(s) + rs.Accounts = NewManagementAccountsService(s) + rs.CustomDataSources = NewManagementCustomDataSourcesService(s) + rs.CustomDimensions = NewManagementCustomDimensionsService(s) + rs.CustomMetrics = NewManagementCustomMetricsService(s) + rs.Experiments = NewManagementExperimentsService(s) + rs.Filters = NewManagementFiltersService(s) + rs.Goals = NewManagementGoalsService(s) + rs.ProfileFilterLinks = NewManagementProfileFilterLinksService(s) + rs.ProfileUserLinks = NewManagementProfileUserLinksService(s) + rs.Profiles = NewManagementProfilesService(s) + rs.Segments = NewManagementSegmentsService(s) + rs.UnsampledReports = NewManagementUnsampledReportsService(s) + rs.Uploads = NewManagementUploadsService(s) + rs.WebPropertyAdWordsLinks = NewManagementWebPropertyAdWordsLinksService(s) + rs.Webproperties = NewManagementWebpropertiesService(s) + rs.WebpropertyUserLinks = NewManagementWebpropertyUserLinksService(s) + return rs +} + +type ManagementService struct { + s *Service + + AccountSummaries *ManagementAccountSummariesService + + AccountUserLinks *ManagementAccountUserLinksService + + Accounts *ManagementAccountsService + + CustomDataSources *ManagementCustomDataSourcesService + + CustomDimensions *ManagementCustomDimensionsService + + CustomMetrics *ManagementCustomMetricsService + + Experiments *ManagementExperimentsService + + Filters *ManagementFiltersService + + Goals *ManagementGoalsService + + ProfileFilterLinks *ManagementProfileFilterLinksService + + ProfileUserLinks *ManagementProfileUserLinksService + + Profiles *ManagementProfilesService + + Segments *ManagementSegmentsService + + UnsampledReports *ManagementUnsampledReportsService + + Uploads *ManagementUploadsService + + WebPropertyAdWordsLinks *ManagementWebPropertyAdWordsLinksService + + Webproperties *ManagementWebpropertiesService + + WebpropertyUserLinks *ManagementWebpropertyUserLinksService +} + +func NewManagementAccountSummariesService(s *Service) *ManagementAccountSummariesService { + rs := &ManagementAccountSummariesService{s: s} + return rs +} + +type ManagementAccountSummariesService struct { + s *Service +} + +func NewManagementAccountUserLinksService(s *Service) *ManagementAccountUserLinksService { + rs := &ManagementAccountUserLinksService{s: s} + return rs +} + +type ManagementAccountUserLinksService struct { + s *Service +} + +func NewManagementAccountsService(s *Service) *ManagementAccountsService { + rs := &ManagementAccountsService{s: s} + return rs +} + +type ManagementAccountsService struct { + s *Service +} + +func NewManagementCustomDataSourcesService(s *Service) *ManagementCustomDataSourcesService { + rs := &ManagementCustomDataSourcesService{s: s} + return rs +} + +type ManagementCustomDataSourcesService struct { + s *Service +} + +func NewManagementCustomDimensionsService(s *Service) *ManagementCustomDimensionsService { + rs := &ManagementCustomDimensionsService{s: s} + return rs +} + +type ManagementCustomDimensionsService struct { + s *Service +} + +func NewManagementCustomMetricsService(s *Service) *ManagementCustomMetricsService { + rs := &ManagementCustomMetricsService{s: s} + return rs +} + +type ManagementCustomMetricsService struct { + s *Service +} + +func NewManagementExperimentsService(s *Service) *ManagementExperimentsService { + rs := &ManagementExperimentsService{s: s} + return rs +} + +type ManagementExperimentsService struct { + s *Service +} + +func NewManagementFiltersService(s *Service) *ManagementFiltersService { + rs := &ManagementFiltersService{s: s} + return rs +} + +type ManagementFiltersService struct { + s *Service +} + +func NewManagementGoalsService(s *Service) *ManagementGoalsService { + rs := &ManagementGoalsService{s: s} + return rs +} + +type ManagementGoalsService struct { + s *Service +} + +func NewManagementProfileFilterLinksService(s *Service) *ManagementProfileFilterLinksService { + rs := &ManagementProfileFilterLinksService{s: s} + return rs +} + +type ManagementProfileFilterLinksService struct { + s *Service +} + +func NewManagementProfileUserLinksService(s *Service) *ManagementProfileUserLinksService { + rs := &ManagementProfileUserLinksService{s: s} + return rs +} + +type ManagementProfileUserLinksService struct { + s *Service +} + +func NewManagementProfilesService(s *Service) *ManagementProfilesService { + rs := &ManagementProfilesService{s: s} + return rs +} + +type ManagementProfilesService struct { + s *Service +} + +func NewManagementSegmentsService(s *Service) *ManagementSegmentsService { + rs := &ManagementSegmentsService{s: s} + return rs +} + +type ManagementSegmentsService struct { + s *Service +} + +func NewManagementUnsampledReportsService(s *Service) *ManagementUnsampledReportsService { + rs := &ManagementUnsampledReportsService{s: s} + return rs +} + +type ManagementUnsampledReportsService struct { + s *Service +} + +func NewManagementUploadsService(s *Service) *ManagementUploadsService { + rs := &ManagementUploadsService{s: s} + return rs +} + +type ManagementUploadsService struct { + s *Service +} + +func NewManagementWebPropertyAdWordsLinksService(s *Service) *ManagementWebPropertyAdWordsLinksService { + rs := &ManagementWebPropertyAdWordsLinksService{s: s} + return rs +} + +type ManagementWebPropertyAdWordsLinksService struct { + s *Service +} + +func NewManagementWebpropertiesService(s *Service) *ManagementWebpropertiesService { + rs := &ManagementWebpropertiesService{s: s} + return rs +} + +type ManagementWebpropertiesService struct { + s *Service +} + +func NewManagementWebpropertyUserLinksService(s *Service) *ManagementWebpropertyUserLinksService { + rs := &ManagementWebpropertyUserLinksService{s: s} + return rs +} + +type ManagementWebpropertyUserLinksService struct { + s *Service +} + +func NewMetadataService(s *Service) *MetadataService { + rs := &MetadataService{s: s} + rs.Columns = NewMetadataColumnsService(s) + return rs +} + +type MetadataService struct { + s *Service + + Columns *MetadataColumnsService +} + +func NewMetadataColumnsService(s *Service) *MetadataColumnsService { + rs := &MetadataColumnsService{s: s} + return rs +} + +type MetadataColumnsService struct { + s *Service +} + +func NewProvisioningService(s *Service) *ProvisioningService { + rs := &ProvisioningService{s: s} + return rs +} + +type ProvisioningService struct { + s *Service +} + +// Account: JSON template for Analytics account entry. +type Account struct { + // ChildLink: Child link for an account entry. Points to the list of web + // properties for this account. + ChildLink *AccountChildLink `json:"childLink,omitempty"` + + // Created: Time the account was created. + Created string `json:"created,omitempty"` + + // Id: Account ID. + Id string `json:"id,omitempty"` + + // Kind: Resource type for Analytics account. + Kind string `json:"kind,omitempty"` + + // Name: Account name. + Name string `json:"name,omitempty"` + + // Permissions: Permissions the user has for this account. + Permissions *AccountPermissions `json:"permissions,omitempty"` + + // SelfLink: Link for this account. + SelfLink string `json:"selfLink,omitempty"` + + // Updated: Time the account was last modified. + Updated string `json:"updated,omitempty"` + + // ForceSendFields is a list of field names (e.g. "ChildLink") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Account) MarshalJSON() ([]byte, error) { + type noMethod Account + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// AccountChildLink: Child link for an account entry. Points to the list +// of web properties for this account. +type AccountChildLink struct { + // Href: Link to the list of web properties for this account. + Href string `json:"href,omitempty"` + + // Type: Type of the child link. Its value is "analytics#webproperties". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *AccountChildLink) MarshalJSON() ([]byte, error) { + type noMethod AccountChildLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// AccountPermissions: Permissions the user has for this account. +type AccountPermissions struct { + // Effective: All the permissions that the user has for this account. + // These include any implied permissions (e.g., EDIT implies VIEW). + Effective []string `json:"effective,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Effective") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *AccountPermissions) MarshalJSON() ([]byte, error) { + type noMethod AccountPermissions + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// AccountRef: JSON template for a linked account. +type AccountRef struct { + // Href: Link for this account. + Href string `json:"href,omitempty"` + + // Id: Account ID. + Id string `json:"id,omitempty"` + + // Kind: Analytics account reference. + Kind string `json:"kind,omitempty"` + + // Name: Account name. + Name string `json:"name,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *AccountRef) MarshalJSON() ([]byte, error) { + type noMethod AccountRef + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// AccountSummaries: An AccountSummary collection lists a summary of +// accounts, properties and views (profiles) to which the user has +// access. Each resource in the collection corresponds to a single +// AccountSummary. +type AccountSummaries struct { + // Items: A list of AccountSummaries. + Items []*AccountSummary `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this AccountSummary collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this AccountSummary + // collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *AccountSummaries) MarshalJSON() ([]byte, error) { + type noMethod AccountSummaries + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// AccountSummary: JSON template for an Analytics AccountSummary. An +// AccountSummary is a lightweight tree comprised of +// properties/profiles. +type AccountSummary struct { + // Id: Account ID. + Id string `json:"id,omitempty"` + + // Kind: Resource type for Analytics AccountSummary. + Kind string `json:"kind,omitempty"` + + // Name: Account name. + Name string `json:"name,omitempty"` + + // WebProperties: List of web properties under this account. + WebProperties []*WebPropertySummary `json:"webProperties,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Id") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *AccountSummary) MarshalJSON() ([]byte, error) { + type noMethod AccountSummary + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// AccountTicket: JSON template for an Analytics account ticket. The +// account ticket consists of the ticket ID and the basic information +// for the account, property and profile. +type AccountTicket struct { + // Account: Account for this ticket. + Account *Account `json:"account,omitempty"` + + // Id: Account ticket ID used to access the account ticket. + Id string `json:"id,omitempty"` + + // Kind: Resource type for account ticket. + Kind string `json:"kind,omitempty"` + + // Profile: View (Profile) for the account. + Profile *Profile `json:"profile,omitempty"` + + // RedirectUri: Redirect URI where the user will be sent after accepting + // Terms of Service. Must be configured in APIs console as a callback + // URL. + RedirectUri string `json:"redirectUri,omitempty"` + + // Webproperty: Web property for the account. + Webproperty *Webproperty `json:"webproperty,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Account") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *AccountTicket) MarshalJSON() ([]byte, error) { + type noMethod AccountTicket + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Accounts: An account collection provides a list of Analytics accounts +// to which a user has access. The account collection is the entry point +// to all management information. Each resource in the collection +// corresponds to a single Analytics account. +type Accounts struct { + // Items: A list of accounts. + Items []*Account `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of entries the response can contain, + // regardless of the actual number of entries returned. Its value ranges + // from 1 to 1000 with a value of 1000 by default, or otherwise + // specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Next link for this account collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Previous link for this account collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the entries, which is 1 by default + // or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Accounts) MarshalJSON() ([]byte, error) { + type noMethod Accounts + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// AdWordsAccount: JSON template for an AdWords account. +type AdWordsAccount struct { + // AutoTaggingEnabled: True if auto-tagging is enabled on the AdWords + // account. Read-only after the insert operation. + AutoTaggingEnabled bool `json:"autoTaggingEnabled,omitempty"` + + // CustomerId: Customer ID. This field is required when creating an + // AdWords link. + CustomerId string `json:"customerId,omitempty"` + + // Kind: Resource type for AdWords account. + Kind string `json:"kind,omitempty"` + + // ForceSendFields is a list of field names (e.g. "AutoTaggingEnabled") + // to unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *AdWordsAccount) MarshalJSON() ([]byte, error) { + type noMethod AdWordsAccount + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// AnalyticsDataimportDeleteUploadDataRequest: Request template for the +// delete upload data request. +type AnalyticsDataimportDeleteUploadDataRequest struct { + // CustomDataImportUids: A list of upload UIDs. + CustomDataImportUids []string `json:"customDataImportUids,omitempty"` + + // ForceSendFields is a list of field names (e.g. + // "CustomDataImportUids") to unconditionally include in API requests. + // By default, fields with empty values are omitted from API requests. + // However, any non-pointer, non-interface field appearing in + // ForceSendFields will be sent to the server regardless of whether the + // field is empty or not. This may be used to include empty fields in + // Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *AnalyticsDataimportDeleteUploadDataRequest) MarshalJSON() ([]byte, error) { + type noMethod AnalyticsDataimportDeleteUploadDataRequest + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Column: JSON template for a metadata column. +type Column struct { + // Attributes: Map of attribute name and value for this column. + Attributes map[string]string `json:"attributes,omitempty"` + + // Id: Column id. + Id string `json:"id,omitempty"` + + // Kind: Resource type for Analytics column. + Kind string `json:"kind,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Attributes") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Column) MarshalJSON() ([]byte, error) { + type noMethod Column + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Columns: Lists columns (dimensions and metrics) for a particular +// report type. +type Columns struct { + // AttributeNames: List of attributes names returned by columns. + AttributeNames []string `json:"attributeNames,omitempty"` + + // Etag: Etag of collection. This etag can be compared with the last + // response etag to check if response has changed. + Etag string `json:"etag,omitempty"` + + // Items: List of columns for a report type. + Items []*Column `json:"items,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // TotalResults: Total number of columns returned in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AttributeNames") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Columns) MarshalJSON() ([]byte, error) { + type noMethod Columns + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// CustomDataSource: JSON template for an Analytics custom data source. +type CustomDataSource struct { + // AccountId: Account ID to which this custom data source belongs. + AccountId string `json:"accountId,omitempty"` + + ChildLink *CustomDataSourceChildLink `json:"childLink,omitempty"` + + // Created: Time this custom data source was created. + Created string `json:"created,omitempty"` + + // Description: Description of custom data source. + Description string `json:"description,omitempty"` + + // Id: Custom data source ID. + Id string `json:"id,omitempty"` + + ImportBehavior string `json:"importBehavior,omitempty"` + + // Kind: Resource type for Analytics custom data source. + Kind string `json:"kind,omitempty"` + + // Name: Name of this custom data source. + Name string `json:"name,omitempty"` + + // ParentLink: Parent link for this custom data source. Points to the + // web property to which this custom data source belongs. + ParentLink *CustomDataSourceParentLink `json:"parentLink,omitempty"` + + // ProfilesLinked: IDs of views (profiles) linked to the custom data + // source. + ProfilesLinked []string `json:"profilesLinked,omitempty"` + + // SelfLink: Link for this Analytics custom data source. + SelfLink string `json:"selfLink,omitempty"` + + // Type: Type of the custom data source. + Type string `json:"type,omitempty"` + + // Updated: Time this custom data source was last modified. + Updated string `json:"updated,omitempty"` + + UploadType string `json:"uploadType,omitempty"` + + // WebPropertyId: Web property ID of the form UA-XXXXX-YY to which this + // custom data source belongs. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *CustomDataSource) MarshalJSON() ([]byte, error) { + type noMethod CustomDataSource + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type CustomDataSourceChildLink struct { + // Href: Link to the list of daily uploads for this custom data source. + // Link to the list of uploads for this custom data source. + Href string `json:"href,omitempty"` + + // Type: Value is "analytics#dailyUploads". Value is + // "analytics#uploads". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *CustomDataSourceChildLink) MarshalJSON() ([]byte, error) { + type noMethod CustomDataSourceChildLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// CustomDataSourceParentLink: Parent link for this custom data source. +// Points to the web property to which this custom data source belongs. +type CustomDataSourceParentLink struct { + // Href: Link to the web property to which this custom data source + // belongs. + Href string `json:"href,omitempty"` + + // Type: Value is "analytics#webproperty". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *CustomDataSourceParentLink) MarshalJSON() ([]byte, error) { + type noMethod CustomDataSourceParentLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// CustomDataSources: Lists Analytics custom data sources to which the +// user has access. Each resource in the collection corresponds to a +// single Analytics custom data source. +type CustomDataSources struct { + // Items: Collection of custom data sources. + Items []*CustomDataSource `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this custom data source collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this custom data source + // collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *CustomDataSources) MarshalJSON() ([]byte, error) { + type noMethod CustomDataSources + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// CustomDimension: JSON template for Analytics Custom Dimension. +type CustomDimension struct { + // AccountId: Account ID. + AccountId string `json:"accountId,omitempty"` + + // Active: Boolean indicating whether the custom dimension is active. + Active bool `json:"active,omitempty"` + + // Created: Time the custom dimension was created. + Created string `json:"created,omitempty"` + + // Id: Custom dimension ID. + Id string `json:"id,omitempty"` + + // Index: Index of the custom dimension. + Index int64 `json:"index,omitempty"` + + // Kind: Kind value for a custom dimension. Set to + // "analytics#customDimension". It is a read-only field. + Kind string `json:"kind,omitempty"` + + // Name: Name of the custom dimension. + Name string `json:"name,omitempty"` + + // ParentLink: Parent link for the custom dimension. Points to the + // property to which the custom dimension belongs. + ParentLink *CustomDimensionParentLink `json:"parentLink,omitempty"` + + // Scope: Scope of the custom dimension: HIT, SESSION, USER or PRODUCT. + Scope string `json:"scope,omitempty"` + + // SelfLink: Link for the custom dimension + SelfLink string `json:"selfLink,omitempty"` + + // Updated: Time the custom dimension was last modified. + Updated string `json:"updated,omitempty"` + + // WebPropertyId: Property ID. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *CustomDimension) MarshalJSON() ([]byte, error) { + type noMethod CustomDimension + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// CustomDimensionParentLink: Parent link for the custom dimension. +// Points to the property to which the custom dimension belongs. +type CustomDimensionParentLink struct { + // Href: Link to the property to which the custom dimension belongs. + Href string `json:"href,omitempty"` + + // Type: Type of the parent link. Set to "analytics#webproperty". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *CustomDimensionParentLink) MarshalJSON() ([]byte, error) { + type noMethod CustomDimensionParentLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// CustomDimensions: A custom dimension collection lists Analytics +// custom dimensions to which the user has access. Each resource in the +// collection corresponds to a single Analytics custom dimension. +type CustomDimensions struct { + // Items: Collection of custom dimensions. + Items []*CustomDimension `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this custom dimension collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this custom dimension + // collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *CustomDimensions) MarshalJSON() ([]byte, error) { + type noMethod CustomDimensions + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// CustomMetric: JSON template for Analytics Custom Metric. +type CustomMetric struct { + // AccountId: Account ID. + AccountId string `json:"accountId,omitempty"` + + // Active: Boolean indicating whether the custom metric is active. + Active bool `json:"active,omitempty"` + + // Created: Time the custom metric was created. + Created string `json:"created,omitempty"` + + // Id: Custom metric ID. + Id string `json:"id,omitempty"` + + // Index: Index of the custom metric. + Index int64 `json:"index,omitempty"` + + // Kind: Kind value for a custom metric. Set to + // "analytics#customMetric". It is a read-only field. + Kind string `json:"kind,omitempty"` + + // MaxValue: Max value of custom metric. + MaxValue string `json:"max_value,omitempty"` + + // MinValue: Min value of custom metric. + MinValue string `json:"min_value,omitempty"` + + // Name: Name of the custom metric. + Name string `json:"name,omitempty"` + + // ParentLink: Parent link for the custom metric. Points to the property + // to which the custom metric belongs. + ParentLink *CustomMetricParentLink `json:"parentLink,omitempty"` + + // Scope: Scope of the custom metric: HIT or PRODUCT. + Scope string `json:"scope,omitempty"` + + // SelfLink: Link for the custom metric + SelfLink string `json:"selfLink,omitempty"` + + // Type: Data type of custom metric. + Type string `json:"type,omitempty"` + + // Updated: Time the custom metric was last modified. + Updated string `json:"updated,omitempty"` + + // WebPropertyId: Property ID. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *CustomMetric) MarshalJSON() ([]byte, error) { + type noMethod CustomMetric + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// CustomMetricParentLink: Parent link for the custom metric. Points to +// the property to which the custom metric belongs. +type CustomMetricParentLink struct { + // Href: Link to the property to which the custom metric belongs. + Href string `json:"href,omitempty"` + + // Type: Type of the parent link. Set to "analytics#webproperty". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *CustomMetricParentLink) MarshalJSON() ([]byte, error) { + type noMethod CustomMetricParentLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// CustomMetrics: A custom metric collection lists Analytics custom +// metrics to which the user has access. Each resource in the collection +// corresponds to a single Analytics custom metric. +type CustomMetrics struct { + // Items: Collection of custom metrics. + Items []*CustomMetric `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this custom metric collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this custom metric + // collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *CustomMetrics) MarshalJSON() ([]byte, error) { + type noMethod CustomMetrics + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// EntityAdWordsLink: JSON template for Analytics Entity AdWords Link. +type EntityAdWordsLink struct { + // AdWordsAccounts: A list of AdWords client accounts. These cannot be + // MCC accounts. This field is required when creating an AdWords link. + // It cannot be empty. + AdWordsAccounts []*AdWordsAccount `json:"adWordsAccounts,omitempty"` + + // Entity: Web property being linked. + Entity *EntityAdWordsLinkEntity `json:"entity,omitempty"` + + // Id: Entity AdWords link ID + Id string `json:"id,omitempty"` + + // Kind: Resource type for entity AdWords link. + Kind string `json:"kind,omitempty"` + + // Name: Name of the link. This field is required when creating an + // AdWords link. + Name string `json:"name,omitempty"` + + // ProfileIds: IDs of linked Views (Profiles) represented as strings. + ProfileIds []string `json:"profileIds,omitempty"` + + // SelfLink: URL link for this Google Analytics - Google AdWords link. + SelfLink string `json:"selfLink,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AdWordsAccounts") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *EntityAdWordsLink) MarshalJSON() ([]byte, error) { + type noMethod EntityAdWordsLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// EntityAdWordsLinkEntity: Web property being linked. +type EntityAdWordsLinkEntity struct { + WebPropertyRef *WebPropertyRef `json:"webPropertyRef,omitempty"` + + // ForceSendFields is a list of field names (e.g. "WebPropertyRef") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *EntityAdWordsLinkEntity) MarshalJSON() ([]byte, error) { + type noMethod EntityAdWordsLinkEntity + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// EntityAdWordsLinks: An entity AdWords link collection provides a list +// of GA-AdWords links Each resource in this collection corresponds to a +// single link. +type EntityAdWordsLinks struct { + // Items: A list of entity AdWords links. + Items []*EntityAdWordsLink `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of entries the response can contain, + // regardless of the actual number of entries returned. Its value ranges + // from 1 to 1000 with a value of 1000 by default, or otherwise + // specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Next link for this AdWords link collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Previous link for this AdWords link collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the entries, which is 1 by default + // or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *EntityAdWordsLinks) MarshalJSON() ([]byte, error) { + type noMethod EntityAdWordsLinks + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// EntityUserLink: JSON template for an Analytics Entity-User Link. +// Returns permissions that a user has for an entity. +type EntityUserLink struct { + // Entity: Entity for this link. It can be an account, a web property, + // or a view (profile). + Entity *EntityUserLinkEntity `json:"entity,omitempty"` + + // Id: Entity user link ID + Id string `json:"id,omitempty"` + + // Kind: Resource type for entity user link. + Kind string `json:"kind,omitempty"` + + // Permissions: Permissions the user has for this entity. + Permissions *EntityUserLinkPermissions `json:"permissions,omitempty"` + + // SelfLink: Self link for this resource. + SelfLink string `json:"selfLink,omitempty"` + + // UserRef: User reference. + UserRef *UserRef `json:"userRef,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Entity") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *EntityUserLink) MarshalJSON() ([]byte, error) { + type noMethod EntityUserLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// EntityUserLinkEntity: Entity for this link. It can be an account, a +// web property, or a view (profile). +type EntityUserLinkEntity struct { + // AccountRef: Account for this link. + AccountRef *AccountRef `json:"accountRef,omitempty"` + + // ProfileRef: View (Profile) for this link. + ProfileRef *ProfileRef `json:"profileRef,omitempty"` + + // WebPropertyRef: Web property for this link. + WebPropertyRef *WebPropertyRef `json:"webPropertyRef,omitempty"` + + // ForceSendFields is a list of field names (e.g. "AccountRef") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *EntityUserLinkEntity) MarshalJSON() ([]byte, error) { + type noMethod EntityUserLinkEntity + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// EntityUserLinkPermissions: Permissions the user has for this entity. +type EntityUserLinkPermissions struct { + // Effective: Effective permissions represent all the permissions that a + // user has for this entity. These include any implied permissions + // (e.g., EDIT implies VIEW) or inherited permissions from the parent + // entity. Effective permissions are read-only. + Effective []string `json:"effective,omitempty"` + + // Local: Permissions that a user has been assigned at this very level. + // Does not include any implied or inherited permissions. Local + // permissions are modifiable. + Local []string `json:"local,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Effective") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *EntityUserLinkPermissions) MarshalJSON() ([]byte, error) { + type noMethod EntityUserLinkPermissions + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// EntityUserLinks: An entity user link collection provides a list of +// Analytics ACL links Each resource in this collection corresponds to a +// single link. +type EntityUserLinks struct { + // Items: A list of entity user links. + Items []*EntityUserLink `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of entries the response can contain, + // regardless of the actual number of entries returned. Its value ranges + // from 1 to 1000 with a value of 1000 by default, or otherwise + // specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Next link for this account collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Previous link for this account collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the entries, which is 1 by default + // or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *EntityUserLinks) MarshalJSON() ([]byte, error) { + type noMethod EntityUserLinks + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Experiment: JSON template for Analytics experiment resource. +type Experiment struct { + // AccountId: Account ID to which this experiment belongs. This field is + // read-only. + AccountId string `json:"accountId,omitempty"` + + // Created: Time the experiment was created. This field is read-only. + Created string `json:"created,omitempty"` + + // Description: Notes about this experiment. + Description string `json:"description,omitempty"` + + // EditableInGaUi: If true, the end user will be able to edit the + // experiment via the Google Analytics user interface. + EditableInGaUi bool `json:"editableInGaUi,omitempty"` + + // EndTime: The ending time of the experiment (the time the status + // changed from RUNNING to ENDED). This field is present only if the + // experiment has ended. This field is read-only. + EndTime string `json:"endTime,omitempty"` + + // EqualWeighting: Boolean specifying whether to distribute traffic + // evenly across all variations. If the value is False, content + // experiments follows the default behavior of adjusting traffic + // dynamically based on variation performance. Optional -- defaults to + // False. This field may not be changed for an experiment whose status + // is ENDED. + EqualWeighting bool `json:"equalWeighting,omitempty"` + + // Id: Experiment ID. Required for patch and update. Disallowed for + // create. + Id string `json:"id,omitempty"` + + // InternalWebPropertyId: Internal ID for the web property to which this + // experiment belongs. This field is read-only. + InternalWebPropertyId string `json:"internalWebPropertyId,omitempty"` + + // Kind: Resource type for an Analytics experiment. This field is + // read-only. + Kind string `json:"kind,omitempty"` + + // MinimumExperimentLengthInDays: An integer number in [3, 90]. + // Specifies the minimum length of the experiment. Can be changed for a + // running experiment. This field may not be changed for an experiments + // whose status is ENDED. + MinimumExperimentLengthInDays int64 `json:"minimumExperimentLengthInDays,omitempty"` + + // Name: Experiment name. This field may not be changed for an + // experiment whose status is ENDED. This field is required when + // creating an experiment. + Name string `json:"name,omitempty"` + + // ObjectiveMetric: The metric that the experiment is optimizing. Valid + // values: "ga:goal(n)Completions", "ga:adsenseAdsClicks", + // "ga:adsenseAdsViewed", "ga:adsenseRevenue", "ga:bounces", + // "ga:pageviews", "ga:sessionDuration", "ga:transactions", + // "ga:transactionRevenue". This field is required if status is + // "RUNNING" and servingFramework is one of "REDIRECT" or "API". + ObjectiveMetric string `json:"objectiveMetric,omitempty"` + + // OptimizationType: Whether the objectiveMetric should be minimized or + // maximized. Possible values: "MAXIMUM", "MINIMUM". Optional--defaults + // to "MAXIMUM". Cannot be specified without objectiveMetric. Cannot be + // modified when status is "RUNNING" or "ENDED". + OptimizationType string `json:"optimizationType,omitempty"` + + // ParentLink: Parent link for an experiment. Points to the view + // (profile) to which this experiment belongs. + ParentLink *ExperimentParentLink `json:"parentLink,omitempty"` + + // ProfileId: View (Profile) ID to which this experiment belongs. This + // field is read-only. + ProfileId string `json:"profileId,omitempty"` + + // ReasonExperimentEnded: Why the experiment ended. Possible values: + // "STOPPED_BY_USER", "WINNER_FOUND", "EXPERIMENT_EXPIRED", + // "ENDED_WITH_NO_WINNER", "GOAL_OBJECTIVE_CHANGED". + // "ENDED_WITH_NO_WINNER" means that the experiment didn't expire but no + // winner was projected to be found. If the experiment status is changed + // via the API to ENDED this field is set to STOPPED_BY_USER. This field + // is read-only. + ReasonExperimentEnded string `json:"reasonExperimentEnded,omitempty"` + + // RewriteVariationUrlsAsOriginal: Boolean specifying whether variations + // URLS are rewritten to match those of the original. This field may not + // be changed for an experiments whose status is ENDED. + RewriteVariationUrlsAsOriginal bool `json:"rewriteVariationUrlsAsOriginal,omitempty"` + + // SelfLink: Link for this experiment. This field is read-only. + SelfLink string `json:"selfLink,omitempty"` + + // ServingFramework: The framework used to serve the experiment + // variations and evaluate the results. One of: + // - REDIRECT: Google Analytics redirects traffic to different variation + // pages, reports the chosen variation and evaluates the results. + // - API: Google Analytics chooses and reports the variation to serve + // and evaluates the results; the caller is responsible for serving the + // selected variation. + // - EXTERNAL: The variations will be served externally and the chosen + // variation reported to Google Analytics. The caller is responsible for + // serving the selected variation and evaluating the results. + ServingFramework string `json:"servingFramework,omitempty"` + + // Snippet: The snippet of code to include on the control page(s). This + // field is read-only. + Snippet string `json:"snippet,omitempty"` + + // StartTime: The starting time of the experiment (the time the status + // changed from READY_TO_RUN to RUNNING). This field is present only if + // the experiment has started. This field is read-only. + StartTime string `json:"startTime,omitempty"` + + // Status: Experiment status. Possible values: "DRAFT", "READY_TO_RUN", + // "RUNNING", "ENDED". Experiments can be created in the "DRAFT", + // "READY_TO_RUN" or "RUNNING" state. This field is required when + // creating an experiment. + Status string `json:"status,omitempty"` + + // TrafficCoverage: A floating-point number in (0, 1]. Specifies the + // fraction of the traffic that participates in the experiment. Can be + // changed for a running experiment. This field may not be changed for + // an experiments whose status is ENDED. + TrafficCoverage float64 `json:"trafficCoverage,omitempty"` + + // Updated: Time the experiment was last modified. This field is + // read-only. + Updated string `json:"updated,omitempty"` + + // Variations: Array of variations. The first variation in the array is + // the original. The number of variations may not change once an + // experiment is in the RUNNING state. At least two variations are + // required before status can be set to RUNNING. + Variations []*ExperimentVariations `json:"variations,omitempty"` + + // WebPropertyId: Web property ID to which this experiment belongs. The + // web property ID is of the form UA-XXXXX-YY. This field is read-only. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // WinnerConfidenceLevel: A floating-point number in (0, 1). Specifies + // the necessary confidence level to choose a winner. This field may not + // be changed for an experiments whose status is ENDED. + WinnerConfidenceLevel float64 `json:"winnerConfidenceLevel,omitempty"` + + // WinnerFound: Boolean specifying whether a winner has been found for + // this experiment. This field is read-only. + WinnerFound bool `json:"winnerFound,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Experiment) MarshalJSON() ([]byte, error) { + type noMethod Experiment + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// ExperimentParentLink: Parent link for an experiment. Points to the +// view (profile) to which this experiment belongs. +type ExperimentParentLink struct { + // Href: Link to the view (profile) to which this experiment belongs. + // This field is read-only. + Href string `json:"href,omitempty"` + + // Type: Value is "analytics#profile". This field is read-only. + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *ExperimentParentLink) MarshalJSON() ([]byte, error) { + type noMethod ExperimentParentLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type ExperimentVariations struct { + // Name: The name of the variation. This field is required when creating + // an experiment. This field may not be changed for an experiment whose + // status is ENDED. + Name string `json:"name,omitempty"` + + // Status: Status of the variation. Possible values: "ACTIVE", + // "INACTIVE". INACTIVE variations are not served. This field may not be + // changed for an experiment whose status is ENDED. + Status string `json:"status,omitempty"` + + // Url: The URL of the variation. This field may not be changed for an + // experiment whose status is RUNNING or ENDED. + Url string `json:"url,omitempty"` + + // Weight: Weight that this variation should receive. Only present if + // the experiment is running. This field is read-only. + Weight float64 `json:"weight,omitempty"` + + // Won: True if the experiment has ended and this variation performed + // (statistically) significantly better than the original. This field is + // read-only. + Won bool `json:"won,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Name") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *ExperimentVariations) MarshalJSON() ([]byte, error) { + type noMethod ExperimentVariations + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Experiments: An experiment collection lists Analytics experiments to +// which the user has access. Each view (profile) can have a set of +// experiments. Each resource in the Experiment collection corresponds +// to a single Analytics experiment. +type Experiments struct { + // Items: A list of experiments. + Items []*Experiment `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this experiment collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this experiment collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of resources in the result. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Experiments) MarshalJSON() ([]byte, error) { + type noMethod Experiments + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Filter: JSON template for an Analytics account filter. +type Filter struct { + // AccountId: Account ID to which this filter belongs. + AccountId string `json:"accountId,omitempty"` + + // AdvancedDetails: Details for the filter of the type ADVANCED. + AdvancedDetails *FilterAdvancedDetails `json:"advancedDetails,omitempty"` + + // Created: Time this filter was created. + Created string `json:"created,omitempty"` + + // ExcludeDetails: Details for the filter of the type EXCLUDE. + ExcludeDetails *FilterExpression `json:"excludeDetails,omitempty"` + + // Id: Filter ID. + Id string `json:"id,omitempty"` + + // IncludeDetails: Details for the filter of the type INCLUDE. + IncludeDetails *FilterExpression `json:"includeDetails,omitempty"` + + // Kind: Resource type for Analytics filter. + Kind string `json:"kind,omitempty"` + + // LowercaseDetails: Details for the filter of the type LOWER. + LowercaseDetails *FilterLowercaseDetails `json:"lowercaseDetails,omitempty"` + + // Name: Name of this filter. + Name string `json:"name,omitempty"` + + // ParentLink: Parent link for this filter. Points to the account to + // which this filter belongs. + ParentLink *FilterParentLink `json:"parentLink,omitempty"` + + // SearchAndReplaceDetails: Details for the filter of the type + // SEARCH_AND_REPLACE. + SearchAndReplaceDetails *FilterSearchAndReplaceDetails `json:"searchAndReplaceDetails,omitempty"` + + // SelfLink: Link for this filter. + SelfLink string `json:"selfLink,omitempty"` + + // Type: Type of this filter. Possible values are INCLUDE, EXCLUDE, + // LOWERCASE, UPPERCASE, SEARCH_AND_REPLACE and ADVANCED. + Type string `json:"type,omitempty"` + + // Updated: Time this filter was last modified. + Updated string `json:"updated,omitempty"` + + // UppercaseDetails: Details for the filter of the type UPPER. + UppercaseDetails *FilterUppercaseDetails `json:"uppercaseDetails,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Filter) MarshalJSON() ([]byte, error) { + type noMethod Filter + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// FilterAdvancedDetails: Details for the filter of the type ADVANCED. +type FilterAdvancedDetails struct { + // CaseSensitive: Indicates if the filter expressions are case + // sensitive. + CaseSensitive bool `json:"caseSensitive,omitempty"` + + // ExtractA: Expression to extract from field A. + ExtractA string `json:"extractA,omitempty"` + + // ExtractB: Expression to extract from field B. + ExtractB string `json:"extractB,omitempty"` + + // FieldA: Field A. + FieldA string `json:"fieldA,omitempty"` + + // FieldAIndex: The Index of the custom dimension. Required if field is + // a CUSTOM_DIMENSION. + FieldAIndex int64 `json:"fieldAIndex,omitempty"` + + // FieldARequired: Indicates if field A is required to match. + FieldARequired bool `json:"fieldARequired,omitempty"` + + // FieldB: Field B. + FieldB string `json:"fieldB,omitempty"` + + // FieldBIndex: The Index of the custom dimension. Required if field is + // a CUSTOM_DIMENSION. + FieldBIndex int64 `json:"fieldBIndex,omitempty"` + + // FieldBRequired: Indicates if field B is required to match. + FieldBRequired bool `json:"fieldBRequired,omitempty"` + + // OutputConstructor: Expression used to construct the output value. + OutputConstructor string `json:"outputConstructor,omitempty"` + + // OutputToField: Output field. + OutputToField string `json:"outputToField,omitempty"` + + // OutputToFieldIndex: The Index of the custom dimension. Required if + // field is a CUSTOM_DIMENSION. + OutputToFieldIndex int64 `json:"outputToFieldIndex,omitempty"` + + // OverrideOutputField: Indicates if the existing value of the output + // field, if any, should be overridden by the output expression. + OverrideOutputField bool `json:"overrideOutputField,omitempty"` + + // ForceSendFields is a list of field names (e.g. "CaseSensitive") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *FilterAdvancedDetails) MarshalJSON() ([]byte, error) { + type noMethod FilterAdvancedDetails + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// FilterLowercaseDetails: Details for the filter of the type LOWER. +type FilterLowercaseDetails struct { + // Field: Field to use in the filter. + Field string `json:"field,omitempty"` + + // FieldIndex: The Index of the custom dimension. Required if field is a + // CUSTOM_DIMENSION. + FieldIndex int64 `json:"fieldIndex,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Field") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *FilterLowercaseDetails) MarshalJSON() ([]byte, error) { + type noMethod FilterLowercaseDetails + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// FilterParentLink: Parent link for this filter. Points to the account +// to which this filter belongs. +type FilterParentLink struct { + // Href: Link to the account to which this filter belongs. + Href string `json:"href,omitempty"` + + // Type: Value is "analytics#account". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *FilterParentLink) MarshalJSON() ([]byte, error) { + type noMethod FilterParentLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// FilterSearchAndReplaceDetails: Details for the filter of the type +// SEARCH_AND_REPLACE. +type FilterSearchAndReplaceDetails struct { + // CaseSensitive: Determines if the filter is case sensitive. + CaseSensitive bool `json:"caseSensitive,omitempty"` + + // Field: Field to use in the filter. + Field string `json:"field,omitempty"` + + // FieldIndex: The Index of the custom dimension. Required if field is a + // CUSTOM_DIMENSION. + FieldIndex int64 `json:"fieldIndex,omitempty"` + + // ReplaceString: Term to replace the search term with. + ReplaceString string `json:"replaceString,omitempty"` + + // SearchString: Term to search. + SearchString string `json:"searchString,omitempty"` + + // ForceSendFields is a list of field names (e.g. "CaseSensitive") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *FilterSearchAndReplaceDetails) MarshalJSON() ([]byte, error) { + type noMethod FilterSearchAndReplaceDetails + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// FilterUppercaseDetails: Details for the filter of the type UPPER. +type FilterUppercaseDetails struct { + // Field: Field to use in the filter. + Field string `json:"field,omitempty"` + + // FieldIndex: The Index of the custom dimension. Required if field is a + // CUSTOM_DIMENSION. + FieldIndex int64 `json:"fieldIndex,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Field") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *FilterUppercaseDetails) MarshalJSON() ([]byte, error) { + type noMethod FilterUppercaseDetails + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// FilterExpression: JSON template for an Analytics filter expression. +type FilterExpression struct { + // CaseSensitive: Determines if the filter is case sensitive. + CaseSensitive bool `json:"caseSensitive,omitempty"` + + // ExpressionValue: Filter expression value + ExpressionValue string `json:"expressionValue,omitempty"` + + // Field: Field to filter. Possible values: + // - Content and Traffic + // - PAGE_REQUEST_URI, + // - PAGE_HOSTNAME, + // - PAGE_TITLE, + // - REFERRAL, + // - COST_DATA_URI (Campaign target URL), + // - HIT_TYPE, + // - INTERNAL_SEARCH_TERM, + // - INTERNAL_SEARCH_TYPE, + // - SOURCE_PROPERTY_TRACKING_ID, + // - Campaign or AdGroup + // - CAMPAIGN_SOURCE, + // - CAMPAIGN_MEDIUM, + // - CAMPAIGN_NAME, + // - CAMPAIGN_AD_GROUP, + // - CAMPAIGN_TERM, + // - CAMPAIGN_CONTENT, + // - CAMPAIGN_CODE, + // - CAMPAIGN_REFERRAL_PATH, + // - E-Commerce + // - TRANSACTION_COUNTRY, + // - TRANSACTION_REGION, + // - TRANSACTION_CITY, + // - TRANSACTION_AFFILIATION (Store or order location), + // - ITEM_NAME, + // - ITEM_CODE, + // - ITEM_VARIATION, + // - TRANSACTION_ID, + // - TRANSACTION_CURRENCY_CODE, + // - PRODUCT_ACTION_TYPE, + // - Audience/Users + // - BROWSER, + // - BROWSER_VERSION, + // - BROWSER_SIZE, + // - PLATFORM, + // - PLATFORM_VERSION, + // - LANGUAGE, + // - SCREEN_RESOLUTION, + // - SCREEN_COLORS, + // - JAVA_ENABLED (Boolean Field), + // - FLASH_VERSION, + // - GEO_SPEED (Connection speed), + // - VISITOR_TYPE, + // - GEO_ORGANIZATION (ISP organization), + // - GEO_DOMAIN, + // - GEO_IP_ADDRESS, + // - GEO_IP_VERSION, + // - Location + // - GEO_COUNTRY, + // - GEO_REGION, + // - GEO_CITY, + // - Event + // - EVENT_CATEGORY, + // - EVENT_ACTION, + // - EVENT_LABEL, + // - Other + // - CUSTOM_FIELD_1, + // - CUSTOM_FIELD_2, + // - USER_DEFINED_VALUE, + // - Application + // - APP_ID, + // - APP_INSTALLER_ID, + // - APP_NAME, + // - APP_VERSION, + // - SCREEN, + // - IS_APP (Boolean Field), + // - IS_FATAL_EXCEPTION (Boolean Field), + // - EXCEPTION_DESCRIPTION, + // - Mobile device + // - IS_MOBILE (Boolean Field, Deprecated. Use DEVICE_CATEGORY=mobile), + // + // - IS_TABLET (Boolean Field, Deprecated. Use DEVICE_CATEGORY=tablet), + // + // - DEVICE_CATEGORY, + // - MOBILE_HAS_QWERTY_KEYBOARD (Boolean Field), + // - MOBILE_HAS_NFC_SUPPORT (Boolean Field), + // - MOBILE_HAS_CELLULAR_RADIO (Boolean Field), + // - MOBILE_HAS_WIFI_SUPPORT (Boolean Field), + // - MOBILE_BRAND_NAME, + // - MOBILE_MODEL_NAME, + // - MOBILE_MARKETING_NAME, + // - MOBILE_POINTING_METHOD, + // - Social + // - SOCIAL_NETWORK, + // - SOCIAL_ACTION, + // - SOCIAL_ACTION_TARGET, + // - Custom dimension + // - CUSTOM_DIMENSION (See accompanying field index), + Field string `json:"field,omitempty"` + + // FieldIndex: The Index of the custom dimension. Set only if the field + // is a is CUSTOM_DIMENSION. + FieldIndex int64 `json:"fieldIndex,omitempty"` + + // Kind: Kind value for filter expression + Kind string `json:"kind,omitempty"` + + // MatchType: Match type for this filter. Possible values are + // BEGINS_WITH, EQUAL, ENDS_WITH, CONTAINS, or MATCHES. GEO_DOMAIN, + // GEO_IP_ADDRESS, PAGE_REQUEST_URI, or PAGE_HOSTNAME filters can use + // any match type; all other filters must use MATCHES. + MatchType string `json:"matchType,omitempty"` + + // ForceSendFields is a list of field names (e.g. "CaseSensitive") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *FilterExpression) MarshalJSON() ([]byte, error) { + type noMethod FilterExpression + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// FilterRef: JSON template for a profile filter link. +type FilterRef struct { + // AccountId: Account ID to which this filter belongs. + AccountId string `json:"accountId,omitempty"` + + // Href: Link for this filter. + Href string `json:"href,omitempty"` + + // Id: Filter ID. + Id string `json:"id,omitempty"` + + // Kind: Kind value for filter reference. + Kind string `json:"kind,omitempty"` + + // Name: Name of this filter. + Name string `json:"name,omitempty"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *FilterRef) MarshalJSON() ([]byte, error) { + type noMethod FilterRef + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Filters: A filter collection lists filters created by users in an +// Analytics account. Each resource in the collection corresponds to a +// filter. +type Filters struct { + // Items: A list of filters. + Items []*Filter `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1,000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this filter collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this filter collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Filters) MarshalJSON() ([]byte, error) { + type noMethod Filters + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// GaData: Analytics data for a given view (profile). +type GaData struct { + // ColumnHeaders: Column headers that list dimension names followed by + // the metric names. The order of dimensions and metrics is same as + // specified in the request. + ColumnHeaders []*GaDataColumnHeaders `json:"columnHeaders,omitempty"` + + // ContainsSampledData: Determines if Analytics data contains samples. + ContainsSampledData bool `json:"containsSampledData,omitempty"` + + DataTable *GaDataDataTable `json:"dataTable,omitempty"` + + // Id: Unique ID for this data response. + Id string `json:"id,omitempty"` + + // ItemsPerPage: The maximum number of rows the response can contain, + // regardless of the actual number of rows returned. Its value ranges + // from 1 to 10,000 with a value of 1000 by default, or otherwise + // specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Resource type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this Analytics data query. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this Analytics data query. + PreviousLink string `json:"previousLink,omitempty"` + + // ProfileInfo: Information for the view (profile), for which the + // Analytics data was requested. + ProfileInfo *GaDataProfileInfo `json:"profileInfo,omitempty"` + + // Query: Analytics data request query parameters. + Query *GaDataQuery `json:"query,omitempty"` + + // Rows: Analytics data rows, where each row contains a list of + // dimension values followed by the metric values. The order of + // dimensions and metrics is same as specified in the request. + Rows [][]string `json:"rows,omitempty"` + + // SampleSize: The number of samples used to calculate the result. + SampleSize int64 `json:"sampleSize,omitempty,string"` + + // SampleSpace: Total size of the sample space from which the samples + // were selected. + SampleSpace int64 `json:"sampleSpace,omitempty,string"` + + // SelfLink: Link to this page. + SelfLink string `json:"selfLink,omitempty"` + + // TotalResults: The total number of rows for the query, regardless of + // the number of rows in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // TotalsForAllResults: Total values for the requested metrics over all + // the results, not just the results returned in this response. The + // order of the metric totals is same as the metric order specified in + // the request. + TotalsForAllResults map[string]string `json:"totalsForAllResults,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "ColumnHeaders") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GaData) MarshalJSON() ([]byte, error) { + type noMethod GaData + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type GaDataColumnHeaders struct { + // ColumnType: Column Type. Either DIMENSION or METRIC. + ColumnType string `json:"columnType,omitempty"` + + // DataType: Data type. Dimension column headers have only STRING as the + // data type. Metric column headers have data types for metric values + // such as INTEGER, DOUBLE, CURRENCY etc. + DataType string `json:"dataType,omitempty"` + + // Name: Column name. + Name string `json:"name,omitempty"` + + // ForceSendFields is a list of field names (e.g. "ColumnType") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GaDataColumnHeaders) MarshalJSON() ([]byte, error) { + type noMethod GaDataColumnHeaders + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type GaDataDataTable struct { + Cols []*GaDataDataTableCols `json:"cols,omitempty"` + + Rows []*GaDataDataTableRows `json:"rows,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Cols") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GaDataDataTable) MarshalJSON() ([]byte, error) { + type noMethod GaDataDataTable + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type GaDataDataTableCols struct { + Id string `json:"id,omitempty"` + + Label string `json:"label,omitempty"` + + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Id") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GaDataDataTableCols) MarshalJSON() ([]byte, error) { + type noMethod GaDataDataTableCols + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type GaDataDataTableRows struct { + C []*GaDataDataTableRowsC `json:"c,omitempty"` + + // ForceSendFields is a list of field names (e.g. "C") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GaDataDataTableRows) MarshalJSON() ([]byte, error) { + type noMethod GaDataDataTableRows + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type GaDataDataTableRowsC struct { + V string `json:"v,omitempty"` + + // ForceSendFields is a list of field names (e.g. "V") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GaDataDataTableRowsC) MarshalJSON() ([]byte, error) { + type noMethod GaDataDataTableRowsC + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// GaDataProfileInfo: Information for the view (profile), for which the +// Analytics data was requested. +type GaDataProfileInfo struct { + // AccountId: Account ID to which this view (profile) belongs. + AccountId string `json:"accountId,omitempty"` + + // InternalWebPropertyId: Internal ID for the web property to which this + // view (profile) belongs. + InternalWebPropertyId string `json:"internalWebPropertyId,omitempty"` + + // ProfileId: View (Profile) ID. + ProfileId string `json:"profileId,omitempty"` + + // ProfileName: View (Profile) name. + ProfileName string `json:"profileName,omitempty"` + + // TableId: Table ID for view (profile). + TableId string `json:"tableId,omitempty"` + + // WebPropertyId: Web Property ID to which this view (profile) belongs. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GaDataProfileInfo) MarshalJSON() ([]byte, error) { + type noMethod GaDataProfileInfo + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// GaDataQuery: Analytics data request query parameters. +type GaDataQuery struct { + // Dimensions: List of analytics dimensions. + Dimensions string `json:"dimensions,omitempty"` + + // EndDate: End date. + EndDate string `json:"end-date,omitempty"` + + // Filters: Comma-separated list of dimension or metric filters. + Filters string `json:"filters,omitempty"` + + // Ids: Unique table ID. + Ids string `json:"ids,omitempty"` + + // MaxResults: Maximum results per page. + MaxResults int64 `json:"max-results,omitempty"` + + // Metrics: List of analytics metrics. + Metrics []string `json:"metrics,omitempty"` + + // SamplingLevel: Desired sampling level + SamplingLevel string `json:"samplingLevel,omitempty"` + + // Segment: Analytics advanced segment. + Segment string `json:"segment,omitempty"` + + // Sort: List of dimensions or metrics based on which Analytics data is + // sorted. + Sort []string `json:"sort,omitempty"` + + // StartDate: Start date. + StartDate string `json:"start-date,omitempty"` + + // StartIndex: Start index. + StartIndex int64 `json:"start-index,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Dimensions") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GaDataQuery) MarshalJSON() ([]byte, error) { + type noMethod GaDataQuery + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Goal: JSON template for Analytics goal resource. +type Goal struct { + // AccountId: Account ID to which this goal belongs. + AccountId string `json:"accountId,omitempty"` + + // Active: Determines whether this goal is active. + Active bool `json:"active,omitempty"` + + // Created: Time this goal was created. + Created string `json:"created,omitempty"` + + // EventDetails: Details for the goal of the type EVENT. + EventDetails *GoalEventDetails `json:"eventDetails,omitempty"` + + // Id: Goal ID. + Id string `json:"id,omitempty"` + + // InternalWebPropertyId: Internal ID for the web property to which this + // goal belongs. + InternalWebPropertyId string `json:"internalWebPropertyId,omitempty"` + + // Kind: Resource type for an Analytics goal. + Kind string `json:"kind,omitempty"` + + // Name: Goal name. + Name string `json:"name,omitempty"` + + // ParentLink: Parent link for a goal. Points to the view (profile) to + // which this goal belongs. + ParentLink *GoalParentLink `json:"parentLink,omitempty"` + + // ProfileId: View (Profile) ID to which this goal belongs. + ProfileId string `json:"profileId,omitempty"` + + // SelfLink: Link for this goal. + SelfLink string `json:"selfLink,omitempty"` + + // Type: Goal type. Possible values are URL_DESTINATION, + // VISIT_TIME_ON_SITE, VISIT_NUM_PAGES, AND EVENT. + Type string `json:"type,omitempty"` + + // Updated: Time this goal was last modified. + Updated string `json:"updated,omitempty"` + + // UrlDestinationDetails: Details for the goal of the type + // URL_DESTINATION. + UrlDestinationDetails *GoalUrlDestinationDetails `json:"urlDestinationDetails,omitempty"` + + // Value: Goal value. + Value float64 `json:"value,omitempty"` + + // VisitNumPagesDetails: Details for the goal of the type + // VISIT_NUM_PAGES. + VisitNumPagesDetails *GoalVisitNumPagesDetails `json:"visitNumPagesDetails,omitempty"` + + // VisitTimeOnSiteDetails: Details for the goal of the type + // VISIT_TIME_ON_SITE. + VisitTimeOnSiteDetails *GoalVisitTimeOnSiteDetails `json:"visitTimeOnSiteDetails,omitempty"` + + // WebPropertyId: Web property ID to which this goal belongs. The web + // property ID is of the form UA-XXXXX-YY. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Goal) MarshalJSON() ([]byte, error) { + type noMethod Goal + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// GoalEventDetails: Details for the goal of the type EVENT. +type GoalEventDetails struct { + // EventConditions: List of event conditions. + EventConditions []*GoalEventDetailsEventConditions `json:"eventConditions,omitempty"` + + // UseEventValue: Determines if the event value should be used as the + // value for this goal. + UseEventValue bool `json:"useEventValue,omitempty"` + + // ForceSendFields is a list of field names (e.g. "EventConditions") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GoalEventDetails) MarshalJSON() ([]byte, error) { + type noMethod GoalEventDetails + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type GoalEventDetailsEventConditions struct { + // ComparisonType: Type of comparison. Possible values are LESS_THAN, + // GREATER_THAN or EQUAL. + ComparisonType string `json:"comparisonType,omitempty"` + + // ComparisonValue: Value used for this comparison. + ComparisonValue int64 `json:"comparisonValue,omitempty,string"` + + // Expression: Expression used for this match. + Expression string `json:"expression,omitempty"` + + // MatchType: Type of the match to be performed. Possible values are + // REGEXP, BEGINS_WITH, or EXACT. + MatchType string `json:"matchType,omitempty"` + + // Type: Type of this event condition. Possible values are CATEGORY, + // ACTION, LABEL, or VALUE. + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "ComparisonType") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GoalEventDetailsEventConditions) MarshalJSON() ([]byte, error) { + type noMethod GoalEventDetailsEventConditions + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// GoalParentLink: Parent link for a goal. Points to the view (profile) +// to which this goal belongs. +type GoalParentLink struct { + // Href: Link to the view (profile) to which this goal belongs. + Href string `json:"href,omitempty"` + + // Type: Value is "analytics#profile". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GoalParentLink) MarshalJSON() ([]byte, error) { + type noMethod GoalParentLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// GoalUrlDestinationDetails: Details for the goal of the type +// URL_DESTINATION. +type GoalUrlDestinationDetails struct { + // CaseSensitive: Determines if the goal URL must exactly match the + // capitalization of visited URLs. + CaseSensitive bool `json:"caseSensitive,omitempty"` + + // FirstStepRequired: Determines if the first step in this goal is + // required. + FirstStepRequired bool `json:"firstStepRequired,omitempty"` + + // MatchType: Match type for the goal URL. Possible values are HEAD, + // EXACT, or REGEX. + MatchType string `json:"matchType,omitempty"` + + // Steps: List of steps configured for this goal funnel. + Steps []*GoalUrlDestinationDetailsSteps `json:"steps,omitempty"` + + // Url: URL for this goal. + Url string `json:"url,omitempty"` + + // ForceSendFields is a list of field names (e.g. "CaseSensitive") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GoalUrlDestinationDetails) MarshalJSON() ([]byte, error) { + type noMethod GoalUrlDestinationDetails + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type GoalUrlDestinationDetailsSteps struct { + // Name: Step name. + Name string `json:"name,omitempty"` + + // Number: Step number. + Number int64 `json:"number,omitempty"` + + // Url: URL for this step. + Url string `json:"url,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Name") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GoalUrlDestinationDetailsSteps) MarshalJSON() ([]byte, error) { + type noMethod GoalUrlDestinationDetailsSteps + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// GoalVisitNumPagesDetails: Details for the goal of the type +// VISIT_NUM_PAGES. +type GoalVisitNumPagesDetails struct { + // ComparisonType: Type of comparison. Possible values are LESS_THAN, + // GREATER_THAN, or EQUAL. + ComparisonType string `json:"comparisonType,omitempty"` + + // ComparisonValue: Value used for this comparison. + ComparisonValue int64 `json:"comparisonValue,omitempty,string"` + + // ForceSendFields is a list of field names (e.g. "ComparisonType") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GoalVisitNumPagesDetails) MarshalJSON() ([]byte, error) { + type noMethod GoalVisitNumPagesDetails + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// GoalVisitTimeOnSiteDetails: Details for the goal of the type +// VISIT_TIME_ON_SITE. +type GoalVisitTimeOnSiteDetails struct { + // ComparisonType: Type of comparison. Possible values are LESS_THAN or + // GREATER_THAN. + ComparisonType string `json:"comparisonType,omitempty"` + + // ComparisonValue: Value used for this comparison. + ComparisonValue int64 `json:"comparisonValue,omitempty,string"` + + // ForceSendFields is a list of field names (e.g. "ComparisonType") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *GoalVisitTimeOnSiteDetails) MarshalJSON() ([]byte, error) { + type noMethod GoalVisitTimeOnSiteDetails + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Goals: A goal collection lists Analytics goals to which the user has +// access. Each view (profile) can have a set of goals. Each resource in +// the Goal collection corresponds to a single Analytics goal. +type Goals struct { + // Items: A list of goals. + Items []*Goal `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this goal collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this goal collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of resources in the result. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Goals) MarshalJSON() ([]byte, error) { + type noMethod Goals + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// McfData: Multi-Channel Funnels data for a given view (profile). +type McfData struct { + // ColumnHeaders: Column headers that list dimension names followed by + // the metric names. The order of dimensions and metrics is same as + // specified in the request. + ColumnHeaders []*McfDataColumnHeaders `json:"columnHeaders,omitempty"` + + // ContainsSampledData: Determines if the Analytics data contains + // sampled data. + ContainsSampledData bool `json:"containsSampledData,omitempty"` + + // Id: Unique ID for this data response. + Id string `json:"id,omitempty"` + + // ItemsPerPage: The maximum number of rows the response can contain, + // regardless of the actual number of rows returned. Its value ranges + // from 1 to 10,000 with a value of 1000 by default, or otherwise + // specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Resource type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this Analytics data query. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this Analytics data query. + PreviousLink string `json:"previousLink,omitempty"` + + // ProfileInfo: Information for the view (profile), for which the + // Analytics data was requested. + ProfileInfo *McfDataProfileInfo `json:"profileInfo,omitempty"` + + // Query: Analytics data request query parameters. + Query *McfDataQuery `json:"query,omitempty"` + + // Rows: Analytics data rows, where each row contains a list of + // dimension values followed by the metric values. The order of + // dimensions and metrics is same as specified in the request. + Rows [][]*McfDataRowsItem `json:"rows,omitempty"` + + // SampleSize: The number of samples used to calculate the result. + SampleSize int64 `json:"sampleSize,omitempty,string"` + + // SampleSpace: Total size of the sample space from which the samples + // were selected. + SampleSpace int64 `json:"sampleSpace,omitempty,string"` + + // SelfLink: Link to this page. + SelfLink string `json:"selfLink,omitempty"` + + // TotalResults: The total number of rows for the query, regardless of + // the number of rows in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // TotalsForAllResults: Total values for the requested metrics over all + // the results, not just the results returned in this response. The + // order of the metric totals is same as the metric order specified in + // the request. + TotalsForAllResults map[string]string `json:"totalsForAllResults,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "ColumnHeaders") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *McfData) MarshalJSON() ([]byte, error) { + type noMethod McfData + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type McfDataColumnHeaders struct { + // ColumnType: Column Type. Either DIMENSION or METRIC. + ColumnType string `json:"columnType,omitempty"` + + // DataType: Data type. Dimension and metric values data types such as + // INTEGER, DOUBLE, CURRENCY, MCF_SEQUENCE etc. + DataType string `json:"dataType,omitempty"` + + // Name: Column name. + Name string `json:"name,omitempty"` + + // ForceSendFields is a list of field names (e.g. "ColumnType") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *McfDataColumnHeaders) MarshalJSON() ([]byte, error) { + type noMethod McfDataColumnHeaders + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// McfDataProfileInfo: Information for the view (profile), for which the +// Analytics data was requested. +type McfDataProfileInfo struct { + // AccountId: Account ID to which this view (profile) belongs. + AccountId string `json:"accountId,omitempty"` + + // InternalWebPropertyId: Internal ID for the web property to which this + // view (profile) belongs. + InternalWebPropertyId string `json:"internalWebPropertyId,omitempty"` + + // ProfileId: View (Profile) ID. + ProfileId string `json:"profileId,omitempty"` + + // ProfileName: View (Profile) name. + ProfileName string `json:"profileName,omitempty"` + + // TableId: Table ID for view (profile). + TableId string `json:"tableId,omitempty"` + + // WebPropertyId: Web Property ID to which this view (profile) belongs. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *McfDataProfileInfo) MarshalJSON() ([]byte, error) { + type noMethod McfDataProfileInfo + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// McfDataQuery: Analytics data request query parameters. +type McfDataQuery struct { + // Dimensions: List of analytics dimensions. + Dimensions string `json:"dimensions,omitempty"` + + // EndDate: End date. + EndDate string `json:"end-date,omitempty"` + + // Filters: Comma-separated list of dimension or metric filters. + Filters string `json:"filters,omitempty"` + + // Ids: Unique table ID. + Ids string `json:"ids,omitempty"` + + // MaxResults: Maximum results per page. + MaxResults int64 `json:"max-results,omitempty"` + + // Metrics: List of analytics metrics. + Metrics []string `json:"metrics,omitempty"` + + // SamplingLevel: Desired sampling level + SamplingLevel string `json:"samplingLevel,omitempty"` + + // Segment: Analytics advanced segment. + Segment string `json:"segment,omitempty"` + + // Sort: List of dimensions or metrics based on which Analytics data is + // sorted. + Sort []string `json:"sort,omitempty"` + + // StartDate: Start date. + StartDate string `json:"start-date,omitempty"` + + // StartIndex: Start index. + StartIndex int64 `json:"start-index,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Dimensions") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *McfDataQuery) MarshalJSON() ([]byte, error) { + type noMethod McfDataQuery + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// McfDataRowsItem: A union object representing a dimension or metric +// value. Only one of "primitiveValue" or "conversionPathValue" +// attribute will be populated. +type McfDataRowsItem struct { + // ConversionPathValue: A conversion path dimension value, containing a + // list of interactions with their attributes. + ConversionPathValue []*McfDataRowsItemConversionPathValue `json:"conversionPathValue,omitempty"` + + // PrimitiveValue: A primitive dimension value. A primitive metric + // value. + PrimitiveValue string `json:"primitiveValue,omitempty"` + + // ForceSendFields is a list of field names (e.g. "ConversionPathValue") + // to unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *McfDataRowsItem) MarshalJSON() ([]byte, error) { + type noMethod McfDataRowsItem + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type McfDataRowsItemConversionPathValue struct { + // InteractionType: Type of an interaction on conversion path. Such as + // CLICK, IMPRESSION etc. + InteractionType string `json:"interactionType,omitempty"` + + // NodeValue: Node value of an interaction on conversion path. Such as + // source, medium etc. + NodeValue string `json:"nodeValue,omitempty"` + + // ForceSendFields is a list of field names (e.g. "InteractionType") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *McfDataRowsItemConversionPathValue) MarshalJSON() ([]byte, error) { + type noMethod McfDataRowsItemConversionPathValue + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Profile: JSON template for an Analytics view (profile). +type Profile struct { + // AccountId: Account ID to which this view (profile) belongs. + AccountId string `json:"accountId,omitempty"` + + // ChildLink: Child link for this view (profile). Points to the list of + // goals for this view (profile). + ChildLink *ProfileChildLink `json:"childLink,omitempty"` + + // Created: Time this view (profile) was created. + Created string `json:"created,omitempty"` + + // Currency: The currency type associated with this view (profile), + // defaults to USD. The supported values are: + // ARS, AUD, BGN, BRL, CAD, CHF, CNY, CZK, DKK, EUR, GBP, HKD, HUF, IDR, + // INR, JPY, KRW, LTL, MXN, NOK, NZD, PHP, PLN, RUB, SEK, THB, TRY, TWD, + // USD, VND, ZAR + Currency string `json:"currency,omitempty"` + + // DefaultPage: Default page for this view (profile). + DefaultPage string `json:"defaultPage,omitempty"` + + // ECommerceTracking: Indicates whether ecommerce tracking is enabled + // for this view (profile). + ECommerceTracking bool `json:"eCommerceTracking,omitempty"` + + // EnhancedECommerceTracking: Indicates whether enhanced ecommerce + // tracking is enabled for this view (profile). This property can only + // be enabled if ecommerce tracking is enabled. + EnhancedECommerceTracking bool `json:"enhancedECommerceTracking,omitempty"` + + // ExcludeQueryParameters: The query parameters that are excluded from + // this view (profile). + ExcludeQueryParameters string `json:"excludeQueryParameters,omitempty"` + + // Id: View (Profile) ID. + Id string `json:"id,omitempty"` + + // InternalWebPropertyId: Internal ID for the web property to which this + // view (profile) belongs. + InternalWebPropertyId string `json:"internalWebPropertyId,omitempty"` + + // Kind: Resource type for Analytics view (profile). + Kind string `json:"kind,omitempty"` + + // Name: Name of this view (profile). + Name string `json:"name,omitempty"` + + // ParentLink: Parent link for this view (profile). Points to the web + // property to which this view (profile) belongs. + ParentLink *ProfileParentLink `json:"parentLink,omitempty"` + + // Permissions: Permissions the user has for this view (profile). + Permissions *ProfilePermissions `json:"permissions,omitempty"` + + // SelfLink: Link for this view (profile). + SelfLink string `json:"selfLink,omitempty"` + + // SiteSearchCategoryParameters: Site search category parameters for + // this view (profile). + SiteSearchCategoryParameters string `json:"siteSearchCategoryParameters,omitempty"` + + // SiteSearchQueryParameters: The site search query parameters for this + // view (profile). + SiteSearchQueryParameters string `json:"siteSearchQueryParameters,omitempty"` + + // StripSiteSearchCategoryParameters: Whether or not Analytics will + // strip search category parameters from the URLs in your reports. + StripSiteSearchCategoryParameters bool `json:"stripSiteSearchCategoryParameters,omitempty"` + + // StripSiteSearchQueryParameters: Whether or not Analytics will strip + // search query parameters from the URLs in your reports. + StripSiteSearchQueryParameters bool `json:"stripSiteSearchQueryParameters,omitempty"` + + // Timezone: Time zone for which this view (profile) has been + // configured. Time zones are identified by strings from the TZ + // database. + Timezone string `json:"timezone,omitempty"` + + // Type: View (Profile) type. Supported types: WEB or APP. + Type string `json:"type,omitempty"` + + // Updated: Time this view (profile) was last modified. + Updated string `json:"updated,omitempty"` + + // WebPropertyId: Web property ID of the form UA-XXXXX-YY to which this + // view (profile) belongs. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // WebsiteUrl: Website URL for this view (profile). + WebsiteUrl string `json:"websiteUrl,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Profile) MarshalJSON() ([]byte, error) { + type noMethod Profile + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// ProfileChildLink: Child link for this view (profile). Points to the +// list of goals for this view (profile). +type ProfileChildLink struct { + // Href: Link to the list of goals for this view (profile). + Href string `json:"href,omitempty"` + + // Type: Value is "analytics#goals". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *ProfileChildLink) MarshalJSON() ([]byte, error) { + type noMethod ProfileChildLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// ProfileParentLink: Parent link for this view (profile). Points to the +// web property to which this view (profile) belongs. +type ProfileParentLink struct { + // Href: Link to the web property to which this view (profile) belongs. + Href string `json:"href,omitempty"` + + // Type: Value is "analytics#webproperty". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *ProfileParentLink) MarshalJSON() ([]byte, error) { + type noMethod ProfileParentLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// ProfilePermissions: Permissions the user has for this view (profile). +type ProfilePermissions struct { + // Effective: All the permissions that the user has for this view + // (profile). These include any implied permissions (e.g., EDIT implies + // VIEW) or inherited permissions from the parent web property. + Effective []string `json:"effective,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Effective") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *ProfilePermissions) MarshalJSON() ([]byte, error) { + type noMethod ProfilePermissions + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// ProfileFilterLink: JSON template for an Analytics profile filter +// link. +type ProfileFilterLink struct { + // FilterRef: Filter for this link. + FilterRef *FilterRef `json:"filterRef,omitempty"` + + // Id: Profile filter link ID. + Id string `json:"id,omitempty"` + + // Kind: Resource type for Analytics filter. + Kind string `json:"kind,omitempty"` + + // ProfileRef: View (Profile) for this link. + ProfileRef *ProfileRef `json:"profileRef,omitempty"` + + // Rank: The rank of this profile filter link relative to the other + // filters linked to the same profile. + // For readonly (i.e., list and get) operations, the rank always starts + // at 1. + // For write (i.e., create, update, or delete) operations, you may + // specify a value between 0 and 255 inclusively, [0, 255]. In order to + // insert a link at the end of the list, either don't specify a rank or + // set a rank to a number greater than the largest rank in the list. In + // order to insert a link to the beginning of the list specify a rank + // that is less than or equal to 1. The new link will move all existing + // filters with the same or lower rank down the list. After the link is + // inserted/updated/deleted all profile filter links will be renumbered + // starting at 1. + Rank int64 `json:"rank,omitempty"` + + // SelfLink: Link for this profile filter link. + SelfLink string `json:"selfLink,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "FilterRef") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *ProfileFilterLink) MarshalJSON() ([]byte, error) { + type noMethod ProfileFilterLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// ProfileFilterLinks: A profile filter link collection lists profile +// filter links between profiles and filters. Each resource in the +// collection corresponds to a profile filter link. +type ProfileFilterLinks struct { + // Items: A list of profile filter links. + Items []*ProfileFilterLink `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1,000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this profile filter link collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this profile filter link + // collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *ProfileFilterLinks) MarshalJSON() ([]byte, error) { + type noMethod ProfileFilterLinks + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// ProfileRef: JSON template for a linked view (profile). +type ProfileRef struct { + // AccountId: Account ID to which this view (profile) belongs. + AccountId string `json:"accountId,omitempty"` + + // Href: Link for this view (profile). + Href string `json:"href,omitempty"` + + // Id: View (Profile) ID. + Id string `json:"id,omitempty"` + + // InternalWebPropertyId: Internal ID for the web property to which this + // view (profile) belongs. + InternalWebPropertyId string `json:"internalWebPropertyId,omitempty"` + + // Kind: Analytics view (profile) reference. + Kind string `json:"kind,omitempty"` + + // Name: Name of this view (profile). + Name string `json:"name,omitempty"` + + // WebPropertyId: Web property ID of the form UA-XXXXX-YY to which this + // view (profile) belongs. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *ProfileRef) MarshalJSON() ([]byte, error) { + type noMethod ProfileRef + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// ProfileSummary: JSON template for an Analytics ProfileSummary. +// ProfileSummary returns basic information (i.e., summary) for a +// profile. +type ProfileSummary struct { + // Id: View (profile) ID. + Id string `json:"id,omitempty"` + + // Kind: Resource type for Analytics ProfileSummary. + Kind string `json:"kind,omitempty"` + + // Name: View (profile) name. + Name string `json:"name,omitempty"` + + // Type: View (Profile) type. Supported types: WEB or APP. + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Id") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *ProfileSummary) MarshalJSON() ([]byte, error) { + type noMethod ProfileSummary + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Profiles: A view (profile) collection lists Analytics views +// (profiles) to which the user has access. Each resource in the +// collection corresponds to a single Analytics view (profile). +type Profiles struct { + // Items: A list of views (profiles). + Items []*Profile `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this view (profile) collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this view (profile) + // collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Profiles) MarshalJSON() ([]byte, error) { + type noMethod Profiles + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// RealtimeData: Real time data for a given view (profile). +type RealtimeData struct { + // ColumnHeaders: Column headers that list dimension names followed by + // the metric names. The order of dimensions and metrics is same as + // specified in the request. + ColumnHeaders []*RealtimeDataColumnHeaders `json:"columnHeaders,omitempty"` + + // Id: Unique ID for this data response. + Id string `json:"id,omitempty"` + + // Kind: Resource type. + Kind string `json:"kind,omitempty"` + + // ProfileInfo: Information for the view (profile), for which the real + // time data was requested. + ProfileInfo *RealtimeDataProfileInfo `json:"profileInfo,omitempty"` + + // Query: Real time data request query parameters. + Query *RealtimeDataQuery `json:"query,omitempty"` + + // Rows: Real time data rows, where each row contains a list of + // dimension values followed by the metric values. The order of + // dimensions and metrics is same as specified in the request. + Rows [][]string `json:"rows,omitempty"` + + // SelfLink: Link to this page. + SelfLink string `json:"selfLink,omitempty"` + + // TotalResults: The total number of rows for the query, regardless of + // the number of rows in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // TotalsForAllResults: Total values for the requested metrics over all + // the results, not just the results returned in this response. The + // order of the metric totals is same as the metric order specified in + // the request. + TotalsForAllResults map[string]string `json:"totalsForAllResults,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "ColumnHeaders") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *RealtimeData) MarshalJSON() ([]byte, error) { + type noMethod RealtimeData + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +type RealtimeDataColumnHeaders struct { + // ColumnType: Column Type. Either DIMENSION or METRIC. + ColumnType string `json:"columnType,omitempty"` + + // DataType: Data type. Dimension column headers have only STRING as the + // data type. Metric column headers have data types for metric values + // such as INTEGER, DOUBLE, CURRENCY etc. + DataType string `json:"dataType,omitempty"` + + // Name: Column name. + Name string `json:"name,omitempty"` + + // ForceSendFields is a list of field names (e.g. "ColumnType") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *RealtimeDataColumnHeaders) MarshalJSON() ([]byte, error) { + type noMethod RealtimeDataColumnHeaders + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// RealtimeDataProfileInfo: Information for the view (profile), for +// which the real time data was requested. +type RealtimeDataProfileInfo struct { + // AccountId: Account ID to which this view (profile) belongs. + AccountId string `json:"accountId,omitempty"` + + // InternalWebPropertyId: Internal ID for the web property to which this + // view (profile) belongs. + InternalWebPropertyId string `json:"internalWebPropertyId,omitempty"` + + // ProfileId: View (Profile) ID. + ProfileId string `json:"profileId,omitempty"` + + // ProfileName: View (Profile) name. + ProfileName string `json:"profileName,omitempty"` + + // TableId: Table ID for view (profile). + TableId string `json:"tableId,omitempty"` + + // WebPropertyId: Web Property ID to which this view (profile) belongs. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *RealtimeDataProfileInfo) MarshalJSON() ([]byte, error) { + type noMethod RealtimeDataProfileInfo + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// RealtimeDataQuery: Real time data request query parameters. +type RealtimeDataQuery struct { + // Dimensions: List of real time dimensions. + Dimensions string `json:"dimensions,omitempty"` + + // Filters: Comma-separated list of dimension or metric filters. + Filters string `json:"filters,omitempty"` + + // Ids: Unique table ID. + Ids string `json:"ids,omitempty"` + + // MaxResults: Maximum results per page. + MaxResults int64 `json:"max-results,omitempty"` + + // Metrics: List of real time metrics. + Metrics []string `json:"metrics,omitempty"` + + // Sort: List of dimensions or metrics based on which real time data is + // sorted. + Sort []string `json:"sort,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Dimensions") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *RealtimeDataQuery) MarshalJSON() ([]byte, error) { + type noMethod RealtimeDataQuery + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Segment: JSON template for an Analytics segment. +type Segment struct { + // Created: Time the segment was created. + Created string `json:"created,omitempty"` + + // Definition: Segment definition. + Definition string `json:"definition,omitempty"` + + // Id: Segment ID. + Id string `json:"id,omitempty"` + + // Kind: Resource type for Analytics segment. + Kind string `json:"kind,omitempty"` + + // Name: Segment name. + Name string `json:"name,omitempty"` + + // SegmentId: Segment ID. Can be used with the 'segment' parameter in + // Core Reporting API. + SegmentId string `json:"segmentId,omitempty"` + + // SelfLink: Link for this segment. + SelfLink string `json:"selfLink,omitempty"` + + // Type: Type for a segment. Possible values are "BUILT_IN" or "CUSTOM". + Type string `json:"type,omitempty"` + + // Updated: Time the segment was last modified. + Updated string `json:"updated,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Created") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Segment) MarshalJSON() ([]byte, error) { + type noMethod Segment + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Segments: An segment collection lists Analytics segments that the +// user has access to. Each resource in the collection corresponds to a +// single Analytics segment. +type Segments struct { + // Items: A list of segments. + Items []*Segment `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type for segments. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this segment collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this segment collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Segments) MarshalJSON() ([]byte, error) { + type noMethod Segments + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// UnsampledReport: JSON template for Analytics unsampled report +// resource. +type UnsampledReport struct { + // AccountId: Account ID to which this unsampled report belongs. + AccountId string `json:"accountId,omitempty"` + + // CloudStorageDownloadDetails: Download details for a file stored in + // Google Cloud Storage. + CloudStorageDownloadDetails *UnsampledReportCloudStorageDownloadDetails `json:"cloudStorageDownloadDetails,omitempty"` + + // Created: Time this unsampled report was created. + Created string `json:"created,omitempty"` + + // Dimensions: The dimensions for the unsampled report. + Dimensions string `json:"dimensions,omitempty"` + + // DownloadType: The type of download you need to use for the report + // data file. + DownloadType string `json:"downloadType,omitempty"` + + // DriveDownloadDetails: Download details for a file stored in Google + // Drive. + DriveDownloadDetails *UnsampledReportDriveDownloadDetails `json:"driveDownloadDetails,omitempty"` + + // EndDate: The end date for the unsampled report. + EndDate string `json:"end-date,omitempty"` + + // Filters: The filters for the unsampled report. + Filters string `json:"filters,omitempty"` + + // Id: Unsampled report ID. + Id string `json:"id,omitempty"` + + // Kind: Resource type for an Analytics unsampled report. + Kind string `json:"kind,omitempty"` + + // Metrics: The metrics for the unsampled report. + Metrics string `json:"metrics,omitempty"` + + // ProfileId: View (Profile) ID to which this unsampled report belongs. + ProfileId string `json:"profileId,omitempty"` + + // Segment: The segment for the unsampled report. + Segment string `json:"segment,omitempty"` + + // SelfLink: Link for this unsampled report. + SelfLink string `json:"selfLink,omitempty"` + + // StartDate: The start date for the unsampled report. + StartDate string `json:"start-date,omitempty"` + + // Status: Status of this unsampled report. Possible values are PENDING, + // COMPLETED, or FAILED. + Status string `json:"status,omitempty"` + + // Title: Title of the unsampled report. + Title string `json:"title,omitempty"` + + // Updated: Time this unsampled report was last modified. + Updated string `json:"updated,omitempty"` + + // WebPropertyId: Web property ID to which this unsampled report + // belongs. The web property ID is of the form UA-XXXXX-YY. + WebPropertyId string `json:"webPropertyId,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *UnsampledReport) MarshalJSON() ([]byte, error) { + type noMethod UnsampledReport + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// UnsampledReportCloudStorageDownloadDetails: Download details for a +// file stored in Google Cloud Storage. +type UnsampledReportCloudStorageDownloadDetails struct { + // BucketId: Id of the bucket the file object is stored in. + BucketId string `json:"bucketId,omitempty"` + + // ObjectId: Id of the file object containing the report data. + ObjectId string `json:"objectId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "BucketId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *UnsampledReportCloudStorageDownloadDetails) MarshalJSON() ([]byte, error) { + type noMethod UnsampledReportCloudStorageDownloadDetails + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// UnsampledReportDriveDownloadDetails: Download details for a file +// stored in Google Drive. +type UnsampledReportDriveDownloadDetails struct { + // DocumentId: Id of the document/file containing the report data. + DocumentId string `json:"documentId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "DocumentId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *UnsampledReportDriveDownloadDetails) MarshalJSON() ([]byte, error) { + type noMethod UnsampledReportDriveDownloadDetails + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// UnsampledReports: An unsampled report collection lists Analytics +// unsampled reports to which the user has access. Each view (profile) +// can have a set of unsampled reports. Each resource in the unsampled +// report collection corresponds to a single Analytics unsampled report. +type UnsampledReports struct { + // Items: A list of unsampled reports. + Items []*UnsampledReport `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this unsampled report collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this unsampled report + // collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of resources in the result. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *UnsampledReports) MarshalJSON() ([]byte, error) { + type noMethod UnsampledReports + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Upload: Metadata returned for an upload operation. +type Upload struct { + // AccountId: Account Id to which this upload belongs. + AccountId int64 `json:"accountId,omitempty,string"` + + // CustomDataSourceId: Custom data source Id to which this data import + // belongs. + CustomDataSourceId string `json:"customDataSourceId,omitempty"` + + // Errors: Data import errors collection. + Errors []string `json:"errors,omitempty"` + + // Id: A unique ID for this upload. + Id string `json:"id,omitempty"` + + // Kind: Resource type for Analytics upload. + Kind string `json:"kind,omitempty"` + + // Status: Upload status. Possible values: PENDING, COMPLETED, FAILED, + // DELETING, DELETED. + Status string `json:"status,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Upload) MarshalJSON() ([]byte, error) { + type noMethod Upload + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Uploads: Upload collection lists Analytics uploads to which the user +// has access. Each custom data source can have a set of uploads. Each +// resource in the upload collection corresponds to a single Analytics +// data upload. +type Uploads struct { + // Items: A list of uploads. + Items []*Upload `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this upload collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this upload collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of resources in the result. + TotalResults int64 `json:"totalResults,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Uploads) MarshalJSON() ([]byte, error) { + type noMethod Uploads + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// UserRef: JSON template for a user reference. +type UserRef struct { + // Email: Email ID of this user. + Email string `json:"email,omitempty"` + + // Id: User ID. + Id string `json:"id,omitempty"` + + Kind string `json:"kind,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Email") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *UserRef) MarshalJSON() ([]byte, error) { + type noMethod UserRef + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// WebPropertyRef: JSON template for a web property reference. +type WebPropertyRef struct { + // AccountId: Account ID to which this web property belongs. + AccountId string `json:"accountId,omitempty"` + + // Href: Link for this web property. + Href string `json:"href,omitempty"` + + // Id: Web property ID of the form UA-XXXXX-YY. + Id string `json:"id,omitempty"` + + // InternalWebPropertyId: Internal ID for this web property. + InternalWebPropertyId string `json:"internalWebPropertyId,omitempty"` + + // Kind: Analytics web property reference. + Kind string `json:"kind,omitempty"` + + // Name: Name of this web property. + Name string `json:"name,omitempty"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *WebPropertyRef) MarshalJSON() ([]byte, error) { + type noMethod WebPropertyRef + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// WebPropertySummary: JSON template for an Analytics +// WebPropertySummary. WebPropertySummary returns basic information +// (i.e., summary) for a web property. +type WebPropertySummary struct { + // Id: Web property ID of the form UA-XXXXX-YY. + Id string `json:"id,omitempty"` + + // InternalWebPropertyId: Internal ID for this web property. + InternalWebPropertyId string `json:"internalWebPropertyId,omitempty"` + + // Kind: Resource type for Analytics WebPropertySummary. + Kind string `json:"kind,omitempty"` + + // Level: Level for this web property. Possible values are STANDARD or + // PREMIUM. + Level string `json:"level,omitempty"` + + // Name: Web property name. + Name string `json:"name,omitempty"` + + // Profiles: List of profiles under this web property. + Profiles []*ProfileSummary `json:"profiles,omitempty"` + + // WebsiteUrl: Website url for this web property. + WebsiteUrl string `json:"websiteUrl,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Id") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *WebPropertySummary) MarshalJSON() ([]byte, error) { + type noMethod WebPropertySummary + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Webproperties: A web property collection lists Analytics web +// properties to which the user has access. Each resource in the +// collection corresponds to a single Analytics web property. +type Webproperties struct { + // Items: A list of web properties. + Items []*Webproperty `json:"items,omitempty"` + + // ItemsPerPage: The maximum number of resources the response can + // contain, regardless of the actual number of resources returned. Its + // value ranges from 1 to 1000 with a value of 1000 by default, or + // otherwise specified by the max-results query parameter. + ItemsPerPage int64 `json:"itemsPerPage,omitempty"` + + // Kind: Collection type. + Kind string `json:"kind,omitempty"` + + // NextLink: Link to next page for this web property collection. + NextLink string `json:"nextLink,omitempty"` + + // PreviousLink: Link to previous page for this web property collection. + PreviousLink string `json:"previousLink,omitempty"` + + // StartIndex: The starting index of the resources, which is 1 by + // default or otherwise specified by the start-index query parameter. + StartIndex int64 `json:"startIndex,omitempty"` + + // TotalResults: The total number of results for the query, regardless + // of the number of results in the response. + TotalResults int64 `json:"totalResults,omitempty"` + + // Username: Email ID of the authenticated user + Username string `json:"username,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Webproperties) MarshalJSON() ([]byte, error) { + type noMethod Webproperties + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// Webproperty: JSON template for an Analytics web property. +type Webproperty struct { + // AccountId: Account ID to which this web property belongs. + AccountId string `json:"accountId,omitempty"` + + // ChildLink: Child link for this web property. Points to the list of + // views (profiles) for this web property. + ChildLink *WebpropertyChildLink `json:"childLink,omitempty"` + + // Created: Time this web property was created. + Created string `json:"created,omitempty"` + + // DefaultProfileId: Default view (profile) ID. + DefaultProfileId int64 `json:"defaultProfileId,omitempty,string"` + + // Id: Web property ID of the form UA-XXXXX-YY. + Id string `json:"id,omitempty"` + + // IndustryVertical: The industry vertical/category selected for this + // web property. + IndustryVertical string `json:"industryVertical,omitempty"` + + // InternalWebPropertyId: Internal ID for this web property. + InternalWebPropertyId string `json:"internalWebPropertyId,omitempty"` + + // Kind: Resource type for Analytics WebProperty. + Kind string `json:"kind,omitempty"` + + // Level: Level for this web property. Possible values are STANDARD or + // PREMIUM. + Level string `json:"level,omitempty"` + + // Name: Name of this web property. + Name string `json:"name,omitempty"` + + // ParentLink: Parent link for this web property. Points to the account + // to which this web property belongs. + ParentLink *WebpropertyParentLink `json:"parentLink,omitempty"` + + // Permissions: Permissions the user has for this web property. + Permissions *WebpropertyPermissions `json:"permissions,omitempty"` + + // ProfileCount: View (Profile) count for this web property. + ProfileCount int64 `json:"profileCount,omitempty"` + + // SelfLink: Link for this web property. + SelfLink string `json:"selfLink,omitempty"` + + // Updated: Time this web property was last modified. + Updated string `json:"updated,omitempty"` + + // WebsiteUrl: Website url for this web property. + WebsiteUrl string `json:"websiteUrl,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *Webproperty) MarshalJSON() ([]byte, error) { + type noMethod Webproperty + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// WebpropertyChildLink: Child link for this web property. Points to the +// list of views (profiles) for this web property. +type WebpropertyChildLink struct { + // Href: Link to the list of views (profiles) for this web property. + Href string `json:"href,omitempty"` + + // Type: Type of the parent link. Its value is "analytics#profiles". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *WebpropertyChildLink) MarshalJSON() ([]byte, error) { + type noMethod WebpropertyChildLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// WebpropertyParentLink: Parent link for this web property. Points to +// the account to which this web property belongs. +type WebpropertyParentLink struct { + // Href: Link to the account for this web property. + Href string `json:"href,omitempty"` + + // Type: Type of the parent link. Its value is "analytics#account". + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Href") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *WebpropertyParentLink) MarshalJSON() ([]byte, error) { + type noMethod WebpropertyParentLink + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// WebpropertyPermissions: Permissions the user has for this web +// property. +type WebpropertyPermissions struct { + // Effective: All the permissions that the user has for this web + // property. These include any implied permissions (e.g., EDIT implies + // VIEW) or inherited permissions from the parent account. + Effective []string `json:"effective,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Effective") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` +} + +func (s *WebpropertyPermissions) MarshalJSON() ([]byte, error) { + type noMethod WebpropertyPermissions + raw := noMethod(*s) + return internal.MarshalJSON(raw, s.ForceSendFields) +} + +// method id "analytics.data.ga.get": + +type DataGaGetCall struct { + s *Service + ids string + startDate string + endDate string + metrics string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Returns Analytics data for a view (profile). +func (r *DataGaService) Get(ids string, startDate string, endDate string, metrics string) *DataGaGetCall { + c := &DataGaGetCall{s: r.s, opt_: make(map[string]interface{})} + c.ids = ids + c.startDate = startDate + c.endDate = endDate + c.metrics = metrics + return c +} + +// Dimensions sets the optional parameter "dimensions": A +// comma-separated list of Analytics dimensions. E.g., +// 'ga:browser,ga:city'. +func (c *DataGaGetCall) Dimensions(dimensions string) *DataGaGetCall { + c.opt_["dimensions"] = dimensions + return c +} + +// Filters sets the optional parameter "filters": A comma-separated list +// of dimension or metric filters to be applied to Analytics data. +func (c *DataGaGetCall) Filters(filters string) *DataGaGetCall { + c.opt_["filters"] = filters + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of entries to include in this feed. +func (c *DataGaGetCall) MaxResults(maxResults int64) *DataGaGetCall { + c.opt_["max-results"] = maxResults + return c +} + +// Output sets the optional parameter "output": The selected format for +// the response. Default format is JSON. +// +// Possible values: +// "dataTable" - Returns the response in Google Charts Data Table +// format. This is useful in creating visualization using Google Charts. +// "json" - Returns the response in standard JSON format. +func (c *DataGaGetCall) Output(output string) *DataGaGetCall { + c.opt_["output"] = output + return c +} + +// SamplingLevel sets the optional parameter "samplingLevel": The +// desired sampling level. +// +// Possible values: +// "DEFAULT" - Returns response with a sample size that balances speed +// and accuracy. +// "FASTER" - Returns a fast response with a smaller sample size. +// "HIGHER_PRECISION" - Returns a more accurate response using a large +// sample size, but this may result in the response being slower. +func (c *DataGaGetCall) SamplingLevel(samplingLevel string) *DataGaGetCall { + c.opt_["samplingLevel"] = samplingLevel + return c +} + +// Segment sets the optional parameter "segment": An Analytics segment +// to be applied to data. +func (c *DataGaGetCall) Segment(segment string) *DataGaGetCall { + c.opt_["segment"] = segment + return c +} + +// Sort sets the optional parameter "sort": A comma-separated list of +// dimensions or metrics that determine the sort order for Analytics +// data. +func (c *DataGaGetCall) Sort(sort string) *DataGaGetCall { + c.opt_["sort"] = sort + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first entity to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *DataGaGetCall) StartIndex(startIndex int64) *DataGaGetCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DataGaGetCall) Fields(s ...googleapi.Field) *DataGaGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *DataGaGetCall) IfNoneMatch(entityTag string) *DataGaGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *DataGaGetCall) Context(ctx context.Context) *DataGaGetCall { + c.ctx_ = ctx + return c +} + +func (c *DataGaGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + params.Set("end-date", fmt.Sprintf("%v", c.endDate)) + params.Set("ids", fmt.Sprintf("%v", c.ids)) + params.Set("metrics", fmt.Sprintf("%v", c.metrics)) + params.Set("start-date", fmt.Sprintf("%v", c.startDate)) + if v, ok := c.opt_["dimensions"]; ok { + params.Set("dimensions", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["filters"]; ok { + params.Set("filters", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["output"]; ok { + params.Set("output", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["samplingLevel"]; ok { + params.Set("samplingLevel", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["segment"]; ok { + params.Set("segment", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["sort"]; ok { + params.Set("sort", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "data/ga") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.SetOpaque(req.URL) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.data.ga.get" call. +// Exactly one of *GaData or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *GaData.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *DataGaGetCall) Do() (*GaData, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &GaData{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns Analytics data for a view (profile).", + // "httpMethod": "GET", + // "id": "analytics.data.ga.get", + // "parameterOrder": [ + // "ids", + // "start-date", + // "end-date", + // "metrics" + // ], + // "parameters": { + // "dimensions": { + // "description": "A comma-separated list of Analytics dimensions. E.g., 'ga:browser,ga:city'.", + // "location": "query", + // "pattern": "(ga:.+)?", + // "type": "string" + // }, + // "end-date": { + // "description": "End date for fetching Analytics data. Request can should specify an end date formatted as YYYY-MM-DD, or as a relative date (e.g., today, yesterday, or 7daysAgo). The default value is yesterday.", + // "location": "query", + // "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)", + // "required": true, + // "type": "string" + // }, + // "filters": { + // "description": "A comma-separated list of dimension or metric filters to be applied to Analytics data.", + // "location": "query", + // "pattern": "ga:.+", + // "type": "string" + // }, + // "ids": { + // "description": "Unique table ID for retrieving Analytics data. Table ID is of the form ga:XXXX, where XXXX is the Analytics view (profile) ID.", + // "location": "query", + // "pattern": "ga:[0-9]+", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of entries to include in this feed.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "metrics": { + // "description": "A comma-separated list of Analytics metrics. E.g., 'ga:sessions,ga:pageviews'. At least one metric must be specified.", + // "location": "query", + // "pattern": "ga:.+", + // "required": true, + // "type": "string" + // }, + // "output": { + // "description": "The selected format for the response. Default format is JSON.", + // "enum": [ + // "dataTable", + // "json" + // ], + // "enumDescriptions": [ + // "Returns the response in Google Charts Data Table format. This is useful in creating visualization using Google Charts.", + // "Returns the response in standard JSON format." + // ], + // "location": "query", + // "type": "string" + // }, + // "samplingLevel": { + // "description": "The desired sampling level.", + // "enum": [ + // "DEFAULT", + // "FASTER", + // "HIGHER_PRECISION" + // ], + // "enumDescriptions": [ + // "Returns response with a sample size that balances speed and accuracy.", + // "Returns a fast response with a smaller sample size.", + // "Returns a more accurate response using a large sample size, but this may result in the response being slower." + // ], + // "location": "query", + // "type": "string" + // }, + // "segment": { + // "description": "An Analytics segment to be applied to data.", + // "location": "query", + // "type": "string" + // }, + // "sort": { + // "description": "A comma-separated list of dimensions or metrics that determine the sort order for Analytics data.", + // "location": "query", + // "pattern": "(-)?ga:.+", + // "type": "string" + // }, + // "start-date": { + // "description": "Start date for fetching Analytics data. Requests can specify a start date formatted as YYYY-MM-DD, or as a relative date (e.g., today, yesterday, or 7daysAgo). The default value is 7daysAgo.", + // "location": "query", + // "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)", + // "required": true, + // "type": "string" + // }, + // "start-index": { + // "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // } + // }, + // "path": "data/ga", + // "response": { + // "$ref": "GaData" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.data.mcf.get": + +type DataMcfGetCall struct { + s *Service + ids string + startDate string + endDate string + metrics string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Returns Analytics Multi-Channel Funnels data for a view +// (profile). +func (r *DataMcfService) Get(ids string, startDate string, endDate string, metrics string) *DataMcfGetCall { + c := &DataMcfGetCall{s: r.s, opt_: make(map[string]interface{})} + c.ids = ids + c.startDate = startDate + c.endDate = endDate + c.metrics = metrics + return c +} + +// Dimensions sets the optional parameter "dimensions": A +// comma-separated list of Multi-Channel Funnels dimensions. E.g., +// 'mcf:source,mcf:medium'. +func (c *DataMcfGetCall) Dimensions(dimensions string) *DataMcfGetCall { + c.opt_["dimensions"] = dimensions + return c +} + +// Filters sets the optional parameter "filters": A comma-separated list +// of dimension or metric filters to be applied to the Analytics data. +func (c *DataMcfGetCall) Filters(filters string) *DataMcfGetCall { + c.opt_["filters"] = filters + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of entries to include in this feed. +func (c *DataMcfGetCall) MaxResults(maxResults int64) *DataMcfGetCall { + c.opt_["max-results"] = maxResults + return c +} + +// SamplingLevel sets the optional parameter "samplingLevel": The +// desired sampling level. +// +// Possible values: +// "DEFAULT" - Returns response with a sample size that balances speed +// and accuracy. +// "FASTER" - Returns a fast response with a smaller sample size. +// "HIGHER_PRECISION" - Returns a more accurate response using a large +// sample size, but this may result in the response being slower. +func (c *DataMcfGetCall) SamplingLevel(samplingLevel string) *DataMcfGetCall { + c.opt_["samplingLevel"] = samplingLevel + return c +} + +// Sort sets the optional parameter "sort": A comma-separated list of +// dimensions or metrics that determine the sort order for the Analytics +// data. +func (c *DataMcfGetCall) Sort(sort string) *DataMcfGetCall { + c.opt_["sort"] = sort + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first entity to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *DataMcfGetCall) StartIndex(startIndex int64) *DataMcfGetCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DataMcfGetCall) Fields(s ...googleapi.Field) *DataMcfGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *DataMcfGetCall) IfNoneMatch(entityTag string) *DataMcfGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *DataMcfGetCall) Context(ctx context.Context) *DataMcfGetCall { + c.ctx_ = ctx + return c +} + +func (c *DataMcfGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + params.Set("end-date", fmt.Sprintf("%v", c.endDate)) + params.Set("ids", fmt.Sprintf("%v", c.ids)) + params.Set("metrics", fmt.Sprintf("%v", c.metrics)) + params.Set("start-date", fmt.Sprintf("%v", c.startDate)) + if v, ok := c.opt_["dimensions"]; ok { + params.Set("dimensions", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["filters"]; ok { + params.Set("filters", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["samplingLevel"]; ok { + params.Set("samplingLevel", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["sort"]; ok { + params.Set("sort", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "data/mcf") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.SetOpaque(req.URL) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.data.mcf.get" call. +// Exactly one of *McfData or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *McfData.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *DataMcfGetCall) Do() (*McfData, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &McfData{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns Analytics Multi-Channel Funnels data for a view (profile).", + // "httpMethod": "GET", + // "id": "analytics.data.mcf.get", + // "parameterOrder": [ + // "ids", + // "start-date", + // "end-date", + // "metrics" + // ], + // "parameters": { + // "dimensions": { + // "description": "A comma-separated list of Multi-Channel Funnels dimensions. E.g., 'mcf:source,mcf:medium'.", + // "location": "query", + // "pattern": "(mcf:.+)?", + // "type": "string" + // }, + // "end-date": { + // "description": "End date for fetching Analytics data. Requests can specify a start date formatted as YYYY-MM-DD, or as a relative date (e.g., today, yesterday, or 7daysAgo). The default value is 7daysAgo.", + // "location": "query", + // "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)", + // "required": true, + // "type": "string" + // }, + // "filters": { + // "description": "A comma-separated list of dimension or metric filters to be applied to the Analytics data.", + // "location": "query", + // "pattern": "mcf:.+", + // "type": "string" + // }, + // "ids": { + // "description": "Unique table ID for retrieving Analytics data. Table ID is of the form ga:XXXX, where XXXX is the Analytics view (profile) ID.", + // "location": "query", + // "pattern": "ga:[0-9]+", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of entries to include in this feed.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "metrics": { + // "description": "A comma-separated list of Multi-Channel Funnels metrics. E.g., 'mcf:totalConversions,mcf:totalConversionValue'. At least one metric must be specified.", + // "location": "query", + // "pattern": "mcf:.+", + // "required": true, + // "type": "string" + // }, + // "samplingLevel": { + // "description": "The desired sampling level.", + // "enum": [ + // "DEFAULT", + // "FASTER", + // "HIGHER_PRECISION" + // ], + // "enumDescriptions": [ + // "Returns response with a sample size that balances speed and accuracy.", + // "Returns a fast response with a smaller sample size.", + // "Returns a more accurate response using a large sample size, but this may result in the response being slower." + // ], + // "location": "query", + // "type": "string" + // }, + // "sort": { + // "description": "A comma-separated list of dimensions or metrics that determine the sort order for the Analytics data.", + // "location": "query", + // "pattern": "(-)?mcf:.+", + // "type": "string" + // }, + // "start-date": { + // "description": "Start date for fetching Analytics data. Requests can specify a start date formatted as YYYY-MM-DD, or as a relative date (e.g., today, yesterday, or 7daysAgo). The default value is 7daysAgo.", + // "location": "query", + // "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)", + // "required": true, + // "type": "string" + // }, + // "start-index": { + // "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // } + // }, + // "path": "data/mcf", + // "response": { + // "$ref": "McfData" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.data.realtime.get": + +type DataRealtimeGetCall struct { + s *Service + ids string + metrics string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Returns real time data for a view (profile). +func (r *DataRealtimeService) Get(ids string, metrics string) *DataRealtimeGetCall { + c := &DataRealtimeGetCall{s: r.s, opt_: make(map[string]interface{})} + c.ids = ids + c.metrics = metrics + return c +} + +// Dimensions sets the optional parameter "dimensions": A +// comma-separated list of real time dimensions. E.g., +// 'rt:medium,rt:city'. +func (c *DataRealtimeGetCall) Dimensions(dimensions string) *DataRealtimeGetCall { + c.opt_["dimensions"] = dimensions + return c +} + +// Filters sets the optional parameter "filters": A comma-separated list +// of dimension or metric filters to be applied to real time data. +func (c *DataRealtimeGetCall) Filters(filters string) *DataRealtimeGetCall { + c.opt_["filters"] = filters + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of entries to include in this feed. +func (c *DataRealtimeGetCall) MaxResults(maxResults int64) *DataRealtimeGetCall { + c.opt_["max-results"] = maxResults + return c +} + +// Sort sets the optional parameter "sort": A comma-separated list of +// dimensions or metrics that determine the sort order for real time +// data. +func (c *DataRealtimeGetCall) Sort(sort string) *DataRealtimeGetCall { + c.opt_["sort"] = sort + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DataRealtimeGetCall) Fields(s ...googleapi.Field) *DataRealtimeGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *DataRealtimeGetCall) IfNoneMatch(entityTag string) *DataRealtimeGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *DataRealtimeGetCall) Context(ctx context.Context) *DataRealtimeGetCall { + c.ctx_ = ctx + return c +} + +func (c *DataRealtimeGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + params.Set("ids", fmt.Sprintf("%v", c.ids)) + params.Set("metrics", fmt.Sprintf("%v", c.metrics)) + if v, ok := c.opt_["dimensions"]; ok { + params.Set("dimensions", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["filters"]; ok { + params.Set("filters", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["sort"]; ok { + params.Set("sort", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "data/realtime") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.SetOpaque(req.URL) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.data.realtime.get" call. +// Exactly one of *RealtimeData or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *RealtimeData.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *DataRealtimeGetCall) Do() (*RealtimeData, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &RealtimeData{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns real time data for a view (profile).", + // "httpMethod": "GET", + // "id": "analytics.data.realtime.get", + // "parameterOrder": [ + // "ids", + // "metrics" + // ], + // "parameters": { + // "dimensions": { + // "description": "A comma-separated list of real time dimensions. E.g., 'rt:medium,rt:city'.", + // "location": "query", + // "pattern": "(ga:.+)|(rt:.+)", + // "type": "string" + // }, + // "filters": { + // "description": "A comma-separated list of dimension or metric filters to be applied to real time data.", + // "location": "query", + // "pattern": "(ga:.+)|(rt:.+)", + // "type": "string" + // }, + // "ids": { + // "description": "Unique table ID for retrieving real time data. Table ID is of the form ga:XXXX, where XXXX is the Analytics view (profile) ID.", + // "location": "query", + // "pattern": "ga:[0-9]+", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of entries to include in this feed.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "metrics": { + // "description": "A comma-separated list of real time metrics. E.g., 'rt:activeUsers'. At least one metric must be specified.", + // "location": "query", + // "pattern": "(ga:.+)|(rt:.+)", + // "required": true, + // "type": "string" + // }, + // "sort": { + // "description": "A comma-separated list of dimensions or metrics that determine the sort order for real time data.", + // "location": "query", + // "pattern": "(-)?((ga:.+)|(rt:.+))", + // "type": "string" + // } + // }, + // "path": "data/realtime", + // "response": { + // "$ref": "RealtimeData" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.accountSummaries.list": + +type ManagementAccountSummariesListCall struct { + s *Service + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists account summaries (lightweight tree comprised of +// accounts/properties/profiles) to which the user has access. +func (r *ManagementAccountSummariesService) List() *ManagementAccountSummariesListCall { + c := &ManagementAccountSummariesListCall{s: r.s, opt_: make(map[string]interface{})} + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of account summaries to include in this response, where the +// largest acceptable value is 1000. +func (c *ManagementAccountSummariesListCall) MaxResults(maxResults int64) *ManagementAccountSummariesListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first entity to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementAccountSummariesListCall) StartIndex(startIndex int64) *ManagementAccountSummariesListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementAccountSummariesListCall) Fields(s ...googleapi.Field) *ManagementAccountSummariesListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementAccountSummariesListCall) IfNoneMatch(entityTag string) *ManagementAccountSummariesListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementAccountSummariesListCall) Context(ctx context.Context) *ManagementAccountSummariesListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementAccountSummariesListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accountSummaries") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.SetOpaque(req.URL) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.accountSummaries.list" call. +// Exactly one of *AccountSummaries or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *AccountSummaries.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementAccountSummariesListCall) Do() (*AccountSummaries, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &AccountSummaries{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists account summaries (lightweight tree comprised of accounts/properties/profiles) to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.accountSummaries.list", + // "parameters": { + // "max-results": { + // "description": "The maximum number of account summaries to include in this response, where the largest acceptable value is 1000.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // } + // }, + // "path": "management/accountSummaries", + // "response": { + // "$ref": "AccountSummaries" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.accountUserLinks.delete": + +type ManagementAccountUserLinksDeleteCall struct { + s *Service + accountId string + linkId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Delete: Removes a user from the given account. +func (r *ManagementAccountUserLinksService) Delete(accountId string, linkId string) *ManagementAccountUserLinksDeleteCall { + c := &ManagementAccountUserLinksDeleteCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.linkId = linkId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementAccountUserLinksDeleteCall) Fields(s ...googleapi.Field) *ManagementAccountUserLinksDeleteCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementAccountUserLinksDeleteCall) Context(ctx context.Context) *ManagementAccountUserLinksDeleteCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementAccountUserLinksDeleteCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/entityUserLinks/{linkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "linkId": c.linkId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.accountUserLinks.delete" call. +func (c *ManagementAccountUserLinksDeleteCall) Do() error { + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Removes a user from the given account.", + // "httpMethod": "DELETE", + // "id": "analytics.management.accountUserLinks.delete", + // "parameterOrder": [ + // "accountId", + // "linkId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to delete the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "linkId": { + // "description": "Link ID to delete the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/entityUserLinks/{linkId}", + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users" + // ] + // } + +} + +// method id "analytics.management.accountUserLinks.insert": + +type ManagementAccountUserLinksInsertCall struct { + s *Service + accountId string + entityuserlink *EntityUserLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Adds a new user to the given account. +func (r *ManagementAccountUserLinksService) Insert(accountId string, entityuserlink *EntityUserLink) *ManagementAccountUserLinksInsertCall { + c := &ManagementAccountUserLinksInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.entityuserlink = entityuserlink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementAccountUserLinksInsertCall) Fields(s ...googleapi.Field) *ManagementAccountUserLinksInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementAccountUserLinksInsertCall) Context(ctx context.Context) *ManagementAccountUserLinksInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementAccountUserLinksInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.entityuserlink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/entityUserLinks") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.accountUserLinks.insert" call. +// Exactly one of *EntityUserLink or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *EntityUserLink.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementAccountUserLinksInsertCall) Do() (*EntityUserLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityUserLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Adds a new user to the given account.", + // "httpMethod": "POST", + // "id": "analytics.management.accountUserLinks.insert", + // "parameterOrder": [ + // "accountId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to create the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/entityUserLinks", + // "request": { + // "$ref": "EntityUserLink" + // }, + // "response": { + // "$ref": "EntityUserLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users" + // ] + // } + +} + +// method id "analytics.management.accountUserLinks.list": + +type ManagementAccountUserLinksListCall struct { + s *Service + accountId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists account-user links for a given account. +func (r *ManagementAccountUserLinksService) List(accountId string) *ManagementAccountUserLinksListCall { + c := &ManagementAccountUserLinksListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of account-user links to include in this response. +func (c *ManagementAccountUserLinksListCall) MaxResults(maxResults int64) *ManagementAccountUserLinksListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first account-user link to retrieve. Use this parameter as a +// pagination mechanism along with the max-results parameter. +func (c *ManagementAccountUserLinksListCall) StartIndex(startIndex int64) *ManagementAccountUserLinksListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementAccountUserLinksListCall) Fields(s ...googleapi.Field) *ManagementAccountUserLinksListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementAccountUserLinksListCall) IfNoneMatch(entityTag string) *ManagementAccountUserLinksListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementAccountUserLinksListCall) Context(ctx context.Context) *ManagementAccountUserLinksListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementAccountUserLinksListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/entityUserLinks") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.accountUserLinks.list" call. +// Exactly one of *EntityUserLinks or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *EntityUserLinks.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementAccountUserLinksListCall) Do() (*EntityUserLinks, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityUserLinks{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists account-user links for a given account.", + // "httpMethod": "GET", + // "id": "analytics.management.accountUserLinks.list", + // "parameterOrder": [ + // "accountId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve the user links for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of account-user links to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first account-user link to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // } + // }, + // "path": "management/accounts/{accountId}/entityUserLinks", + // "response": { + // "$ref": "EntityUserLinks" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users", + // "https://www.googleapis.com/auth/analytics.manage.users.readonly" + // ] + // } + +} + +// method id "analytics.management.accountUserLinks.update": + +type ManagementAccountUserLinksUpdateCall struct { + s *Service + accountId string + linkId string + entityuserlink *EntityUserLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Updates permissions for an existing user on the given +// account. +func (r *ManagementAccountUserLinksService) Update(accountId string, linkId string, entityuserlink *EntityUserLink) *ManagementAccountUserLinksUpdateCall { + c := &ManagementAccountUserLinksUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.linkId = linkId + c.entityuserlink = entityuserlink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementAccountUserLinksUpdateCall) Fields(s ...googleapi.Field) *ManagementAccountUserLinksUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementAccountUserLinksUpdateCall) Context(ctx context.Context) *ManagementAccountUserLinksUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementAccountUserLinksUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.entityuserlink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/entityUserLinks/{linkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "linkId": c.linkId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.accountUserLinks.update" call. +// Exactly one of *EntityUserLink or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *EntityUserLink.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementAccountUserLinksUpdateCall) Do() (*EntityUserLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityUserLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates permissions for an existing user on the given account.", + // "httpMethod": "PUT", + // "id": "analytics.management.accountUserLinks.update", + // "parameterOrder": [ + // "accountId", + // "linkId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to update the account-user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "linkId": { + // "description": "Link ID to update the account-user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/entityUserLinks/{linkId}", + // "request": { + // "$ref": "EntityUserLink" + // }, + // "response": { + // "$ref": "EntityUserLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users" + // ] + // } + +} + +// method id "analytics.management.accounts.list": + +type ManagementAccountsListCall struct { + s *Service + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists all accounts to which the user has access. +func (r *ManagementAccountsService) List() *ManagementAccountsListCall { + c := &ManagementAccountsListCall{s: r.s, opt_: make(map[string]interface{})} + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of accounts to include in this response. +func (c *ManagementAccountsListCall) MaxResults(maxResults int64) *ManagementAccountsListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first account to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementAccountsListCall) StartIndex(startIndex int64) *ManagementAccountsListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementAccountsListCall) Fields(s ...googleapi.Field) *ManagementAccountsListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementAccountsListCall) IfNoneMatch(entityTag string) *ManagementAccountsListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementAccountsListCall) Context(ctx context.Context) *ManagementAccountsListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementAccountsListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.SetOpaque(req.URL) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.accounts.list" call. +// Exactly one of *Accounts or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Accounts.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementAccountsListCall) Do() (*Accounts, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Accounts{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists all accounts to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.accounts.list", + // "parameters": { + // "max-results": { + // "description": "The maximum number of accounts to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first account to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // } + // }, + // "path": "management/accounts", + // "response": { + // "$ref": "Accounts" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.customDataSources.list": + +type ManagementCustomDataSourcesListCall struct { + s *Service + accountId string + webPropertyId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: List custom data sources to which the user has access. +func (r *ManagementCustomDataSourcesService) List(accountId string, webPropertyId string) *ManagementCustomDataSourcesListCall { + c := &ManagementCustomDataSourcesListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of custom data sources to include in this response. +func (c *ManagementCustomDataSourcesListCall) MaxResults(maxResults int64) *ManagementCustomDataSourcesListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": A 1-based index +// of the first custom data source to retrieve. Use this parameter as a +// pagination mechanism along with the max-results parameter. +func (c *ManagementCustomDataSourcesListCall) StartIndex(startIndex int64) *ManagementCustomDataSourcesListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomDataSourcesListCall) Fields(s ...googleapi.Field) *ManagementCustomDataSourcesListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementCustomDataSourcesListCall) IfNoneMatch(entityTag string) *ManagementCustomDataSourcesListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomDataSourcesListCall) Context(ctx context.Context) *ManagementCustomDataSourcesListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomDataSourcesListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customDataSources.list" call. +// Exactly one of *CustomDataSources or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *CustomDataSources.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementCustomDataSourcesListCall) Do() (*CustomDataSources, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomDataSources{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "List custom data sources to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.customDataSources.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account Id for the custom data sources to retrieve.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of custom data sources to include in this response.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "start-index": { + // "description": "A 1-based index of the first custom data source to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web property Id for the custom data sources to retrieve.", + // "location": "path", + // "pattern": "UA-(\\d+)-(\\d+)", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources", + // "response": { + // "$ref": "CustomDataSources" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.customDimensions.get": + +type ManagementCustomDimensionsGetCall struct { + s *Service + accountId string + webPropertyId string + customDimensionId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Get a custom dimension to which the user has access. +func (r *ManagementCustomDimensionsService) Get(accountId string, webPropertyId string, customDimensionId string) *ManagementCustomDimensionsGetCall { + c := &ManagementCustomDimensionsGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customDimensionId = customDimensionId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomDimensionsGetCall) Fields(s ...googleapi.Field) *ManagementCustomDimensionsGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementCustomDimensionsGetCall) IfNoneMatch(entityTag string) *ManagementCustomDimensionsGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomDimensionsGetCall) Context(ctx context.Context) *ManagementCustomDimensionsGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomDimensionsGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions/{customDimensionId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "customDimensionId": c.customDimensionId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customDimensions.get" call. +// Exactly one of *CustomDimension or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *CustomDimension.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementCustomDimensionsGetCall) Do() (*CustomDimension, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomDimension{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Get a custom dimension to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.customDimensions.get", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "customDimensionId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the custom dimension to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "customDimensionId": { + // "description": "The ID of the custom dimension to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID for the custom dimension to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions/{customDimensionId}", + // "response": { + // "$ref": "CustomDimension" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.customDimensions.insert": + +type ManagementCustomDimensionsInsertCall struct { + s *Service + accountId string + webPropertyId string + customdimension *CustomDimension + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Create a new custom dimension. +func (r *ManagementCustomDimensionsService) Insert(accountId string, webPropertyId string, customdimension *CustomDimension) *ManagementCustomDimensionsInsertCall { + c := &ManagementCustomDimensionsInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customdimension = customdimension + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomDimensionsInsertCall) Fields(s ...googleapi.Field) *ManagementCustomDimensionsInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomDimensionsInsertCall) Context(ctx context.Context) *ManagementCustomDimensionsInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomDimensionsInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.customdimension) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customDimensions.insert" call. +// Exactly one of *CustomDimension or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *CustomDimension.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementCustomDimensionsInsertCall) Do() (*CustomDimension, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomDimension{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Create a new custom dimension.", + // "httpMethod": "POST", + // "id": "analytics.management.customDimensions.insert", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the custom dimension to create.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID for the custom dimension to create.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions", + // "request": { + // "$ref": "CustomDimension" + // }, + // "response": { + // "$ref": "CustomDimension" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.customDimensions.list": + +type ManagementCustomDimensionsListCall struct { + s *Service + accountId string + webPropertyId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists custom dimensions to which the user has access. +func (r *ManagementCustomDimensionsService) List(accountId string, webPropertyId string) *ManagementCustomDimensionsListCall { + c := &ManagementCustomDimensionsListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of custom dimensions to include in this response. +func (c *ManagementCustomDimensionsListCall) MaxResults(maxResults int64) *ManagementCustomDimensionsListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first entity to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementCustomDimensionsListCall) StartIndex(startIndex int64) *ManagementCustomDimensionsListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomDimensionsListCall) Fields(s ...googleapi.Field) *ManagementCustomDimensionsListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementCustomDimensionsListCall) IfNoneMatch(entityTag string) *ManagementCustomDimensionsListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomDimensionsListCall) Context(ctx context.Context) *ManagementCustomDimensionsListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomDimensionsListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customDimensions.list" call. +// Exactly one of *CustomDimensions or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *CustomDimensions.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementCustomDimensionsListCall) Do() (*CustomDimensions, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomDimensions{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists custom dimensions to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.customDimensions.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the custom dimensions to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of custom dimensions to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web property ID for the custom dimensions to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions", + // "response": { + // "$ref": "CustomDimensions" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.customDimensions.patch": + +type ManagementCustomDimensionsPatchCall struct { + s *Service + accountId string + webPropertyId string + customDimensionId string + customdimension *CustomDimension + opt_ map[string]interface{} + ctx_ context.Context +} + +// Patch: Updates an existing custom dimension. This method supports +// patch semantics. +func (r *ManagementCustomDimensionsService) Patch(accountId string, webPropertyId string, customDimensionId string, customdimension *CustomDimension) *ManagementCustomDimensionsPatchCall { + c := &ManagementCustomDimensionsPatchCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customDimensionId = customDimensionId + c.customdimension = customdimension + return c +} + +// IgnoreCustomDataSourceLinks sets the optional parameter +// "ignoreCustomDataSourceLinks": Force the update and ignore any +// warnings related to the custom dimension being linked to a custom +// data source / data set. +func (c *ManagementCustomDimensionsPatchCall) IgnoreCustomDataSourceLinks(ignoreCustomDataSourceLinks bool) *ManagementCustomDimensionsPatchCall { + c.opt_["ignoreCustomDataSourceLinks"] = ignoreCustomDataSourceLinks + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomDimensionsPatchCall) Fields(s ...googleapi.Field) *ManagementCustomDimensionsPatchCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomDimensionsPatchCall) Context(ctx context.Context) *ManagementCustomDimensionsPatchCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomDimensionsPatchCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.customdimension) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["ignoreCustomDataSourceLinks"]; ok { + params.Set("ignoreCustomDataSourceLinks", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions/{customDimensionId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "customDimensionId": c.customDimensionId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customDimensions.patch" call. +// Exactly one of *CustomDimension or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *CustomDimension.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementCustomDimensionsPatchCall) Do() (*CustomDimension, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomDimension{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing custom dimension. This method supports patch semantics.", + // "httpMethod": "PATCH", + // "id": "analytics.management.customDimensions.patch", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "customDimensionId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the custom dimension to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "customDimensionId": { + // "description": "Custom dimension ID for the custom dimension to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ignoreCustomDataSourceLinks": { + // "default": "false", + // "description": "Force the update and ignore any warnings related to the custom dimension being linked to a custom data source / data set.", + // "location": "query", + // "type": "boolean" + // }, + // "webPropertyId": { + // "description": "Web property ID for the custom dimension to update.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions/{customDimensionId}", + // "request": { + // "$ref": "CustomDimension" + // }, + // "response": { + // "$ref": "CustomDimension" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.customDimensions.update": + +type ManagementCustomDimensionsUpdateCall struct { + s *Service + accountId string + webPropertyId string + customDimensionId string + customdimension *CustomDimension + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Updates an existing custom dimension. +func (r *ManagementCustomDimensionsService) Update(accountId string, webPropertyId string, customDimensionId string, customdimension *CustomDimension) *ManagementCustomDimensionsUpdateCall { + c := &ManagementCustomDimensionsUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customDimensionId = customDimensionId + c.customdimension = customdimension + return c +} + +// IgnoreCustomDataSourceLinks sets the optional parameter +// "ignoreCustomDataSourceLinks": Force the update and ignore any +// warnings related to the custom dimension being linked to a custom +// data source / data set. +func (c *ManagementCustomDimensionsUpdateCall) IgnoreCustomDataSourceLinks(ignoreCustomDataSourceLinks bool) *ManagementCustomDimensionsUpdateCall { + c.opt_["ignoreCustomDataSourceLinks"] = ignoreCustomDataSourceLinks + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomDimensionsUpdateCall) Fields(s ...googleapi.Field) *ManagementCustomDimensionsUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomDimensionsUpdateCall) Context(ctx context.Context) *ManagementCustomDimensionsUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomDimensionsUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.customdimension) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["ignoreCustomDataSourceLinks"]; ok { + params.Set("ignoreCustomDataSourceLinks", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions/{customDimensionId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "customDimensionId": c.customDimensionId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customDimensions.update" call. +// Exactly one of *CustomDimension or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *CustomDimension.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementCustomDimensionsUpdateCall) Do() (*CustomDimension, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomDimension{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing custom dimension.", + // "httpMethod": "PUT", + // "id": "analytics.management.customDimensions.update", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "customDimensionId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the custom dimension to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "customDimensionId": { + // "description": "Custom dimension ID for the custom dimension to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ignoreCustomDataSourceLinks": { + // "default": "false", + // "description": "Force the update and ignore any warnings related to the custom dimension being linked to a custom data source / data set.", + // "location": "query", + // "type": "boolean" + // }, + // "webPropertyId": { + // "description": "Web property ID for the custom dimension to update.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDimensions/{customDimensionId}", + // "request": { + // "$ref": "CustomDimension" + // }, + // "response": { + // "$ref": "CustomDimension" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.customMetrics.get": + +type ManagementCustomMetricsGetCall struct { + s *Service + accountId string + webPropertyId string + customMetricId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Get a custom metric to which the user has access. +func (r *ManagementCustomMetricsService) Get(accountId string, webPropertyId string, customMetricId string) *ManagementCustomMetricsGetCall { + c := &ManagementCustomMetricsGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customMetricId = customMetricId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomMetricsGetCall) Fields(s ...googleapi.Field) *ManagementCustomMetricsGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementCustomMetricsGetCall) IfNoneMatch(entityTag string) *ManagementCustomMetricsGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomMetricsGetCall) Context(ctx context.Context) *ManagementCustomMetricsGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomMetricsGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics/{customMetricId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "customMetricId": c.customMetricId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customMetrics.get" call. +// Exactly one of *CustomMetric or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *CustomMetric.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementCustomMetricsGetCall) Do() (*CustomMetric, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomMetric{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Get a custom metric to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.customMetrics.get", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "customMetricId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the custom metric to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "customMetricId": { + // "description": "The ID of the custom metric to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID for the custom metric to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics/{customMetricId}", + // "response": { + // "$ref": "CustomMetric" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.customMetrics.insert": + +type ManagementCustomMetricsInsertCall struct { + s *Service + accountId string + webPropertyId string + custommetric *CustomMetric + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Create a new custom metric. +func (r *ManagementCustomMetricsService) Insert(accountId string, webPropertyId string, custommetric *CustomMetric) *ManagementCustomMetricsInsertCall { + c := &ManagementCustomMetricsInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.custommetric = custommetric + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomMetricsInsertCall) Fields(s ...googleapi.Field) *ManagementCustomMetricsInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomMetricsInsertCall) Context(ctx context.Context) *ManagementCustomMetricsInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomMetricsInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.custommetric) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customMetrics.insert" call. +// Exactly one of *CustomMetric or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *CustomMetric.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementCustomMetricsInsertCall) Do() (*CustomMetric, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomMetric{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Create a new custom metric.", + // "httpMethod": "POST", + // "id": "analytics.management.customMetrics.insert", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the custom metric to create.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID for the custom dimension to create.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics", + // "request": { + // "$ref": "CustomMetric" + // }, + // "response": { + // "$ref": "CustomMetric" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.customMetrics.list": + +type ManagementCustomMetricsListCall struct { + s *Service + accountId string + webPropertyId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists custom metrics to which the user has access. +func (r *ManagementCustomMetricsService) List(accountId string, webPropertyId string) *ManagementCustomMetricsListCall { + c := &ManagementCustomMetricsListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of custom metrics to include in this response. +func (c *ManagementCustomMetricsListCall) MaxResults(maxResults int64) *ManagementCustomMetricsListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first entity to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementCustomMetricsListCall) StartIndex(startIndex int64) *ManagementCustomMetricsListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomMetricsListCall) Fields(s ...googleapi.Field) *ManagementCustomMetricsListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementCustomMetricsListCall) IfNoneMatch(entityTag string) *ManagementCustomMetricsListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomMetricsListCall) Context(ctx context.Context) *ManagementCustomMetricsListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomMetricsListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customMetrics.list" call. +// Exactly one of *CustomMetrics or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *CustomMetrics.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementCustomMetricsListCall) Do() (*CustomMetrics, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomMetrics{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists custom metrics to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.customMetrics.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the custom metrics to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of custom metrics to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web property ID for the custom metrics to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics", + // "response": { + // "$ref": "CustomMetrics" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.customMetrics.patch": + +type ManagementCustomMetricsPatchCall struct { + s *Service + accountId string + webPropertyId string + customMetricId string + custommetric *CustomMetric + opt_ map[string]interface{} + ctx_ context.Context +} + +// Patch: Updates an existing custom metric. This method supports patch +// semantics. +func (r *ManagementCustomMetricsService) Patch(accountId string, webPropertyId string, customMetricId string, custommetric *CustomMetric) *ManagementCustomMetricsPatchCall { + c := &ManagementCustomMetricsPatchCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customMetricId = customMetricId + c.custommetric = custommetric + return c +} + +// IgnoreCustomDataSourceLinks sets the optional parameter +// "ignoreCustomDataSourceLinks": Force the update and ignore any +// warnings related to the custom metric being linked to a custom data +// source / data set. +func (c *ManagementCustomMetricsPatchCall) IgnoreCustomDataSourceLinks(ignoreCustomDataSourceLinks bool) *ManagementCustomMetricsPatchCall { + c.opt_["ignoreCustomDataSourceLinks"] = ignoreCustomDataSourceLinks + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomMetricsPatchCall) Fields(s ...googleapi.Field) *ManagementCustomMetricsPatchCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomMetricsPatchCall) Context(ctx context.Context) *ManagementCustomMetricsPatchCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomMetricsPatchCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.custommetric) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["ignoreCustomDataSourceLinks"]; ok { + params.Set("ignoreCustomDataSourceLinks", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics/{customMetricId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "customMetricId": c.customMetricId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customMetrics.patch" call. +// Exactly one of *CustomMetric or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *CustomMetric.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementCustomMetricsPatchCall) Do() (*CustomMetric, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomMetric{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing custom metric. This method supports patch semantics.", + // "httpMethod": "PATCH", + // "id": "analytics.management.customMetrics.patch", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "customMetricId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the custom metric to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "customMetricId": { + // "description": "Custom metric ID for the custom metric to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ignoreCustomDataSourceLinks": { + // "default": "false", + // "description": "Force the update and ignore any warnings related to the custom metric being linked to a custom data source / data set.", + // "location": "query", + // "type": "boolean" + // }, + // "webPropertyId": { + // "description": "Web property ID for the custom metric to update.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics/{customMetricId}", + // "request": { + // "$ref": "CustomMetric" + // }, + // "response": { + // "$ref": "CustomMetric" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.customMetrics.update": + +type ManagementCustomMetricsUpdateCall struct { + s *Service + accountId string + webPropertyId string + customMetricId string + custommetric *CustomMetric + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Updates an existing custom metric. +func (r *ManagementCustomMetricsService) Update(accountId string, webPropertyId string, customMetricId string, custommetric *CustomMetric) *ManagementCustomMetricsUpdateCall { + c := &ManagementCustomMetricsUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customMetricId = customMetricId + c.custommetric = custommetric + return c +} + +// IgnoreCustomDataSourceLinks sets the optional parameter +// "ignoreCustomDataSourceLinks": Force the update and ignore any +// warnings related to the custom metric being linked to a custom data +// source / data set. +func (c *ManagementCustomMetricsUpdateCall) IgnoreCustomDataSourceLinks(ignoreCustomDataSourceLinks bool) *ManagementCustomMetricsUpdateCall { + c.opt_["ignoreCustomDataSourceLinks"] = ignoreCustomDataSourceLinks + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementCustomMetricsUpdateCall) Fields(s ...googleapi.Field) *ManagementCustomMetricsUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementCustomMetricsUpdateCall) Context(ctx context.Context) *ManagementCustomMetricsUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementCustomMetricsUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.custommetric) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["ignoreCustomDataSourceLinks"]; ok { + params.Set("ignoreCustomDataSourceLinks", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics/{customMetricId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "customMetricId": c.customMetricId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.customMetrics.update" call. +// Exactly one of *CustomMetric or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *CustomMetric.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementCustomMetricsUpdateCall) Do() (*CustomMetric, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &CustomMetric{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing custom metric.", + // "httpMethod": "PUT", + // "id": "analytics.management.customMetrics.update", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "customMetricId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the custom metric to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "customMetricId": { + // "description": "Custom metric ID for the custom metric to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ignoreCustomDataSourceLinks": { + // "default": "false", + // "description": "Force the update and ignore any warnings related to the custom metric being linked to a custom data source / data set.", + // "location": "query", + // "type": "boolean" + // }, + // "webPropertyId": { + // "description": "Web property ID for the custom metric to update.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customMetrics/{customMetricId}", + // "request": { + // "$ref": "CustomMetric" + // }, + // "response": { + // "$ref": "CustomMetric" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.experiments.delete": + +type ManagementExperimentsDeleteCall struct { + s *Service + accountId string + webPropertyId string + profileId string + experimentId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Delete: Delete an experiment. +func (r *ManagementExperimentsService) Delete(accountId string, webPropertyId string, profileId string, experimentId string) *ManagementExperimentsDeleteCall { + c := &ManagementExperimentsDeleteCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.experimentId = experimentId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementExperimentsDeleteCall) Fields(s ...googleapi.Field) *ManagementExperimentsDeleteCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementExperimentsDeleteCall) Context(ctx context.Context) *ManagementExperimentsDeleteCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementExperimentsDeleteCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "experimentId": c.experimentId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.experiments.delete" call. +func (c *ManagementExperimentsDeleteCall) Do() error { + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Delete an experiment.", + // "httpMethod": "DELETE", + // "id": "analytics.management.experiments.delete", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "experimentId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to which the experiment belongs", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "experimentId": { + // "description": "ID of the experiment to delete", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to which the experiment belongs", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to which the experiment belongs", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}", + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.experiments.get": + +type ManagementExperimentsGetCall struct { + s *Service + accountId string + webPropertyId string + profileId string + experimentId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Returns an experiment to which the user has access. +func (r *ManagementExperimentsService) Get(accountId string, webPropertyId string, profileId string, experimentId string) *ManagementExperimentsGetCall { + c := &ManagementExperimentsGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.experimentId = experimentId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementExperimentsGetCall) Fields(s ...googleapi.Field) *ManagementExperimentsGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementExperimentsGetCall) IfNoneMatch(entityTag string) *ManagementExperimentsGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementExperimentsGetCall) Context(ctx context.Context) *ManagementExperimentsGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementExperimentsGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "experimentId": c.experimentId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.experiments.get" call. +// Exactly one of *Experiment or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Experiment.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementExperimentsGetCall) Do() (*Experiment, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Experiment{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns an experiment to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.experiments.get", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "experimentId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve the experiment for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "experimentId": { + // "description": "Experiment ID to retrieve the experiment for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to retrieve the experiment for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve the experiment for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}", + // "response": { + // "$ref": "Experiment" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.experiments.insert": + +type ManagementExperimentsInsertCall struct { + s *Service + accountId string + webPropertyId string + profileId string + experiment *Experiment + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Create a new experiment. +func (r *ManagementExperimentsService) Insert(accountId string, webPropertyId string, profileId string, experiment *Experiment) *ManagementExperimentsInsertCall { + c := &ManagementExperimentsInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.experiment = experiment + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementExperimentsInsertCall) Fields(s ...googleapi.Field) *ManagementExperimentsInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementExperimentsInsertCall) Context(ctx context.Context) *ManagementExperimentsInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementExperimentsInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.experiment) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.experiments.insert" call. +// Exactly one of *Experiment or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Experiment.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementExperimentsInsertCall) Do() (*Experiment, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Experiment{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Create a new experiment.", + // "httpMethod": "POST", + // "id": "analytics.management.experiments.insert", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to create the experiment for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to create the experiment for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to create the experiment for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments", + // "request": { + // "$ref": "Experiment" + // }, + // "response": { + // "$ref": "Experiment" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.experiments.list": + +type ManagementExperimentsListCall struct { + s *Service + accountId string + webPropertyId string + profileId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists experiments to which the user has access. +func (r *ManagementExperimentsService) List(accountId string, webPropertyId string, profileId string) *ManagementExperimentsListCall { + c := &ManagementExperimentsListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of experiments to include in this response. +func (c *ManagementExperimentsListCall) MaxResults(maxResults int64) *ManagementExperimentsListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first experiment to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementExperimentsListCall) StartIndex(startIndex int64) *ManagementExperimentsListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementExperimentsListCall) Fields(s ...googleapi.Field) *ManagementExperimentsListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementExperimentsListCall) IfNoneMatch(entityTag string) *ManagementExperimentsListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementExperimentsListCall) Context(ctx context.Context) *ManagementExperimentsListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementExperimentsListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.experiments.list" call. +// Exactly one of *Experiments or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Experiments.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementExperimentsListCall) Do() (*Experiments, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Experiments{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists experiments to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.experiments.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve experiments for.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of experiments to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "profileId": { + // "description": "View (Profile) ID to retrieve experiments for.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "start-index": { + // "description": "An index of the first experiment to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve experiments for.", + // "location": "path", + // "pattern": "UA-(\\d+)-(\\d+)", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments", + // "response": { + // "$ref": "Experiments" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.experiments.patch": + +type ManagementExperimentsPatchCall struct { + s *Service + accountId string + webPropertyId string + profileId string + experimentId string + experiment *Experiment + opt_ map[string]interface{} + ctx_ context.Context +} + +// Patch: Update an existing experiment. This method supports patch +// semantics. +func (r *ManagementExperimentsService) Patch(accountId string, webPropertyId string, profileId string, experimentId string, experiment *Experiment) *ManagementExperimentsPatchCall { + c := &ManagementExperimentsPatchCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.experimentId = experimentId + c.experiment = experiment + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementExperimentsPatchCall) Fields(s ...googleapi.Field) *ManagementExperimentsPatchCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementExperimentsPatchCall) Context(ctx context.Context) *ManagementExperimentsPatchCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementExperimentsPatchCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.experiment) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "experimentId": c.experimentId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.experiments.patch" call. +// Exactly one of *Experiment or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Experiment.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementExperimentsPatchCall) Do() (*Experiment, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Experiment{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Update an existing experiment. This method supports patch semantics.", + // "httpMethod": "PATCH", + // "id": "analytics.management.experiments.patch", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "experimentId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID of the experiment to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "experimentId": { + // "description": "Experiment ID of the experiment to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID of the experiment to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID of the experiment to update.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}", + // "request": { + // "$ref": "Experiment" + // }, + // "response": { + // "$ref": "Experiment" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.experiments.update": + +type ManagementExperimentsUpdateCall struct { + s *Service + accountId string + webPropertyId string + profileId string + experimentId string + experiment *Experiment + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Update an existing experiment. +func (r *ManagementExperimentsService) Update(accountId string, webPropertyId string, profileId string, experimentId string, experiment *Experiment) *ManagementExperimentsUpdateCall { + c := &ManagementExperimentsUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.experimentId = experimentId + c.experiment = experiment + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementExperimentsUpdateCall) Fields(s ...googleapi.Field) *ManagementExperimentsUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementExperimentsUpdateCall) Context(ctx context.Context) *ManagementExperimentsUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementExperimentsUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.experiment) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "experimentId": c.experimentId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.experiments.update" call. +// Exactly one of *Experiment or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Experiment.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementExperimentsUpdateCall) Do() (*Experiment, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Experiment{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Update an existing experiment.", + // "httpMethod": "PUT", + // "id": "analytics.management.experiments.update", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "experimentId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID of the experiment to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "experimentId": { + // "description": "Experiment ID of the experiment to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID of the experiment to update.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID of the experiment to update.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/experiments/{experimentId}", + // "request": { + // "$ref": "Experiment" + // }, + // "response": { + // "$ref": "Experiment" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.filters.delete": + +type ManagementFiltersDeleteCall struct { + s *Service + accountId string + filterId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Delete: Delete a filter. +func (r *ManagementFiltersService) Delete(accountId string, filterId string) *ManagementFiltersDeleteCall { + c := &ManagementFiltersDeleteCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.filterId = filterId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementFiltersDeleteCall) Fields(s ...googleapi.Field) *ManagementFiltersDeleteCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementFiltersDeleteCall) Context(ctx context.Context) *ManagementFiltersDeleteCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementFiltersDeleteCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/filters/{filterId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "filterId": c.filterId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.filters.delete" call. +// Exactly one of *Filter or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Filter.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementFiltersDeleteCall) Do() (*Filter, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Filter{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Delete a filter.", + // "httpMethod": "DELETE", + // "id": "analytics.management.filters.delete", + // "parameterOrder": [ + // "accountId", + // "filterId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to delete the filter for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "filterId": { + // "description": "ID of the filter to be deleted.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/filters/{filterId}", + // "response": { + // "$ref": "Filter" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.filters.get": + +type ManagementFiltersGetCall struct { + s *Service + accountId string + filterId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Returns a filters to which the user has access. +func (r *ManagementFiltersService) Get(accountId string, filterId string) *ManagementFiltersGetCall { + c := &ManagementFiltersGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.filterId = filterId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementFiltersGetCall) Fields(s ...googleapi.Field) *ManagementFiltersGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementFiltersGetCall) IfNoneMatch(entityTag string) *ManagementFiltersGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementFiltersGetCall) Context(ctx context.Context) *ManagementFiltersGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementFiltersGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/filters/{filterId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "filterId": c.filterId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.filters.get" call. +// Exactly one of *Filter or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Filter.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementFiltersGetCall) Do() (*Filter, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Filter{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns a filters to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.filters.get", + // "parameterOrder": [ + // "accountId", + // "filterId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve filters for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "filterId": { + // "description": "Filter ID to retrieve filters for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/filters/{filterId}", + // "response": { + // "$ref": "Filter" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.filters.insert": + +type ManagementFiltersInsertCall struct { + s *Service + accountId string + filter *Filter + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Create a new filter. +func (r *ManagementFiltersService) Insert(accountId string, filter *Filter) *ManagementFiltersInsertCall { + c := &ManagementFiltersInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.filter = filter + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementFiltersInsertCall) Fields(s ...googleapi.Field) *ManagementFiltersInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementFiltersInsertCall) Context(ctx context.Context) *ManagementFiltersInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementFiltersInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.filter) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/filters") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.filters.insert" call. +// Exactly one of *Filter or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Filter.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementFiltersInsertCall) Do() (*Filter, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Filter{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Create a new filter.", + // "httpMethod": "POST", + // "id": "analytics.management.filters.insert", + // "parameterOrder": [ + // "accountId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to create filter for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/filters", + // "request": { + // "$ref": "Filter" + // }, + // "response": { + // "$ref": "Filter" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.filters.list": + +type ManagementFiltersListCall struct { + s *Service + accountId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists all filters for an account +func (r *ManagementFiltersService) List(accountId string) *ManagementFiltersListCall { + c := &ManagementFiltersListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of filters to include in this response. +func (c *ManagementFiltersListCall) MaxResults(maxResults int64) *ManagementFiltersListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first entity to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementFiltersListCall) StartIndex(startIndex int64) *ManagementFiltersListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementFiltersListCall) Fields(s ...googleapi.Field) *ManagementFiltersListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementFiltersListCall) IfNoneMatch(entityTag string) *ManagementFiltersListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementFiltersListCall) Context(ctx context.Context) *ManagementFiltersListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementFiltersListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/filters") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.filters.list" call. +// Exactly one of *Filters or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Filters.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementFiltersListCall) Do() (*Filters, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Filters{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists all filters for an account", + // "httpMethod": "GET", + // "id": "analytics.management.filters.list", + // "parameterOrder": [ + // "accountId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve filters for.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of filters to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // } + // }, + // "path": "management/accounts/{accountId}/filters", + // "response": { + // "$ref": "Filters" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.filters.patch": + +type ManagementFiltersPatchCall struct { + s *Service + accountId string + filterId string + filter *Filter + opt_ map[string]interface{} + ctx_ context.Context +} + +// Patch: Updates an existing filter. This method supports patch +// semantics. +func (r *ManagementFiltersService) Patch(accountId string, filterId string, filter *Filter) *ManagementFiltersPatchCall { + c := &ManagementFiltersPatchCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.filterId = filterId + c.filter = filter + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementFiltersPatchCall) Fields(s ...googleapi.Field) *ManagementFiltersPatchCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementFiltersPatchCall) Context(ctx context.Context) *ManagementFiltersPatchCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementFiltersPatchCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.filter) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/filters/{filterId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "filterId": c.filterId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.filters.patch" call. +// Exactly one of *Filter or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Filter.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementFiltersPatchCall) Do() (*Filter, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Filter{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing filter. This method supports patch semantics.", + // "httpMethod": "PATCH", + // "id": "analytics.management.filters.patch", + // "parameterOrder": [ + // "accountId", + // "filterId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to which the filter belongs.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "filterId": { + // "description": "ID of the filter to be updated.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/filters/{filterId}", + // "request": { + // "$ref": "Filter" + // }, + // "response": { + // "$ref": "Filter" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.filters.update": + +type ManagementFiltersUpdateCall struct { + s *Service + accountId string + filterId string + filter *Filter + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Updates an existing filter. +func (r *ManagementFiltersService) Update(accountId string, filterId string, filter *Filter) *ManagementFiltersUpdateCall { + c := &ManagementFiltersUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.filterId = filterId + c.filter = filter + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementFiltersUpdateCall) Fields(s ...googleapi.Field) *ManagementFiltersUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementFiltersUpdateCall) Context(ctx context.Context) *ManagementFiltersUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementFiltersUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.filter) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/filters/{filterId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "filterId": c.filterId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.filters.update" call. +// Exactly one of *Filter or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Filter.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementFiltersUpdateCall) Do() (*Filter, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Filter{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing filter.", + // "httpMethod": "PUT", + // "id": "analytics.management.filters.update", + // "parameterOrder": [ + // "accountId", + // "filterId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to which the filter belongs.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "filterId": { + // "description": "ID of the filter to be updated.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/filters/{filterId}", + // "request": { + // "$ref": "Filter" + // }, + // "response": { + // "$ref": "Filter" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.goals.get": + +type ManagementGoalsGetCall struct { + s *Service + accountId string + webPropertyId string + profileId string + goalId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Gets a goal to which the user has access. +func (r *ManagementGoalsService) Get(accountId string, webPropertyId string, profileId string, goalId string) *ManagementGoalsGetCall { + c := &ManagementGoalsGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.goalId = goalId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementGoalsGetCall) Fields(s ...googleapi.Field) *ManagementGoalsGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementGoalsGetCall) IfNoneMatch(entityTag string) *ManagementGoalsGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementGoalsGetCall) Context(ctx context.Context) *ManagementGoalsGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementGoalsGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals/{goalId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "goalId": c.goalId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.goals.get" call. +// Exactly one of *Goal or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Goal.ServerResponse.Header or (if a response was returned at all) in +// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check +// whether the returned error was because http.StatusNotModified was +// returned. +func (c *ManagementGoalsGetCall) Do() (*Goal, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Goal{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Gets a goal to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.goals.get", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "goalId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve the goal for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "goalId": { + // "description": "Goal ID to retrieve the goal for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to retrieve the goal for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve the goal for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals/{goalId}", + // "response": { + // "$ref": "Goal" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.goals.insert": + +type ManagementGoalsInsertCall struct { + s *Service + accountId string + webPropertyId string + profileId string + goal *Goal + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Create a new goal. +func (r *ManagementGoalsService) Insert(accountId string, webPropertyId string, profileId string, goal *Goal) *ManagementGoalsInsertCall { + c := &ManagementGoalsInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.goal = goal + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementGoalsInsertCall) Fields(s ...googleapi.Field) *ManagementGoalsInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementGoalsInsertCall) Context(ctx context.Context) *ManagementGoalsInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementGoalsInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.goal) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.goals.insert" call. +// Exactly one of *Goal or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Goal.ServerResponse.Header or (if a response was returned at all) in +// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check +// whether the returned error was because http.StatusNotModified was +// returned. +func (c *ManagementGoalsInsertCall) Do() (*Goal, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Goal{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Create a new goal.", + // "httpMethod": "POST", + // "id": "analytics.management.goals.insert", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to create the goal for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to create the goal for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to create the goal for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals", + // "request": { + // "$ref": "Goal" + // }, + // "response": { + // "$ref": "Goal" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.goals.list": + +type ManagementGoalsListCall struct { + s *Service + accountId string + webPropertyId string + profileId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists goals to which the user has access. +func (r *ManagementGoalsService) List(accountId string, webPropertyId string, profileId string) *ManagementGoalsListCall { + c := &ManagementGoalsListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of goals to include in this response. +func (c *ManagementGoalsListCall) MaxResults(maxResults int64) *ManagementGoalsListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first goal to retrieve. Use this parameter as a pagination mechanism +// along with the max-results parameter. +func (c *ManagementGoalsListCall) StartIndex(startIndex int64) *ManagementGoalsListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementGoalsListCall) Fields(s ...googleapi.Field) *ManagementGoalsListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementGoalsListCall) IfNoneMatch(entityTag string) *ManagementGoalsListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementGoalsListCall) Context(ctx context.Context) *ManagementGoalsListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementGoalsListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.goals.list" call. +// Exactly one of *Goals or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Goals.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementGoalsListCall) Do() (*Goals, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Goals{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists goals to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.goals.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve goals for. Can either be a specific account ID or '~all', which refers to all the accounts that user has access to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of goals to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "profileId": { + // "description": "View (Profile) ID to retrieve goals for. Can either be a specific view (profile) ID or '~all', which refers to all the views (profiles) that user has access to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "start-index": { + // "description": "An index of the first goal to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve goals for. Can either be a specific web property ID or '~all', which refers to all the web properties that user has access to.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals", + // "response": { + // "$ref": "Goals" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.goals.patch": + +type ManagementGoalsPatchCall struct { + s *Service + accountId string + webPropertyId string + profileId string + goalId string + goal *Goal + opt_ map[string]interface{} + ctx_ context.Context +} + +// Patch: Updates an existing view (profile). This method supports patch +// semantics. +func (r *ManagementGoalsService) Patch(accountId string, webPropertyId string, profileId string, goalId string, goal *Goal) *ManagementGoalsPatchCall { + c := &ManagementGoalsPatchCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.goalId = goalId + c.goal = goal + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementGoalsPatchCall) Fields(s ...googleapi.Field) *ManagementGoalsPatchCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementGoalsPatchCall) Context(ctx context.Context) *ManagementGoalsPatchCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementGoalsPatchCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.goal) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals/{goalId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "goalId": c.goalId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.goals.patch" call. +// Exactly one of *Goal or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Goal.ServerResponse.Header or (if a response was returned at all) in +// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check +// whether the returned error was because http.StatusNotModified was +// returned. +func (c *ManagementGoalsPatchCall) Do() (*Goal, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Goal{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing view (profile). This method supports patch semantics.", + // "httpMethod": "PATCH", + // "id": "analytics.management.goals.patch", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "goalId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to update the goal.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "goalId": { + // "description": "Index of the goal to be updated.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to update the goal.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to update the goal.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals/{goalId}", + // "request": { + // "$ref": "Goal" + // }, + // "response": { + // "$ref": "Goal" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.goals.update": + +type ManagementGoalsUpdateCall struct { + s *Service + accountId string + webPropertyId string + profileId string + goalId string + goal *Goal + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Updates an existing view (profile). +func (r *ManagementGoalsService) Update(accountId string, webPropertyId string, profileId string, goalId string, goal *Goal) *ManagementGoalsUpdateCall { + c := &ManagementGoalsUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.goalId = goalId + c.goal = goal + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementGoalsUpdateCall) Fields(s ...googleapi.Field) *ManagementGoalsUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementGoalsUpdateCall) Context(ctx context.Context) *ManagementGoalsUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementGoalsUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.goal) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals/{goalId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "goalId": c.goalId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.goals.update" call. +// Exactly one of *Goal or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Goal.ServerResponse.Header or (if a response was returned at all) in +// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check +// whether the returned error was because http.StatusNotModified was +// returned. +func (c *ManagementGoalsUpdateCall) Do() (*Goal, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Goal{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing view (profile).", + // "httpMethod": "PUT", + // "id": "analytics.management.goals.update", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "goalId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to update the goal.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "goalId": { + // "description": "Index of the goal to be updated.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to update the goal.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to update the goal.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals/{goalId}", + // "request": { + // "$ref": "Goal" + // }, + // "response": { + // "$ref": "Goal" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.profileFilterLinks.delete": + +type ManagementProfileFilterLinksDeleteCall struct { + s *Service + accountId string + webPropertyId string + profileId string + linkId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Delete: Delete a profile filter link. +func (r *ManagementProfileFilterLinksService) Delete(accountId string, webPropertyId string, profileId string, linkId string) *ManagementProfileFilterLinksDeleteCall { + c := &ManagementProfileFilterLinksDeleteCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.linkId = linkId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfileFilterLinksDeleteCall) Fields(s ...googleapi.Field) *ManagementProfileFilterLinksDeleteCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfileFilterLinksDeleteCall) Context(ctx context.Context) *ManagementProfileFilterLinksDeleteCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfileFilterLinksDeleteCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "linkId": c.linkId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profileFilterLinks.delete" call. +func (c *ManagementProfileFilterLinksDeleteCall) Do() error { + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Delete a profile filter link.", + // "httpMethod": "DELETE", + // "id": "analytics.management.profileFilterLinks.delete", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "linkId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to which the profile filter link belongs.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "linkId": { + // "description": "ID of the profile filter link to delete.", + // "location": "path", + // "pattern": "\\d+:\\d+", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "Profile ID to which the filter link belongs.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property Id to which the profile filter link belongs.", + // "location": "path", + // "pattern": "UA-(\\d+)-(\\d+)", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}", + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.profileFilterLinks.get": + +type ManagementProfileFilterLinksGetCall struct { + s *Service + accountId string + webPropertyId string + profileId string + linkId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Returns a single profile filter link. +func (r *ManagementProfileFilterLinksService) Get(accountId string, webPropertyId string, profileId string, linkId string) *ManagementProfileFilterLinksGetCall { + c := &ManagementProfileFilterLinksGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.linkId = linkId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfileFilterLinksGetCall) Fields(s ...googleapi.Field) *ManagementProfileFilterLinksGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementProfileFilterLinksGetCall) IfNoneMatch(entityTag string) *ManagementProfileFilterLinksGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfileFilterLinksGetCall) Context(ctx context.Context) *ManagementProfileFilterLinksGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfileFilterLinksGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "linkId": c.linkId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profileFilterLinks.get" call. +// Exactly one of *ProfileFilterLink or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ProfileFilterLink.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementProfileFilterLinksGetCall) Do() (*ProfileFilterLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ProfileFilterLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns a single profile filter link.", + // "httpMethod": "GET", + // "id": "analytics.management.profileFilterLinks.get", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "linkId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve profile filter link for.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "linkId": { + // "description": "ID of the profile filter link.", + // "location": "path", + // "pattern": "\\d+:\\d+", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "Profile ID to retrieve filter link for.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property Id to retrieve profile filter link for.", + // "location": "path", + // "pattern": "UA-(\\d+)-(\\d+)", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}", + // "response": { + // "$ref": "ProfileFilterLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.profileFilterLinks.insert": + +type ManagementProfileFilterLinksInsertCall struct { + s *Service + accountId string + webPropertyId string + profileId string + profilefilterlink *ProfileFilterLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Create a new profile filter link. +func (r *ManagementProfileFilterLinksService) Insert(accountId string, webPropertyId string, profileId string, profilefilterlink *ProfileFilterLink) *ManagementProfileFilterLinksInsertCall { + c := &ManagementProfileFilterLinksInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.profilefilterlink = profilefilterlink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfileFilterLinksInsertCall) Fields(s ...googleapi.Field) *ManagementProfileFilterLinksInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfileFilterLinksInsertCall) Context(ctx context.Context) *ManagementProfileFilterLinksInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfileFilterLinksInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.profilefilterlink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profileFilterLinks.insert" call. +// Exactly one of *ProfileFilterLink or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ProfileFilterLink.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementProfileFilterLinksInsertCall) Do() (*ProfileFilterLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ProfileFilterLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Create a new profile filter link.", + // "httpMethod": "POST", + // "id": "analytics.management.profileFilterLinks.insert", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to create profile filter link for.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "Profile ID to create filter link for.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property Id to create profile filter link for.", + // "location": "path", + // "pattern": "UA-(\\d+)-(\\d+)", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks", + // "request": { + // "$ref": "ProfileFilterLink" + // }, + // "response": { + // "$ref": "ProfileFilterLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.profileFilterLinks.list": + +type ManagementProfileFilterLinksListCall struct { + s *Service + accountId string + webPropertyId string + profileId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists all profile filter links for a profile. +func (r *ManagementProfileFilterLinksService) List(accountId string, webPropertyId string, profileId string) *ManagementProfileFilterLinksListCall { + c := &ManagementProfileFilterLinksListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of profile filter links to include in this response. +func (c *ManagementProfileFilterLinksListCall) MaxResults(maxResults int64) *ManagementProfileFilterLinksListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first entity to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementProfileFilterLinksListCall) StartIndex(startIndex int64) *ManagementProfileFilterLinksListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfileFilterLinksListCall) Fields(s ...googleapi.Field) *ManagementProfileFilterLinksListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementProfileFilterLinksListCall) IfNoneMatch(entityTag string) *ManagementProfileFilterLinksListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfileFilterLinksListCall) Context(ctx context.Context) *ManagementProfileFilterLinksListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfileFilterLinksListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profileFilterLinks.list" call. +// Exactly one of *ProfileFilterLinks or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ProfileFilterLinks.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementProfileFilterLinksListCall) Do() (*ProfileFilterLinks, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ProfileFilterLinks{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists all profile filter links for a profile.", + // "httpMethod": "GET", + // "id": "analytics.management.profileFilterLinks.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve profile filter links for.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of profile filter links to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "profileId": { + // "description": "Profile ID to retrieve filter links for. Can either be a specific profile ID or '~all', which refers to all the profiles that user has access to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "start-index": { + // "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web property Id for profile filter links for. Can either be a specific web property ID or '~all', which refers to all the web properties that user has access to.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks", + // "response": { + // "$ref": "ProfileFilterLinks" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.profileFilterLinks.patch": + +type ManagementProfileFilterLinksPatchCall struct { + s *Service + accountId string + webPropertyId string + profileId string + linkId string + profilefilterlink *ProfileFilterLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Patch: Update an existing profile filter link. This method supports +// patch semantics. +func (r *ManagementProfileFilterLinksService) Patch(accountId string, webPropertyId string, profileId string, linkId string, profilefilterlink *ProfileFilterLink) *ManagementProfileFilterLinksPatchCall { + c := &ManagementProfileFilterLinksPatchCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.linkId = linkId + c.profilefilterlink = profilefilterlink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfileFilterLinksPatchCall) Fields(s ...googleapi.Field) *ManagementProfileFilterLinksPatchCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfileFilterLinksPatchCall) Context(ctx context.Context) *ManagementProfileFilterLinksPatchCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfileFilterLinksPatchCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.profilefilterlink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "linkId": c.linkId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profileFilterLinks.patch" call. +// Exactly one of *ProfileFilterLink or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ProfileFilterLink.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementProfileFilterLinksPatchCall) Do() (*ProfileFilterLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ProfileFilterLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Update an existing profile filter link. This method supports patch semantics.", + // "httpMethod": "PATCH", + // "id": "analytics.management.profileFilterLinks.patch", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "linkId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to which profile filter link belongs.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "linkId": { + // "description": "ID of the profile filter link to be updated.", + // "location": "path", + // "pattern": "\\d+:\\d+", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "Profile ID to which filter link belongs", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property Id to which profile filter link belongs", + // "location": "path", + // "pattern": "UA-(\\d+)-(\\d+)", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}", + // "request": { + // "$ref": "ProfileFilterLink" + // }, + // "response": { + // "$ref": "ProfileFilterLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.profileFilterLinks.update": + +type ManagementProfileFilterLinksUpdateCall struct { + s *Service + accountId string + webPropertyId string + profileId string + linkId string + profilefilterlink *ProfileFilterLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Update an existing profile filter link. +func (r *ManagementProfileFilterLinksService) Update(accountId string, webPropertyId string, profileId string, linkId string, profilefilterlink *ProfileFilterLink) *ManagementProfileFilterLinksUpdateCall { + c := &ManagementProfileFilterLinksUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.linkId = linkId + c.profilefilterlink = profilefilterlink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfileFilterLinksUpdateCall) Fields(s ...googleapi.Field) *ManagementProfileFilterLinksUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfileFilterLinksUpdateCall) Context(ctx context.Context) *ManagementProfileFilterLinksUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfileFilterLinksUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.profilefilterlink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "linkId": c.linkId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profileFilterLinks.update" call. +// Exactly one of *ProfileFilterLink or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ProfileFilterLink.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementProfileFilterLinksUpdateCall) Do() (*ProfileFilterLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ProfileFilterLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Update an existing profile filter link.", + // "httpMethod": "PUT", + // "id": "analytics.management.profileFilterLinks.update", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "linkId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to which profile filter link belongs.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "linkId": { + // "description": "ID of the profile filter link to be updated.", + // "location": "path", + // "pattern": "\\d+:\\d+", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "Profile ID to which filter link belongs", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property Id to which profile filter link belongs", + // "location": "path", + // "pattern": "UA-(\\d+)-(\\d+)", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/profileFilterLinks/{linkId}", + // "request": { + // "$ref": "ProfileFilterLink" + // }, + // "response": { + // "$ref": "ProfileFilterLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.profileUserLinks.delete": + +type ManagementProfileUserLinksDeleteCall struct { + s *Service + accountId string + webPropertyId string + profileId string + linkId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Delete: Removes a user from the given view (profile). +func (r *ManagementProfileUserLinksService) Delete(accountId string, webPropertyId string, profileId string, linkId string) *ManagementProfileUserLinksDeleteCall { + c := &ManagementProfileUserLinksDeleteCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.linkId = linkId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfileUserLinksDeleteCall) Fields(s ...googleapi.Field) *ManagementProfileUserLinksDeleteCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfileUserLinksDeleteCall) Context(ctx context.Context) *ManagementProfileUserLinksDeleteCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfileUserLinksDeleteCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks/{linkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "linkId": c.linkId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profileUserLinks.delete" call. +func (c *ManagementProfileUserLinksDeleteCall) Do() error { + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Removes a user from the given view (profile).", + // "httpMethod": "DELETE", + // "id": "analytics.management.profileUserLinks.delete", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "linkId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to delete the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "linkId": { + // "description": "Link ID to delete the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to delete the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web Property ID to delete the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks/{linkId}", + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users" + // ] + // } + +} + +// method id "analytics.management.profileUserLinks.insert": + +type ManagementProfileUserLinksInsertCall struct { + s *Service + accountId string + webPropertyId string + profileId string + entityuserlink *EntityUserLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Adds a new user to the given view (profile). +func (r *ManagementProfileUserLinksService) Insert(accountId string, webPropertyId string, profileId string, entityuserlink *EntityUserLink) *ManagementProfileUserLinksInsertCall { + c := &ManagementProfileUserLinksInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.entityuserlink = entityuserlink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfileUserLinksInsertCall) Fields(s ...googleapi.Field) *ManagementProfileUserLinksInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfileUserLinksInsertCall) Context(ctx context.Context) *ManagementProfileUserLinksInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfileUserLinksInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.entityuserlink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profileUserLinks.insert" call. +// Exactly one of *EntityUserLink or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *EntityUserLink.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementProfileUserLinksInsertCall) Do() (*EntityUserLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityUserLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Adds a new user to the given view (profile).", + // "httpMethod": "POST", + // "id": "analytics.management.profileUserLinks.insert", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to create the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to create the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web Property ID to create the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks", + // "request": { + // "$ref": "EntityUserLink" + // }, + // "response": { + // "$ref": "EntityUserLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users" + // ] + // } + +} + +// method id "analytics.management.profileUserLinks.list": + +type ManagementProfileUserLinksListCall struct { + s *Service + accountId string + webPropertyId string + profileId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists profile-user links for a given view (profile). +func (r *ManagementProfileUserLinksService) List(accountId string, webPropertyId string, profileId string) *ManagementProfileUserLinksListCall { + c := &ManagementProfileUserLinksListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of profile-user links to include in this response. +func (c *ManagementProfileUserLinksListCall) MaxResults(maxResults int64) *ManagementProfileUserLinksListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first profile-user link to retrieve. Use this parameter as a +// pagination mechanism along with the max-results parameter. +func (c *ManagementProfileUserLinksListCall) StartIndex(startIndex int64) *ManagementProfileUserLinksListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfileUserLinksListCall) Fields(s ...googleapi.Field) *ManagementProfileUserLinksListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementProfileUserLinksListCall) IfNoneMatch(entityTag string) *ManagementProfileUserLinksListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfileUserLinksListCall) Context(ctx context.Context) *ManagementProfileUserLinksListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfileUserLinksListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profileUserLinks.list" call. +// Exactly one of *EntityUserLinks or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *EntityUserLinks.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementProfileUserLinksListCall) Do() (*EntityUserLinks, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityUserLinks{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists profile-user links for a given view (profile).", + // "httpMethod": "GET", + // "id": "analytics.management.profileUserLinks.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID which the given view (profile) belongs to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of profile-user links to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "profileId": { + // "description": "View (Profile) ID to retrieve the profile-user links for. Can either be a specific profile ID or '~all', which refers to all the profiles that user has access to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "start-index": { + // "description": "An index of the first profile-user link to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web Property ID which the given view (profile) belongs to. Can either be a specific web property ID or '~all', which refers to all the web properties that user has access to.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks", + // "response": { + // "$ref": "EntityUserLinks" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users", + // "https://www.googleapis.com/auth/analytics.manage.users.readonly" + // ] + // } + +} + +// method id "analytics.management.profileUserLinks.update": + +type ManagementProfileUserLinksUpdateCall struct { + s *Service + accountId string + webPropertyId string + profileId string + linkId string + entityuserlink *EntityUserLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Updates permissions for an existing user on the given view +// (profile). +func (r *ManagementProfileUserLinksService) Update(accountId string, webPropertyId string, profileId string, linkId string, entityuserlink *EntityUserLink) *ManagementProfileUserLinksUpdateCall { + c := &ManagementProfileUserLinksUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.linkId = linkId + c.entityuserlink = entityuserlink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfileUserLinksUpdateCall) Fields(s ...googleapi.Field) *ManagementProfileUserLinksUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfileUserLinksUpdateCall) Context(ctx context.Context) *ManagementProfileUserLinksUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfileUserLinksUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.entityuserlink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks/{linkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "linkId": c.linkId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profileUserLinks.update" call. +// Exactly one of *EntityUserLink or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *EntityUserLink.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementProfileUserLinksUpdateCall) Do() (*EntityUserLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityUserLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates permissions for an existing user on the given view (profile).", + // "httpMethod": "PUT", + // "id": "analytics.management.profileUserLinks.update", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "linkId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to update the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "linkId": { + // "description": "Link ID to update the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile ID) to update the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web Property ID to update the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/entityUserLinks/{linkId}", + // "request": { + // "$ref": "EntityUserLink" + // }, + // "response": { + // "$ref": "EntityUserLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users" + // ] + // } + +} + +// method id "analytics.management.profiles.delete": + +type ManagementProfilesDeleteCall struct { + s *Service + accountId string + webPropertyId string + profileId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Delete: Deletes a view (profile). +func (r *ManagementProfilesService) Delete(accountId string, webPropertyId string, profileId string) *ManagementProfilesDeleteCall { + c := &ManagementProfilesDeleteCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfilesDeleteCall) Fields(s ...googleapi.Field) *ManagementProfilesDeleteCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfilesDeleteCall) Context(ctx context.Context) *ManagementProfilesDeleteCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfilesDeleteCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profiles.delete" call. +func (c *ManagementProfilesDeleteCall) Do() error { + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Deletes a view (profile).", + // "httpMethod": "DELETE", + // "id": "analytics.management.profiles.delete", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to delete the view (profile) for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "ID of the view (profile) to be deleted.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to delete the view (profile) for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}", + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.profiles.get": + +type ManagementProfilesGetCall struct { + s *Service + accountId string + webPropertyId string + profileId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Gets a view (profile) to which the user has access. +func (r *ManagementProfilesService) Get(accountId string, webPropertyId string, profileId string) *ManagementProfilesGetCall { + c := &ManagementProfilesGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfilesGetCall) Fields(s ...googleapi.Field) *ManagementProfilesGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementProfilesGetCall) IfNoneMatch(entityTag string) *ManagementProfilesGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfilesGetCall) Context(ctx context.Context) *ManagementProfilesGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfilesGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profiles.get" call. +// Exactly one of *Profile or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Profile.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementProfilesGetCall) Do() (*Profile, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Profile{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Gets a view (profile) to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.profiles.get", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve the goal for.", + // "location": "path", + // "pattern": "[0-9]+", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to retrieve the goal for.", + // "location": "path", + // "pattern": "[0-9]+", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve the goal for.", + // "location": "path", + // "pattern": "UA-[0-9]+-[0-9]+", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}", + // "response": { + // "$ref": "Profile" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.profiles.insert": + +type ManagementProfilesInsertCall struct { + s *Service + accountId string + webPropertyId string + profile *Profile + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Create a new view (profile). +func (r *ManagementProfilesService) Insert(accountId string, webPropertyId string, profile *Profile) *ManagementProfilesInsertCall { + c := &ManagementProfilesInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profile = profile + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfilesInsertCall) Fields(s ...googleapi.Field) *ManagementProfilesInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfilesInsertCall) Context(ctx context.Context) *ManagementProfilesInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfilesInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.profile) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profiles.insert" call. +// Exactly one of *Profile or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Profile.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementProfilesInsertCall) Do() (*Profile, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Profile{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Create a new view (profile).", + // "httpMethod": "POST", + // "id": "analytics.management.profiles.insert", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to create the view (profile) for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to create the view (profile) for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles", + // "request": { + // "$ref": "Profile" + // }, + // "response": { + // "$ref": "Profile" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.profiles.list": + +type ManagementProfilesListCall struct { + s *Service + accountId string + webPropertyId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists views (profiles) to which the user has access. +func (r *ManagementProfilesService) List(accountId string, webPropertyId string) *ManagementProfilesListCall { + c := &ManagementProfilesListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of views (profiles) to include in this response. +func (c *ManagementProfilesListCall) MaxResults(maxResults int64) *ManagementProfilesListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first entity to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementProfilesListCall) StartIndex(startIndex int64) *ManagementProfilesListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfilesListCall) Fields(s ...googleapi.Field) *ManagementProfilesListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementProfilesListCall) IfNoneMatch(entityTag string) *ManagementProfilesListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfilesListCall) Context(ctx context.Context) *ManagementProfilesListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfilesListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profiles.list" call. +// Exactly one of *Profiles or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Profiles.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementProfilesListCall) Do() (*Profiles, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Profiles{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists views (profiles) to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.profiles.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID for the view (profiles) to retrieve. Can either be a specific account ID or '~all', which refers to all the accounts to which the user has access.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of views (profiles) to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web property ID for the views (profiles) to retrieve. Can either be a specific web property ID or '~all', which refers to all the web properties to which the user has access.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles", + // "response": { + // "$ref": "Profiles" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.profiles.patch": + +type ManagementProfilesPatchCall struct { + s *Service + accountId string + webPropertyId string + profileId string + profile *Profile + opt_ map[string]interface{} + ctx_ context.Context +} + +// Patch: Updates an existing view (profile). This method supports patch +// semantics. +func (r *ManagementProfilesService) Patch(accountId string, webPropertyId string, profileId string, profile *Profile) *ManagementProfilesPatchCall { + c := &ManagementProfilesPatchCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.profile = profile + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfilesPatchCall) Fields(s ...googleapi.Field) *ManagementProfilesPatchCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfilesPatchCall) Context(ctx context.Context) *ManagementProfilesPatchCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfilesPatchCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.profile) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profiles.patch" call. +// Exactly one of *Profile or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Profile.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementProfilesPatchCall) Do() (*Profile, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Profile{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing view (profile). This method supports patch semantics.", + // "httpMethod": "PATCH", + // "id": "analytics.management.profiles.patch", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to which the view (profile) belongs", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "ID of the view (profile) to be updated.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to which the view (profile) belongs", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}", + // "request": { + // "$ref": "Profile" + // }, + // "response": { + // "$ref": "Profile" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.profiles.update": + +type ManagementProfilesUpdateCall struct { + s *Service + accountId string + webPropertyId string + profileId string + profile *Profile + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Updates an existing view (profile). +func (r *ManagementProfilesService) Update(accountId string, webPropertyId string, profileId string, profile *Profile) *ManagementProfilesUpdateCall { + c := &ManagementProfilesUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.profile = profile + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementProfilesUpdateCall) Fields(s ...googleapi.Field) *ManagementProfilesUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementProfilesUpdateCall) Context(ctx context.Context) *ManagementProfilesUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementProfilesUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.profile) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.profiles.update" call. +// Exactly one of *Profile or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Profile.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementProfilesUpdateCall) Do() (*Profile, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Profile{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing view (profile).", + // "httpMethod": "PUT", + // "id": "analytics.management.profiles.update", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to which the view (profile) belongs", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "ID of the view (profile) to be updated.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to which the view (profile) belongs", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}", + // "request": { + // "$ref": "Profile" + // }, + // "response": { + // "$ref": "Profile" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.segments.list": + +type ManagementSegmentsListCall struct { + s *Service + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists segments to which the user has access. +func (r *ManagementSegmentsService) List() *ManagementSegmentsListCall { + c := &ManagementSegmentsListCall{s: r.s, opt_: make(map[string]interface{})} + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of segments to include in this response. +func (c *ManagementSegmentsListCall) MaxResults(maxResults int64) *ManagementSegmentsListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first segment to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementSegmentsListCall) StartIndex(startIndex int64) *ManagementSegmentsListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementSegmentsListCall) Fields(s ...googleapi.Field) *ManagementSegmentsListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementSegmentsListCall) IfNoneMatch(entityTag string) *ManagementSegmentsListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementSegmentsListCall) Context(ctx context.Context) *ManagementSegmentsListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementSegmentsListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/segments") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.SetOpaque(req.URL) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.segments.list" call. +// Exactly one of *Segments or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Segments.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementSegmentsListCall) Do() (*Segments, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Segments{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists segments to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.segments.list", + // "parameters": { + // "max-results": { + // "description": "The maximum number of segments to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first segment to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // } + // }, + // "path": "management/segments", + // "response": { + // "$ref": "Segments" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.unsampledReports.get": + +type ManagementUnsampledReportsGetCall struct { + s *Service + accountId string + webPropertyId string + profileId string + unsampledReportId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Returns a single unsampled report. +func (r *ManagementUnsampledReportsService) Get(accountId string, webPropertyId string, profileId string, unsampledReportId string) *ManagementUnsampledReportsGetCall { + c := &ManagementUnsampledReportsGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.unsampledReportId = unsampledReportId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementUnsampledReportsGetCall) Fields(s ...googleapi.Field) *ManagementUnsampledReportsGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementUnsampledReportsGetCall) IfNoneMatch(entityTag string) *ManagementUnsampledReportsGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementUnsampledReportsGetCall) Context(ctx context.Context) *ManagementUnsampledReportsGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementUnsampledReportsGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/unsampledReports/{unsampledReportId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + "unsampledReportId": c.unsampledReportId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.unsampledReports.get" call. +// Exactly one of *UnsampledReport or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *UnsampledReport.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementUnsampledReportsGetCall) Do() (*UnsampledReport, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &UnsampledReport{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns a single unsampled report.", + // "httpMethod": "GET", + // "id": "analytics.management.unsampledReports.get", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId", + // "unsampledReportId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve unsampled report for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to retrieve unsampled report for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "unsampledReportId": { + // "description": "ID of the unsampled report to retrieve.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve unsampled reports for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/unsampledReports/{unsampledReportId}", + // "response": { + // "$ref": "UnsampledReport" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.unsampledReports.insert": + +type ManagementUnsampledReportsInsertCall struct { + s *Service + accountId string + webPropertyId string + profileId string + unsampledreport *UnsampledReport + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Create a new unsampled report. +func (r *ManagementUnsampledReportsService) Insert(accountId string, webPropertyId string, profileId string, unsampledreport *UnsampledReport) *ManagementUnsampledReportsInsertCall { + c := &ManagementUnsampledReportsInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + c.unsampledreport = unsampledreport + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementUnsampledReportsInsertCall) Fields(s ...googleapi.Field) *ManagementUnsampledReportsInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementUnsampledReportsInsertCall) Context(ctx context.Context) *ManagementUnsampledReportsInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementUnsampledReportsInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.unsampledreport) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/unsampledReports") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.unsampledReports.insert" call. +// Exactly one of *UnsampledReport or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *UnsampledReport.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementUnsampledReportsInsertCall) Do() (*UnsampledReport, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &UnsampledReport{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Create a new unsampled report.", + // "httpMethod": "POST", + // "id": "analytics.management.unsampledReports.insert", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to create the unsampled report for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "profileId": { + // "description": "View (Profile) ID to create the unsampled report for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to create the unsampled report for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/unsampledReports", + // "request": { + // "$ref": "UnsampledReport" + // }, + // "response": { + // "$ref": "UnsampledReport" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.unsampledReports.list": + +type ManagementUnsampledReportsListCall struct { + s *Service + accountId string + webPropertyId string + profileId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists unsampled reports to which the user has access. +func (r *ManagementUnsampledReportsService) List(accountId string, webPropertyId string, profileId string) *ManagementUnsampledReportsListCall { + c := &ManagementUnsampledReportsListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.profileId = profileId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of unsampled reports to include in this response. +func (c *ManagementUnsampledReportsListCall) MaxResults(maxResults int64) *ManagementUnsampledReportsListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first unsampled report to retrieve. Use this parameter as a +// pagination mechanism along with the max-results parameter. +func (c *ManagementUnsampledReportsListCall) StartIndex(startIndex int64) *ManagementUnsampledReportsListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementUnsampledReportsListCall) Fields(s ...googleapi.Field) *ManagementUnsampledReportsListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementUnsampledReportsListCall) IfNoneMatch(entityTag string) *ManagementUnsampledReportsListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementUnsampledReportsListCall) Context(ctx context.Context) *ManagementUnsampledReportsListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementUnsampledReportsListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/unsampledReports") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "profileId": c.profileId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.unsampledReports.list" call. +// Exactly one of *UnsampledReports or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *UnsampledReports.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementUnsampledReportsListCall) Do() (*UnsampledReports, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &UnsampledReports{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists unsampled reports to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.unsampledReports.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "profileId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve unsampled reports for. Must be a specific account ID, ~all is not supported.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of unsampled reports to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "profileId": { + // "description": "View (Profile) ID to retrieve unsampled reports for. Must be a specific view (profile) ID, ~all is not supported.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "start-index": { + // "description": "An index of the first unsampled report to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve unsampled reports for. Must be a specific web property ID, ~all is not supported.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/unsampledReports", + // "response": { + // "$ref": "UnsampledReports" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.uploads.deleteUploadData": + +type ManagementUploadsDeleteUploadDataCall struct { + s *Service + accountId string + webPropertyId string + customDataSourceId string + analyticsdataimportdeleteuploaddatarequest *AnalyticsDataimportDeleteUploadDataRequest + opt_ map[string]interface{} + ctx_ context.Context +} + +// DeleteUploadData: Delete data associated with a previous upload. +func (r *ManagementUploadsService) DeleteUploadData(accountId string, webPropertyId string, customDataSourceId string, analyticsdataimportdeleteuploaddatarequest *AnalyticsDataimportDeleteUploadDataRequest) *ManagementUploadsDeleteUploadDataCall { + c := &ManagementUploadsDeleteUploadDataCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customDataSourceId = customDataSourceId + c.analyticsdataimportdeleteuploaddatarequest = analyticsdataimportdeleteuploaddatarequest + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementUploadsDeleteUploadDataCall) Fields(s ...googleapi.Field) *ManagementUploadsDeleteUploadDataCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementUploadsDeleteUploadDataCall) Context(ctx context.Context) *ManagementUploadsDeleteUploadDataCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementUploadsDeleteUploadDataCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.analyticsdataimportdeleteuploaddatarequest) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/deleteUploadData") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "customDataSourceId": c.customDataSourceId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.uploads.deleteUploadData" call. +func (c *ManagementUploadsDeleteUploadDataCall) Do() error { + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Delete data associated with a previous upload.", + // "httpMethod": "POST", + // "id": "analytics.management.uploads.deleteUploadData", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "customDataSourceId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account Id for the uploads to be deleted.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "customDataSourceId": { + // "description": "Custom data source Id for the uploads to be deleted.", + // "location": "path", + // "pattern": ".{22}", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property Id for the uploads to be deleted.", + // "location": "path", + // "pattern": "UA-(\\d+)-(\\d+)", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/deleteUploadData", + // "request": { + // "$ref": "AnalyticsDataimportDeleteUploadDataRequest" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.uploads.get": + +type ManagementUploadsGetCall struct { + s *Service + accountId string + webPropertyId string + customDataSourceId string + uploadId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: List uploads to which the user has access. +func (r *ManagementUploadsService) Get(accountId string, webPropertyId string, customDataSourceId string, uploadId string) *ManagementUploadsGetCall { + c := &ManagementUploadsGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customDataSourceId = customDataSourceId + c.uploadId = uploadId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementUploadsGetCall) Fields(s ...googleapi.Field) *ManagementUploadsGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementUploadsGetCall) IfNoneMatch(entityTag string) *ManagementUploadsGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementUploadsGetCall) Context(ctx context.Context) *ManagementUploadsGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementUploadsGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads/{uploadId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "customDataSourceId": c.customDataSourceId, + "uploadId": c.uploadId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.uploads.get" call. +// Exactly one of *Upload or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Upload.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementUploadsGetCall) Do() (*Upload, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Upload{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "List uploads to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.uploads.get", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "customDataSourceId", + // "uploadId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account Id for the upload to retrieve.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "customDataSourceId": { + // "description": "Custom data source Id for upload to retrieve.", + // "location": "path", + // "pattern": ".{22}", + // "required": true, + // "type": "string" + // }, + // "uploadId": { + // "description": "Upload Id to retrieve.", + // "location": "path", + // "pattern": ".{22}", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property Id for the upload to retrieve.", + // "location": "path", + // "pattern": "UA-(\\d+)-(\\d+)", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads/{uploadId}", + // "response": { + // "$ref": "Upload" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.uploads.list": + +type ManagementUploadsListCall struct { + s *Service + accountId string + webPropertyId string + customDataSourceId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: List uploads to which the user has access. +func (r *ManagementUploadsService) List(accountId string, webPropertyId string, customDataSourceId string) *ManagementUploadsListCall { + c := &ManagementUploadsListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customDataSourceId = customDataSourceId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of uploads to include in this response. +func (c *ManagementUploadsListCall) MaxResults(maxResults int64) *ManagementUploadsListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": A 1-based index +// of the first upload to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementUploadsListCall) StartIndex(startIndex int64) *ManagementUploadsListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementUploadsListCall) Fields(s ...googleapi.Field) *ManagementUploadsListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementUploadsListCall) IfNoneMatch(entityTag string) *ManagementUploadsListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementUploadsListCall) Context(ctx context.Context) *ManagementUploadsListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementUploadsListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "customDataSourceId": c.customDataSourceId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.uploads.list" call. +// Exactly one of *Uploads or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Uploads.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementUploadsListCall) Do() (*Uploads, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Uploads{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "List uploads to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.uploads.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "customDataSourceId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account Id for the uploads to retrieve.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "customDataSourceId": { + // "description": "Custom data source Id for uploads to retrieve.", + // "location": "path", + // "pattern": ".{22}", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of uploads to include in this response.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "start-index": { + // "description": "A 1-based index of the first upload to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web property Id for the uploads to retrieve.", + // "location": "path", + // "pattern": "UA-(\\d+)-(\\d+)", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads", + // "response": { + // "$ref": "Uploads" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.uploads.uploadData": + +type ManagementUploadsUploadDataCall struct { + s *Service + accountId string + webPropertyId string + customDataSourceId string + opt_ map[string]interface{} + media_ io.Reader + resumable_ googleapi.SizeReaderAt + mediaType_ string + protocol_ string + ctx_ context.Context +} + +// UploadData: Upload data for a custom data source. +func (r *ManagementUploadsService) UploadData(accountId string, webPropertyId string, customDataSourceId string) *ManagementUploadsUploadDataCall { + c := &ManagementUploadsUploadDataCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.customDataSourceId = customDataSourceId + return c +} + +// Media specifies the media to upload in a single chunk. +// At most one of Media and ResumableMedia may be set. +func (c *ManagementUploadsUploadDataCall) Media(r io.Reader) *ManagementUploadsUploadDataCall { + c.media_ = r + c.protocol_ = "multipart" + return c +} + +// ResumableMedia specifies the media to upload in chunks and can be canceled with ctx. +// At most one of Media and ResumableMedia may be set. +// mediaType identifies the MIME media type of the upload, such as "image/png". +// If mediaType is "", it will be auto-detected. +// The provided ctx will supersede any context previously provided to +// the Context method. +func (c *ManagementUploadsUploadDataCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *ManagementUploadsUploadDataCall { + c.ctx_ = ctx + c.resumable_ = io.NewSectionReader(r, 0, size) + c.mediaType_ = mediaType + c.protocol_ = "resumable" + return c +} + +// ProgressUpdater provides a callback function that will be called after every chunk. +// It should be a low-latency function in order to not slow down the upload operation. +// This should only be called when using ResumableMedia (as opposed to Media). +func (c *ManagementUploadsUploadDataCall) ProgressUpdater(pu googleapi.ProgressUpdater) *ManagementUploadsUploadDataCall { + c.opt_["progressUpdater"] = pu + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementUploadsUploadDataCall) Fields(s ...googleapi.Field) *ManagementUploadsUploadDataCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +// This context will supersede any context previously provided to +// the ResumableMedia method. +func (c *ManagementUploadsUploadDataCall) Context(ctx context.Context) *ManagementUploadsUploadDataCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementUploadsUploadDataCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads") + if c.media_ != nil || c.resumable_ != nil { + urls = strings.Replace(urls, "https://www.googleapis.com/", "https://www.googleapis.com/upload/", 1) + params.Set("uploadType", c.protocol_) + } + urls += "?" + params.Encode() + body = new(bytes.Buffer) + ctype := "application/json" + if c.protocol_ != "resumable" { + var cancel func() + cancel, _ = googleapi.ConditionallyIncludeMedia(c.media_, &body, &ctype) + if cancel != nil { + defer cancel() + } + } + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "customDataSourceId": c.customDataSourceId, + }) + if c.protocol_ == "resumable" { + if c.mediaType_ == "" { + c.mediaType_ = googleapi.DetectMediaType(c.resumable_) + } + req.Header.Set("X-Upload-Content-Type", c.mediaType_) + req.Header.Set("Content-Type", "application/json; charset=utf-8") + } else { + req.Header.Set("Content-Type", ctype) + } + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.uploads.uploadData" call. +// Exactly one of *Upload or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Upload.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ManagementUploadsUploadDataCall) Do() (*Upload, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + var progressUpdater_ googleapi.ProgressUpdater + if v, ok := c.opt_["progressUpdater"]; ok { + if pu, ok := v.(googleapi.ProgressUpdater); ok { + progressUpdater_ = pu + } + } + if c.protocol_ == "resumable" { + loc := res.Header.Get("Location") + rx := &googleapi.ResumableUpload{ + Client: c.s.client, + UserAgent: c.s.userAgent(), + URI: loc, + Media: c.resumable_, + MediaType: c.mediaType_, + ContentLength: c.resumable_.Size(), + Callback: progressUpdater_, + } + res, err = rx.Upload(c.ctx_) + if err != nil { + return nil, err + } + defer res.Body.Close() + } + ret := &Upload{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Upload data for a custom data source.", + // "httpMethod": "POST", + // "id": "analytics.management.uploads.uploadData", + // "mediaUpload": { + // "accept": [ + // "application/octet-stream" + // ], + // "maxSize": "1GB", + // "protocols": { + // "resumable": { + // "multipart": true, + // "path": "/resumable/upload/analytics/v3/management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads" + // }, + // "simple": { + // "multipart": true, + // "path": "/upload/analytics/v3/management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads" + // } + // } + // }, + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "customDataSourceId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account Id associated with the upload.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "customDataSourceId": { + // "description": "Custom data source Id to which the data being uploaded belongs.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property UA-string associated with the upload.", + // "location": "path", + // "pattern": "UA-\\d+-\\d+", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/customDataSources/{customDataSourceId}/uploads", + // "response": { + // "$ref": "Upload" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit" + // ], + // "supportsMediaUpload": true + // } + +} + +// method id "analytics.management.webPropertyAdWordsLinks.delete": + +type ManagementWebPropertyAdWordsLinksDeleteCall struct { + s *Service + accountId string + webPropertyId string + webPropertyAdWordsLinkId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Delete: Deletes a web property-AdWords link. +func (r *ManagementWebPropertyAdWordsLinksService) Delete(accountId string, webPropertyId string, webPropertyAdWordsLinkId string) *ManagementWebPropertyAdWordsLinksDeleteCall { + c := &ManagementWebPropertyAdWordsLinksDeleteCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.webPropertyAdWordsLinkId = webPropertyAdWordsLinkId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebPropertyAdWordsLinksDeleteCall) Fields(s ...googleapi.Field) *ManagementWebPropertyAdWordsLinksDeleteCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebPropertyAdWordsLinksDeleteCall) Context(ctx context.Context) *ManagementWebPropertyAdWordsLinksDeleteCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebPropertyAdWordsLinksDeleteCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "webPropertyAdWordsLinkId": c.webPropertyAdWordsLinkId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webPropertyAdWordsLinks.delete" call. +func (c *ManagementWebPropertyAdWordsLinksDeleteCall) Do() error { + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Deletes a web property-AdWords link.", + // "httpMethod": "DELETE", + // "id": "analytics.management.webPropertyAdWordsLinks.delete", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "webPropertyAdWordsLinkId" + // ], + // "parameters": { + // "accountId": { + // "description": "ID of the account which the given web property belongs to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyAdWordsLinkId": { + // "description": "Web property AdWords link ID.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to delete the AdWords link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}", + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.webPropertyAdWordsLinks.get": + +type ManagementWebPropertyAdWordsLinksGetCall struct { + s *Service + accountId string + webPropertyId string + webPropertyAdWordsLinkId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Returns a web property-AdWords link to which the user has +// access. +func (r *ManagementWebPropertyAdWordsLinksService) Get(accountId string, webPropertyId string, webPropertyAdWordsLinkId string) *ManagementWebPropertyAdWordsLinksGetCall { + c := &ManagementWebPropertyAdWordsLinksGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.webPropertyAdWordsLinkId = webPropertyAdWordsLinkId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebPropertyAdWordsLinksGetCall) Fields(s ...googleapi.Field) *ManagementWebPropertyAdWordsLinksGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementWebPropertyAdWordsLinksGetCall) IfNoneMatch(entityTag string) *ManagementWebPropertyAdWordsLinksGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebPropertyAdWordsLinksGetCall) Context(ctx context.Context) *ManagementWebPropertyAdWordsLinksGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebPropertyAdWordsLinksGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "webPropertyAdWordsLinkId": c.webPropertyAdWordsLinkId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webPropertyAdWordsLinks.get" call. +// Exactly one of *EntityAdWordsLink or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *EntityAdWordsLink.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementWebPropertyAdWordsLinksGetCall) Do() (*EntityAdWordsLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityAdWordsLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns a web property-AdWords link to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.webPropertyAdWordsLinks.get", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "webPropertyAdWordsLinkId" + // ], + // "parameters": { + // "accountId": { + // "description": "ID of the account which the given web property belongs to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyAdWordsLinkId": { + // "description": "Web property-AdWords link ID.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve the AdWords link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}", + // "response": { + // "$ref": "EntityAdWordsLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.webPropertyAdWordsLinks.insert": + +type ManagementWebPropertyAdWordsLinksInsertCall struct { + s *Service + accountId string + webPropertyId string + entityadwordslink *EntityAdWordsLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Creates a webProperty-AdWords link. +func (r *ManagementWebPropertyAdWordsLinksService) Insert(accountId string, webPropertyId string, entityadwordslink *EntityAdWordsLink) *ManagementWebPropertyAdWordsLinksInsertCall { + c := &ManagementWebPropertyAdWordsLinksInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.entityadwordslink = entityadwordslink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebPropertyAdWordsLinksInsertCall) Fields(s ...googleapi.Field) *ManagementWebPropertyAdWordsLinksInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebPropertyAdWordsLinksInsertCall) Context(ctx context.Context) *ManagementWebPropertyAdWordsLinksInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebPropertyAdWordsLinksInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.entityadwordslink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webPropertyAdWordsLinks.insert" call. +// Exactly one of *EntityAdWordsLink or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *EntityAdWordsLink.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementWebPropertyAdWordsLinksInsertCall) Do() (*EntityAdWordsLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityAdWordsLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a webProperty-AdWords link.", + // "httpMethod": "POST", + // "id": "analytics.management.webPropertyAdWordsLinks.insert", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "ID of the Google Analytics account to create the link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to create the link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks", + // "request": { + // "$ref": "EntityAdWordsLink" + // }, + // "response": { + // "$ref": "EntityAdWordsLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.webPropertyAdWordsLinks.list": + +type ManagementWebPropertyAdWordsLinksListCall struct { + s *Service + accountId string + webPropertyId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists webProperty-AdWords links for a given web property. +func (r *ManagementWebPropertyAdWordsLinksService) List(accountId string, webPropertyId string) *ManagementWebPropertyAdWordsLinksListCall { + c := &ManagementWebPropertyAdWordsLinksListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of webProperty-AdWords links to include in this response. +func (c *ManagementWebPropertyAdWordsLinksListCall) MaxResults(maxResults int64) *ManagementWebPropertyAdWordsLinksListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first webProperty-AdWords link to retrieve. Use this parameter as a +// pagination mechanism along with the max-results parameter. +func (c *ManagementWebPropertyAdWordsLinksListCall) StartIndex(startIndex int64) *ManagementWebPropertyAdWordsLinksListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebPropertyAdWordsLinksListCall) Fields(s ...googleapi.Field) *ManagementWebPropertyAdWordsLinksListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementWebPropertyAdWordsLinksListCall) IfNoneMatch(entityTag string) *ManagementWebPropertyAdWordsLinksListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebPropertyAdWordsLinksListCall) Context(ctx context.Context) *ManagementWebPropertyAdWordsLinksListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebPropertyAdWordsLinksListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webPropertyAdWordsLinks.list" call. +// Exactly one of *EntityAdWordsLinks or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *EntityAdWordsLinks.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementWebPropertyAdWordsLinksListCall) Do() (*EntityAdWordsLinks, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityAdWordsLinks{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists webProperty-AdWords links for a given web property.", + // "httpMethod": "GET", + // "id": "analytics.management.webPropertyAdWordsLinks.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "ID of the account which the given web property belongs to.", + // "location": "path", + // "pattern": "\\d+", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of webProperty-AdWords links to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first webProperty-AdWords link to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve the AdWords links for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks", + // "response": { + // "$ref": "EntityAdWordsLinks" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.webPropertyAdWordsLinks.patch": + +type ManagementWebPropertyAdWordsLinksPatchCall struct { + s *Service + accountId string + webPropertyId string + webPropertyAdWordsLinkId string + entityadwordslink *EntityAdWordsLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Patch: Updates an existing webProperty-AdWords link. This method +// supports patch semantics. +func (r *ManagementWebPropertyAdWordsLinksService) Patch(accountId string, webPropertyId string, webPropertyAdWordsLinkId string, entityadwordslink *EntityAdWordsLink) *ManagementWebPropertyAdWordsLinksPatchCall { + c := &ManagementWebPropertyAdWordsLinksPatchCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.webPropertyAdWordsLinkId = webPropertyAdWordsLinkId + c.entityadwordslink = entityadwordslink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebPropertyAdWordsLinksPatchCall) Fields(s ...googleapi.Field) *ManagementWebPropertyAdWordsLinksPatchCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebPropertyAdWordsLinksPatchCall) Context(ctx context.Context) *ManagementWebPropertyAdWordsLinksPatchCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebPropertyAdWordsLinksPatchCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.entityadwordslink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "webPropertyAdWordsLinkId": c.webPropertyAdWordsLinkId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webPropertyAdWordsLinks.patch" call. +// Exactly one of *EntityAdWordsLink or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *EntityAdWordsLink.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementWebPropertyAdWordsLinksPatchCall) Do() (*EntityAdWordsLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityAdWordsLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing webProperty-AdWords link. This method supports patch semantics.", + // "httpMethod": "PATCH", + // "id": "analytics.management.webPropertyAdWordsLinks.patch", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "webPropertyAdWordsLinkId" + // ], + // "parameters": { + // "accountId": { + // "description": "ID of the account which the given web property belongs to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyAdWordsLinkId": { + // "description": "Web property-AdWords link ID.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve the AdWords link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}", + // "request": { + // "$ref": "EntityAdWordsLink" + // }, + // "response": { + // "$ref": "EntityAdWordsLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.webPropertyAdWordsLinks.update": + +type ManagementWebPropertyAdWordsLinksUpdateCall struct { + s *Service + accountId string + webPropertyId string + webPropertyAdWordsLinkId string + entityadwordslink *EntityAdWordsLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Updates an existing webProperty-AdWords link. +func (r *ManagementWebPropertyAdWordsLinksService) Update(accountId string, webPropertyId string, webPropertyAdWordsLinkId string, entityadwordslink *EntityAdWordsLink) *ManagementWebPropertyAdWordsLinksUpdateCall { + c := &ManagementWebPropertyAdWordsLinksUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.webPropertyAdWordsLinkId = webPropertyAdWordsLinkId + c.entityadwordslink = entityadwordslink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebPropertyAdWordsLinksUpdateCall) Fields(s ...googleapi.Field) *ManagementWebPropertyAdWordsLinksUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebPropertyAdWordsLinksUpdateCall) Context(ctx context.Context) *ManagementWebPropertyAdWordsLinksUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebPropertyAdWordsLinksUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.entityadwordslink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "webPropertyAdWordsLinkId": c.webPropertyAdWordsLinkId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webPropertyAdWordsLinks.update" call. +// Exactly one of *EntityAdWordsLink or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *EntityAdWordsLink.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementWebPropertyAdWordsLinksUpdateCall) Do() (*EntityAdWordsLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityAdWordsLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing webProperty-AdWords link.", + // "httpMethod": "PUT", + // "id": "analytics.management.webPropertyAdWordsLinks.update", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "webPropertyAdWordsLinkId" + // ], + // "parameters": { + // "accountId": { + // "description": "ID of the account which the given web property belongs to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyAdWordsLinkId": { + // "description": "Web property-AdWords link ID.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to retrieve the AdWords link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityAdWordsLinks/{webPropertyAdWordsLinkId}", + // "request": { + // "$ref": "EntityAdWordsLink" + // }, + // "response": { + // "$ref": "EntityAdWordsLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.webproperties.get": + +type ManagementWebpropertiesGetCall struct { + s *Service + accountId string + webPropertyId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Get: Gets a web property to which the user has access. +func (r *ManagementWebpropertiesService) Get(accountId string, webPropertyId string) *ManagementWebpropertiesGetCall { + c := &ManagementWebpropertiesGetCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebpropertiesGetCall) Fields(s ...googleapi.Field) *ManagementWebpropertiesGetCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementWebpropertiesGetCall) IfNoneMatch(entityTag string) *ManagementWebpropertiesGetCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebpropertiesGetCall) Context(ctx context.Context) *ManagementWebpropertiesGetCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebpropertiesGetCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webproperties.get" call. +// Exactly one of *Webproperty or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Webproperty.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementWebpropertiesGetCall) Do() (*Webproperty, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Webproperty{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Gets a web property to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.webproperties.get", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve the web property for.", + // "location": "path", + // "pattern": "[0-9]+", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "ID to retrieve the web property for.", + // "location": "path", + // "pattern": "UA-[0-9]+-[0-9]+", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}", + // "response": { + // "$ref": "Webproperty" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.webproperties.insert": + +type ManagementWebpropertiesInsertCall struct { + s *Service + accountId string + webproperty *Webproperty + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Create a new property if the account has fewer than 20 +// properties. Web properties are visible in the Google Analytics +// interface only if they have at least one profile. +func (r *ManagementWebpropertiesService) Insert(accountId string, webproperty *Webproperty) *ManagementWebpropertiesInsertCall { + c := &ManagementWebpropertiesInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webproperty = webproperty + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebpropertiesInsertCall) Fields(s ...googleapi.Field) *ManagementWebpropertiesInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebpropertiesInsertCall) Context(ctx context.Context) *ManagementWebpropertiesInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebpropertiesInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.webproperty) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webproperties.insert" call. +// Exactly one of *Webproperty or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Webproperty.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementWebpropertiesInsertCall) Do() (*Webproperty, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Webproperty{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Create a new property if the account has fewer than 20 properties. Web properties are visible in the Google Analytics interface only if they have at least one profile.", + // "httpMethod": "POST", + // "id": "analytics.management.webproperties.insert", + // "parameterOrder": [ + // "accountId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to create the web property for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties", + // "request": { + // "$ref": "Webproperty" + // }, + // "response": { + // "$ref": "Webproperty" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.webproperties.list": + +type ManagementWebpropertiesListCall struct { + s *Service + accountId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists web properties to which the user has access. +func (r *ManagementWebpropertiesService) List(accountId string) *ManagementWebpropertiesListCall { + c := &ManagementWebpropertiesListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of web properties to include in this response. +func (c *ManagementWebpropertiesListCall) MaxResults(maxResults int64) *ManagementWebpropertiesListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first entity to retrieve. Use this parameter as a pagination +// mechanism along with the max-results parameter. +func (c *ManagementWebpropertiesListCall) StartIndex(startIndex int64) *ManagementWebpropertiesListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebpropertiesListCall) Fields(s ...googleapi.Field) *ManagementWebpropertiesListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementWebpropertiesListCall) IfNoneMatch(entityTag string) *ManagementWebpropertiesListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebpropertiesListCall) Context(ctx context.Context) *ManagementWebpropertiesListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebpropertiesListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webproperties.list" call. +// Exactly one of *Webproperties or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Webproperties.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementWebpropertiesListCall) Do() (*Webproperties, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Webproperties{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists web properties to which the user has access.", + // "httpMethod": "GET", + // "id": "analytics.management.webproperties.list", + // "parameterOrder": [ + // "accountId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to retrieve web properties for. Can either be a specific account ID or '~all', which refers to all the accounts that user has access to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of web properties to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties", + // "response": { + // "$ref": "Webproperties" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.management.webproperties.patch": + +type ManagementWebpropertiesPatchCall struct { + s *Service + accountId string + webPropertyId string + webproperty *Webproperty + opt_ map[string]interface{} + ctx_ context.Context +} + +// Patch: Updates an existing web property. This method supports patch +// semantics. +func (r *ManagementWebpropertiesService) Patch(accountId string, webPropertyId string, webproperty *Webproperty) *ManagementWebpropertiesPatchCall { + c := &ManagementWebpropertiesPatchCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.webproperty = webproperty + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebpropertiesPatchCall) Fields(s ...googleapi.Field) *ManagementWebpropertiesPatchCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebpropertiesPatchCall) Context(ctx context.Context) *ManagementWebpropertiesPatchCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebpropertiesPatchCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.webproperty) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webproperties.patch" call. +// Exactly one of *Webproperty or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Webproperty.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementWebpropertiesPatchCall) Do() (*Webproperty, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Webproperty{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing web property. This method supports patch semantics.", + // "httpMethod": "PATCH", + // "id": "analytics.management.webproperties.patch", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to which the web property belongs", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}", + // "request": { + // "$ref": "Webproperty" + // }, + // "response": { + // "$ref": "Webproperty" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.webproperties.update": + +type ManagementWebpropertiesUpdateCall struct { + s *Service + accountId string + webPropertyId string + webproperty *Webproperty + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Updates an existing web property. +func (r *ManagementWebpropertiesService) Update(accountId string, webPropertyId string, webproperty *Webproperty) *ManagementWebpropertiesUpdateCall { + c := &ManagementWebpropertiesUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.webproperty = webproperty + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebpropertiesUpdateCall) Fields(s ...googleapi.Field) *ManagementWebpropertiesUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebpropertiesUpdateCall) Context(ctx context.Context) *ManagementWebpropertiesUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebpropertiesUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.webproperty) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webproperties.update" call. +// Exactly one of *Webproperty or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Webproperty.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *ManagementWebpropertiesUpdateCall) Do() (*Webproperty, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Webproperty{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an existing web property.", + // "httpMethod": "PUT", + // "id": "analytics.management.webproperties.update", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to which the web property belongs", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}", + // "request": { + // "$ref": "Webproperty" + // }, + // "response": { + // "$ref": "Webproperty" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.edit" + // ] + // } + +} + +// method id "analytics.management.webpropertyUserLinks.delete": + +type ManagementWebpropertyUserLinksDeleteCall struct { + s *Service + accountId string + webPropertyId string + linkId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// Delete: Removes a user from the given web property. +func (r *ManagementWebpropertyUserLinksService) Delete(accountId string, webPropertyId string, linkId string) *ManagementWebpropertyUserLinksDeleteCall { + c := &ManagementWebpropertyUserLinksDeleteCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.linkId = linkId + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebpropertyUserLinksDeleteCall) Fields(s ...googleapi.Field) *ManagementWebpropertyUserLinksDeleteCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebpropertyUserLinksDeleteCall) Context(ctx context.Context) *ManagementWebpropertyUserLinksDeleteCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebpropertyUserLinksDeleteCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks/{linkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "linkId": c.linkId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webpropertyUserLinks.delete" call. +func (c *ManagementWebpropertyUserLinksDeleteCall) Do() error { + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Removes a user from the given web property.", + // "httpMethod": "DELETE", + // "id": "analytics.management.webpropertyUserLinks.delete", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "linkId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to delete the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "linkId": { + // "description": "Link ID to delete the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web Property ID to delete the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks/{linkId}", + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users" + // ] + // } + +} + +// method id "analytics.management.webpropertyUserLinks.insert": + +type ManagementWebpropertyUserLinksInsertCall struct { + s *Service + accountId string + webPropertyId string + entityuserlink *EntityUserLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Insert: Adds a new user to the given web property. +func (r *ManagementWebpropertyUserLinksService) Insert(accountId string, webPropertyId string, entityuserlink *EntityUserLink) *ManagementWebpropertyUserLinksInsertCall { + c := &ManagementWebpropertyUserLinksInsertCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.entityuserlink = entityuserlink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebpropertyUserLinksInsertCall) Fields(s ...googleapi.Field) *ManagementWebpropertyUserLinksInsertCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebpropertyUserLinksInsertCall) Context(ctx context.Context) *ManagementWebpropertyUserLinksInsertCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebpropertyUserLinksInsertCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.entityuserlink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webpropertyUserLinks.insert" call. +// Exactly one of *EntityUserLink or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *EntityUserLink.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementWebpropertyUserLinksInsertCall) Do() (*EntityUserLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityUserLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Adds a new user to the given web property.", + // "httpMethod": "POST", + // "id": "analytics.management.webpropertyUserLinks.insert", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to create the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web Property ID to create the user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks", + // "request": { + // "$ref": "EntityUserLink" + // }, + // "response": { + // "$ref": "EntityUserLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users" + // ] + // } + +} + +// method id "analytics.management.webpropertyUserLinks.list": + +type ManagementWebpropertyUserLinksListCall struct { + s *Service + accountId string + webPropertyId string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists webProperty-user links for a given web property. +func (r *ManagementWebpropertyUserLinksService) List(accountId string, webPropertyId string) *ManagementWebpropertyUserLinksListCall { + c := &ManagementWebpropertyUserLinksListCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + return c +} + +// MaxResults sets the optional parameter "max-results": The maximum +// number of webProperty-user Links to include in this response. +func (c *ManagementWebpropertyUserLinksListCall) MaxResults(maxResults int64) *ManagementWebpropertyUserLinksListCall { + c.opt_["max-results"] = maxResults + return c +} + +// StartIndex sets the optional parameter "start-index": An index of the +// first webProperty-user link to retrieve. Use this parameter as a +// pagination mechanism along with the max-results parameter. +func (c *ManagementWebpropertyUserLinksListCall) StartIndex(startIndex int64) *ManagementWebpropertyUserLinksListCall { + c.opt_["start-index"] = startIndex + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebpropertyUserLinksListCall) Fields(s ...googleapi.Field) *ManagementWebpropertyUserLinksListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ManagementWebpropertyUserLinksListCall) IfNoneMatch(entityTag string) *ManagementWebpropertyUserLinksListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebpropertyUserLinksListCall) Context(ctx context.Context) *ManagementWebpropertyUserLinksListCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebpropertyUserLinksListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["max-results"]; ok { + params.Set("max-results", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["start-index"]; ok { + params.Set("start-index", fmt.Sprintf("%v", v)) + } + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webpropertyUserLinks.list" call. +// Exactly one of *EntityUserLinks or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *EntityUserLinks.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementWebpropertyUserLinksListCall) Do() (*EntityUserLinks, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityUserLinks{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists webProperty-user links for a given web property.", + // "httpMethod": "GET", + // "id": "analytics.management.webpropertyUserLinks.list", + // "parameterOrder": [ + // "accountId", + // "webPropertyId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID which the given web property belongs to.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "max-results": { + // "description": "The maximum number of webProperty-user Links to include in this response.", + // "format": "int32", + // "location": "query", + // "type": "integer" + // }, + // "start-index": { + // "description": "An index of the first webProperty-user link to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.", + // "format": "int32", + // "location": "query", + // "minimum": "1", + // "type": "integer" + // }, + // "webPropertyId": { + // "description": "Web Property ID for the webProperty-user links to retrieve. Can either be a specific web property ID or '~all', which refers to all the web properties that user has access to.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks", + // "response": { + // "$ref": "EntityUserLinks" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users", + // "https://www.googleapis.com/auth/analytics.manage.users.readonly" + // ] + // } + +} + +// method id "analytics.management.webpropertyUserLinks.update": + +type ManagementWebpropertyUserLinksUpdateCall struct { + s *Service + accountId string + webPropertyId string + linkId string + entityuserlink *EntityUserLink + opt_ map[string]interface{} + ctx_ context.Context +} + +// Update: Updates permissions for an existing user on the given web +// property. +func (r *ManagementWebpropertyUserLinksService) Update(accountId string, webPropertyId string, linkId string, entityuserlink *EntityUserLink) *ManagementWebpropertyUserLinksUpdateCall { + c := &ManagementWebpropertyUserLinksUpdateCall{s: r.s, opt_: make(map[string]interface{})} + c.accountId = accountId + c.webPropertyId = webPropertyId + c.linkId = linkId + c.entityuserlink = entityuserlink + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ManagementWebpropertyUserLinksUpdateCall) Fields(s ...googleapi.Field) *ManagementWebpropertyUserLinksUpdateCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ManagementWebpropertyUserLinksUpdateCall) Context(ctx context.Context) *ManagementWebpropertyUserLinksUpdateCall { + c.ctx_ = ctx + return c +} + +func (c *ManagementWebpropertyUserLinksUpdateCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.entityuserlink) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks/{linkId}") + urls += "?" + params.Encode() + req, _ := http.NewRequest("PUT", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "accountId": c.accountId, + "webPropertyId": c.webPropertyId, + "linkId": c.linkId, + }) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.management.webpropertyUserLinks.update" call. +// Exactly one of *EntityUserLink or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *EntityUserLink.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ManagementWebpropertyUserLinksUpdateCall) Do() (*EntityUserLink, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &EntityUserLink{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates permissions for an existing user on the given web property.", + // "httpMethod": "PUT", + // "id": "analytics.management.webpropertyUserLinks.update", + // "parameterOrder": [ + // "accountId", + // "webPropertyId", + // "linkId" + // ], + // "parameters": { + // "accountId": { + // "description": "Account ID to update the account-user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "linkId": { + // "description": "Link ID to update the account-user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "webPropertyId": { + // "description": "Web property ID to update the account-user link for.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/entityUserLinks/{linkId}", + // "request": { + // "$ref": "EntityUserLink" + // }, + // "response": { + // "$ref": "EntityUserLink" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.manage.users" + // ] + // } + +} + +// method id "analytics.metadata.columns.list": + +type MetadataColumnsListCall struct { + s *Service + reportType string + opt_ map[string]interface{} + ctx_ context.Context +} + +// List: Lists all columns for a report type +func (r *MetadataColumnsService) List(reportType string) *MetadataColumnsListCall { + c := &MetadataColumnsListCall{s: r.s, opt_: make(map[string]interface{})} + c.reportType = reportType + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *MetadataColumnsListCall) Fields(s ...googleapi.Field) *MetadataColumnsListCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *MetadataColumnsListCall) IfNoneMatch(entityTag string) *MetadataColumnsListCall { + c.opt_["ifNoneMatch"] = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *MetadataColumnsListCall) Context(ctx context.Context) *MetadataColumnsListCall { + c.ctx_ = ctx + return c +} + +func (c *MetadataColumnsListCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "metadata/{reportType}/columns") + urls += "?" + params.Encode() + req, _ := http.NewRequest("GET", urls, body) + googleapi.Expand(req.URL, map[string]string{ + "reportType": c.reportType, + }) + req.Header.Set("User-Agent", c.s.userAgent()) + if v, ok := c.opt_["ifNoneMatch"]; ok { + req.Header.Set("If-None-Match", fmt.Sprintf("%v", v)) + } + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.metadata.columns.list" call. +// Exactly one of *Columns or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Columns.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *MetadataColumnsListCall) Do() (*Columns, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Columns{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Lists all columns for a report type", + // "httpMethod": "GET", + // "id": "analytics.metadata.columns.list", + // "parameterOrder": [ + // "reportType" + // ], + // "parameters": { + // "reportType": { + // "description": "Report type. Allowed Values: 'ga'. Where 'ga' corresponds to the Core Reporting API", + // "location": "path", + // "pattern": "ga", + // "required": true, + // "type": "string" + // } + // }, + // "path": "metadata/{reportType}/columns", + // "response": { + // "$ref": "Columns" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics", + // "https://www.googleapis.com/auth/analytics.edit", + // "https://www.googleapis.com/auth/analytics.readonly" + // ] + // } + +} + +// method id "analytics.provisioning.createAccountTicket": + +type ProvisioningCreateAccountTicketCall struct { + s *Service + accountticket *AccountTicket + opt_ map[string]interface{} + ctx_ context.Context +} + +// CreateAccountTicket: Creates an account ticket. +func (r *ProvisioningService) CreateAccountTicket(accountticket *AccountTicket) *ProvisioningCreateAccountTicketCall { + c := &ProvisioningCreateAccountTicketCall{s: r.s, opt_: make(map[string]interface{})} + c.accountticket = accountticket + return c +} + +// Fields allows partial responses to be retrieved. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ProvisioningCreateAccountTicketCall) Fields(s ...googleapi.Field) *ProvisioningCreateAccountTicketCall { + c.opt_["fields"] = googleapi.CombineFields(s) + return c +} + +// Context sets the context to be used in this call's Do method. +// Any pending HTTP request will be aborted if the provided context +// is canceled. +func (c *ProvisioningCreateAccountTicketCall) Context(ctx context.Context) *ProvisioningCreateAccountTicketCall { + c.ctx_ = ctx + return c +} + +func (c *ProvisioningCreateAccountTicketCall) doRequest(alt string) (*http.Response, error) { + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.accountticket) + if err != nil { + return nil, err + } + ctype := "application/json" + params := make(url.Values) + params.Set("alt", alt) + if v, ok := c.opt_["fields"]; ok { + params.Set("fields", fmt.Sprintf("%v", v)) + } + urls := googleapi.ResolveRelative(c.s.BasePath, "provisioning/createAccountTicket") + urls += "?" + params.Encode() + req, _ := http.NewRequest("POST", urls, body) + googleapi.SetOpaque(req.URL) + req.Header.Set("Content-Type", ctype) + req.Header.Set("User-Agent", c.s.userAgent()) + if c.ctx_ != nil { + return ctxhttp.Do(c.ctx_, c.s.client, req) + } + return c.s.client.Do(req) +} + +// Do executes the "analytics.provisioning.createAccountTicket" call. +// Exactly one of *AccountTicket or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *AccountTicket.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ProvisioningCreateAccountTicketCall) Do() (*AccountTicket, error) { + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &AccountTicket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates an account ticket.", + // "httpMethod": "POST", + // "id": "analytics.provisioning.createAccountTicket", + // "path": "provisioning/createAccountTicket", + // "request": { + // "$ref": "AccountTicket" + // }, + // "response": { + // "$ref": "AccountTicket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/analytics.provision" + // ] + // } + +} diff --git a/_third_party/google.golang.org/api/googleapi/googleapi.go b/_third_party/google.golang.org/api/googleapi/googleapi.go new file mode 100644 index 0000000000..7af48b5120 --- /dev/null +++ b/_third_party/google.golang.org/api/googleapi/googleapi.go @@ -0,0 +1,592 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package googleapi contains the common code shared by all Google API +// libraries. +package googleapi // import "bosun.org/_third_party/google.golang.org/api/googleapi" + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "mime/multipart" + "net/http" + "net/textproto" + "net/url" + "regexp" + "strconv" + "strings" + "sync" + "time" + + "bosun.org/_third_party/golang.org/x/net/context" + "bosun.org/_third_party/golang.org/x/net/context/ctxhttp" + "bosun.org/_third_party/google.golang.org/api/googleapi/internal/uritemplates" +) + +// ContentTyper is an interface for Readers which know (or would like +// to override) their Content-Type. If a media body doesn't implement +// ContentTyper, the type is sniffed from the content using +// http.DetectContentType. +type ContentTyper interface { + ContentType() string +} + +// A SizeReaderAt is a ReaderAt with a Size method. +// An io.SectionReader implements SizeReaderAt. +type SizeReaderAt interface { + io.ReaderAt + Size() int64 +} + +// ServerResponse is embedded in each Do response and +// provides the HTTP status code and header sent by the server. +type ServerResponse struct { + // HTTPStatusCode is the server's response status code. + // When using a resource method's Do call, this will always be in the 2xx range. + HTTPStatusCode int + // Header contains the response header fields from the server. + Header http.Header +} + +const ( + Version = "0.5" + + // statusResumeIncomplete is the code returned by the Google uploader when the transfer is not yet complete. + statusResumeIncomplete = 308 + + // UserAgent is the header string used to identify this package. + UserAgent = "google-api-go-client/" + Version + + // uploadPause determines the delay between failed upload attempts + uploadPause = 1 * time.Second +) + +// Error contains an error response from the server. +type Error struct { + // Code is the HTTP response status code and will always be populated. + Code int `json:"code"` + // Message is the server response message and is only populated when + // explicitly referenced by the JSON server response. + Message string `json:"message"` + // Body is the raw response returned by the server. + // It is often but not always JSON, depending on how the request fails. + Body string + // Header contains the response header fields from the server. + Header http.Header + + Errors []ErrorItem +} + +// ErrorItem is a detailed error code & message from the Google API frontend. +type ErrorItem struct { + // Reason is the typed error code. For example: "some_example". + Reason string `json:"reason"` + // Message is the human-readable description of the error. + Message string `json:"message"` +} + +func (e *Error) Error() string { + if len(e.Errors) == 0 && e.Message == "" { + return fmt.Sprintf("googleapi: got HTTP response code %d with body: %v", e.Code, e.Body) + } + var buf bytes.Buffer + fmt.Fprintf(&buf, "googleapi: Error %d: ", e.Code) + if e.Message != "" { + fmt.Fprintf(&buf, "%s", e.Message) + } + if len(e.Errors) == 0 { + return strings.TrimSpace(buf.String()) + } + if len(e.Errors) == 1 && e.Errors[0].Message == e.Message { + fmt.Fprintf(&buf, ", %s", e.Errors[0].Reason) + return buf.String() + } + fmt.Fprintln(&buf, "\nMore details:") + for _, v := range e.Errors { + fmt.Fprintf(&buf, "Reason: %s, Message: %s\n", v.Reason, v.Message) + } + return buf.String() +} + +type errorReply struct { + Error *Error `json:"error"` +} + +// CheckResponse returns an error (of type *Error) if the response +// status code is not 2xx. +func CheckResponse(res *http.Response) error { + if res.StatusCode >= 200 && res.StatusCode <= 299 { + return nil + } + slurp, err := ioutil.ReadAll(res.Body) + if err == nil { + jerr := new(errorReply) + err = json.Unmarshal(slurp, jerr) + if err == nil && jerr.Error != nil { + if jerr.Error.Code == 0 { + jerr.Error.Code = res.StatusCode + } + jerr.Error.Body = string(slurp) + return jerr.Error + } + } + return &Error{ + Code: res.StatusCode, + Body: string(slurp), + Header: res.Header, + } +} + +// IsNotModified reports whether err is the result of the +// server replying with http.StatusNotModified. +// Such error values are sometimes returned by "Do" methods +// on calls when If-None-Match is used. +func IsNotModified(err error) bool { + if err == nil { + return false + } + ae, ok := err.(*Error) + return ok && ae.Code == http.StatusNotModified +} + +// CheckMediaResponse returns an error (of type *Error) if the response +// status code is not 2xx. Unlike CheckResponse it does not assume the +// body is a JSON error document. +func CheckMediaResponse(res *http.Response) error { + if res.StatusCode >= 200 && res.StatusCode <= 299 { + return nil + } + slurp, _ := ioutil.ReadAll(io.LimitReader(res.Body, 1<<20)) + res.Body.Close() + return &Error{ + Code: res.StatusCode, + Body: string(slurp), + } +} + +type MarshalStyle bool + +var WithDataWrapper = MarshalStyle(true) +var WithoutDataWrapper = MarshalStyle(false) + +func (wrap MarshalStyle) JSONReader(v interface{}) (io.Reader, error) { + buf := new(bytes.Buffer) + if wrap { + buf.Write([]byte(`{"data": `)) + } + err := json.NewEncoder(buf).Encode(v) + if err != nil { + return nil, err + } + if wrap { + buf.Write([]byte(`}`)) + } + return buf, nil +} + +func getMediaType(media io.Reader) (io.Reader, string) { + if typer, ok := media.(ContentTyper); ok { + return media, typer.ContentType() + } + + pr, pw := io.Pipe() + typ := "application/octet-stream" + buf, err := ioutil.ReadAll(io.LimitReader(media, 512)) + if err != nil { + pw.CloseWithError(fmt.Errorf("error reading media: %v", err)) + return pr, typ + } + typ = http.DetectContentType(buf) + mr := io.MultiReader(bytes.NewReader(buf), media) + go func() { + _, err = io.Copy(pw, mr) + if err != nil { + pw.CloseWithError(fmt.Errorf("error reading media: %v", err)) + return + } + pw.Close() + }() + return pr, typ +} + +// DetectMediaType detects and returns the content type of the provided media. +// If the type can not be determined, "application/octet-stream" is returned. +func DetectMediaType(media io.ReaderAt) string { + if typer, ok := media.(ContentTyper); ok { + return typer.ContentType() + } + + typ := "application/octet-stream" + buf := make([]byte, 1024) + n, err := media.ReadAt(buf, 0) + buf = buf[:n] + if err == nil || err == io.EOF { + typ = http.DetectContentType(buf) + } + return typ +} + +type Lengther interface { + Len() int +} + +// endingWithErrorReader from r until it returns an error. If the +// final error from r is io.EOF and e is non-nil, e is used instead. +type endingWithErrorReader struct { + r io.Reader + e error +} + +func (er endingWithErrorReader) Read(p []byte) (n int, err error) { + n, err = er.r.Read(p) + if err == io.EOF && er.e != nil { + err = er.e + } + return +} + +func typeHeader(contentType string) textproto.MIMEHeader { + h := make(textproto.MIMEHeader) + h.Set("Content-Type", contentType) + return h +} + +// countingWriter counts the number of bytes it receives to write, but +// discards them. +type countingWriter struct { + n *int64 +} + +func (w countingWriter) Write(p []byte) (int, error) { + *w.n += int64(len(p)) + return len(p), nil +} + +// ConditionallyIncludeMedia does nothing if media is nil. +// +// bodyp is an in/out parameter. It should initially point to the +// reader of the application/json (or whatever) payload to send in the +// API request. It's updated to point to the multipart body reader. +// +// ctypep is an in/out parameter. It should initially point to the +// content type of the bodyp, usually "application/json". It's updated +// to the "multipart/related" content type, with random boundary. +// +// The return value is the content-length of the entire multpart body. +func ConditionallyIncludeMedia(media io.Reader, bodyp *io.Reader, ctypep *string) (cancel func(), ok bool) { + if media == nil { + return + } + // Get the media type, which might return a different reader instance. + var mediaType string + media, mediaType = getMediaType(media) + + body, bodyType := *bodyp, *ctypep + + pr, pw := io.Pipe() + mpw := multipart.NewWriter(pw) + *bodyp = pr + *ctypep = "multipart/related; boundary=" + mpw.Boundary() + go func() { + w, err := mpw.CreatePart(typeHeader(bodyType)) + if err != nil { + mpw.Close() + pw.CloseWithError(fmt.Errorf("googleapi: body CreatePart failed: %v", err)) + return + } + _, err = io.Copy(w, body) + if err != nil { + mpw.Close() + pw.CloseWithError(fmt.Errorf("googleapi: body Copy failed: %v", err)) + return + } + + w, err = mpw.CreatePart(typeHeader(mediaType)) + if err != nil { + mpw.Close() + pw.CloseWithError(fmt.Errorf("googleapi: media CreatePart failed: %v", err)) + return + } + _, err = io.Copy(w, media) + if err != nil { + mpw.Close() + pw.CloseWithError(fmt.Errorf("googleapi: media Copy failed: %v", err)) + return + } + mpw.Close() + pw.Close() + }() + cancel = func() { pw.CloseWithError(errAborted) } + return cancel, true +} + +var errAborted = errors.New("googleapi: upload aborted") + +// ProgressUpdater is a function that is called upon every progress update of a resumable upload. +// This is the only part of a resumable upload (from googleapi) that is usable by the developer. +// The remaining usable pieces of resumable uploads is exposed in each auto-generated API. +type ProgressUpdater func(current, total int64) + +// ResumableUpload is used by the generated APIs to provide resumable uploads. +// It is not used by developers directly. +type ResumableUpload struct { + Client *http.Client + // URI is the resumable resource destination provided by the server after specifying "&uploadType=resumable". + URI string + UserAgent string // User-Agent for header of the request + // Media is the object being uploaded. + Media io.ReaderAt + // MediaType defines the media type, e.g. "image/jpeg". + MediaType string + // ContentLength is the full size of the object being uploaded. + ContentLength int64 + + mu sync.Mutex // guards progress + progress int64 // number of bytes uploaded so far + started bool // whether the upload has been started + + // Callback is an optional function that will be called upon every progress update. + Callback ProgressUpdater +} + +var ( + // rangeRE matches the transfer status response from the server. $1 is the last byte index uploaded. + rangeRE = regexp.MustCompile(`^bytes=0\-(\d+)$`) + // chunkSize is the size of the chunks created during a resumable upload and should be a power of two. + // 1<<18 is the minimum size supported by the Google uploader, and there is no maximum. + chunkSize int64 = 1 << 18 +) + +// Progress returns the number of bytes uploaded at this point. +func (rx *ResumableUpload) Progress() int64 { + rx.mu.Lock() + defer rx.mu.Unlock() + return rx.progress +} + +func (rx *ResumableUpload) transferStatus(ctx context.Context) (int64, *http.Response, error) { + req, _ := http.NewRequest("POST", rx.URI, nil) + req.ContentLength = 0 + req.Header.Set("User-Agent", rx.UserAgent) + req.Header.Set("Content-Range", fmt.Sprintf("bytes */%v", rx.ContentLength)) + res, err := ctxhttp.Do(ctx, rx.Client, req) + if err != nil || res.StatusCode != statusResumeIncomplete { + return 0, res, err + } + var start int64 + if m := rangeRE.FindStringSubmatch(res.Header.Get("Range")); len(m) == 2 { + start, err = strconv.ParseInt(m[1], 10, 64) + if err != nil { + return 0, nil, fmt.Errorf("unable to parse range size %v", m[1]) + } + start += 1 // Start at the next byte + } + return start, res, nil +} + +type chunk struct { + body io.Reader + size int64 + err error +} + +func (rx *ResumableUpload) transferChunks(ctx context.Context) (*http.Response, error) { + var start int64 + var err error + res := &http.Response{} + if rx.started { + start, res, err = rx.transferStatus(ctx) + if err != nil || res.StatusCode != statusResumeIncomplete { + return res, err + } + } + rx.started = true + + for { + select { // Check for cancellation + case <-ctx.Done(): + res.StatusCode = http.StatusRequestTimeout + return res, ctx.Err() + default: + } + reqSize := rx.ContentLength - start + if reqSize > chunkSize { + reqSize = chunkSize + } + r := io.NewSectionReader(rx.Media, start, reqSize) + req, _ := http.NewRequest("POST", rx.URI, r) + req.ContentLength = reqSize + req.Header.Set("Content-Range", fmt.Sprintf("bytes %v-%v/%v", start, start+reqSize-1, rx.ContentLength)) + req.Header.Set("Content-Type", rx.MediaType) + req.Header.Set("User-Agent", rx.UserAgent) + res, err = ctxhttp.Do(ctx, rx.Client, req) + start += reqSize + if err == nil && (res.StatusCode == statusResumeIncomplete || res.StatusCode == http.StatusOK) { + rx.mu.Lock() + rx.progress = start // keep track of number of bytes sent so far + rx.mu.Unlock() + if rx.Callback != nil { + rx.Callback(start, rx.ContentLength) + } + } + if err != nil || res.StatusCode != statusResumeIncomplete { + break + } + } + return res, err +} + +var sleep = time.Sleep // override in unit tests + +// Upload starts the process of a resumable upload with a cancellable context. +// It retries indefinitely (with a pause of uploadPause between attempts) until cancelled. +// It is called from the auto-generated API code and is not visible to the user. +// rx is private to the auto-generated API code. +func (rx *ResumableUpload) Upload(ctx context.Context) (*http.Response, error) { + var res *http.Response + var err error + for { + res, err = rx.transferChunks(ctx) + if err != nil || res.StatusCode == http.StatusCreated || res.StatusCode == http.StatusOK { + return res, err + } + select { // Check for cancellation + case <-ctx.Done(): + res.StatusCode = http.StatusRequestTimeout + return res, ctx.Err() + default: + } + sleep(uploadPause) + } + return res, err +} + +func ResolveRelative(basestr, relstr string) string { + u, _ := url.Parse(basestr) + rel, _ := url.Parse(relstr) + u = u.ResolveReference(rel) + us := u.String() + us = strings.Replace(us, "%7B", "{", -1) + us = strings.Replace(us, "%7D", "}", -1) + return us +} + +// has4860Fix is whether this Go environment contains the fix for +// http://golang.org/issue/4860 +var has4860Fix bool + +// init initializes has4860Fix by checking the behavior of the net/http package. +func init() { + r := http.Request{ + URL: &url.URL{ + Scheme: "http", + Opaque: "//opaque", + }, + } + b := &bytes.Buffer{} + r.Write(b) + has4860Fix = bytes.HasPrefix(b.Bytes(), []byte("GET http")) +} + +// SetOpaque sets u.Opaque from u.Path such that HTTP requests to it +// don't alter any hex-escaped characters in u.Path. +func SetOpaque(u *url.URL) { + u.Opaque = "//" + u.Host + u.Path + if !has4860Fix { + u.Opaque = u.Scheme + ":" + u.Opaque + } +} + +// Expand subsitutes any {encoded} strings in the URL passed in using +// the map supplied. +// +// This calls SetOpaque to avoid encoding of the parameters in the URL path. +func Expand(u *url.URL, expansions map[string]string) { + expanded, err := uritemplates.Expand(u.Path, expansions) + if err == nil { + u.Path = expanded + SetOpaque(u) + } +} + +// CloseBody is used to close res.Body. +// Prior to calling Close, it also tries to Read a small amount to see an EOF. +// Not seeing an EOF can prevent HTTP Transports from reusing connections. +func CloseBody(res *http.Response) { + if res == nil || res.Body == nil { + return + } + // Justification for 3 byte reads: two for up to "\r\n" after + // a JSON/XML document, and then 1 to see EOF if we haven't yet. + // TODO(bradfitz): detect Go 1.3+ and skip these reads. + // See https://codereview.appspot.com/58240043 + // and https://codereview.appspot.com/49570044 + buf := make([]byte, 1) + for i := 0; i < 3; i++ { + _, err := res.Body.Read(buf) + if err != nil { + break + } + } + res.Body.Close() + +} + +// VariantType returns the type name of the given variant. +// If the map doesn't contain the named key or the value is not a []interface{}, "" is returned. +// This is used to support "variant" APIs that can return one of a number of different types. +func VariantType(t map[string]interface{}) string { + s, _ := t["type"].(string) + return s +} + +// ConvertVariant uses the JSON encoder/decoder to fill in the struct 'dst' with the fields found in variant 'v'. +// This is used to support "variant" APIs that can return one of a number of different types. +// It reports whether the conversion was successful. +func ConvertVariant(v map[string]interface{}, dst interface{}) bool { + var buf bytes.Buffer + err := json.NewEncoder(&buf).Encode(v) + if err != nil { + return false + } + return json.Unmarshal(buf.Bytes(), dst) == nil +} + +// A Field names a field to be retrieved with a partial response. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// +// Partial responses can dramatically reduce the amount of data that must be sent to your application. +// In order to request partial responses, you can specify the full list of fields +// that your application needs by adding the Fields option to your request. +// +// Field strings use camelCase with leading lower-case characters to identify fields within the response. +// +// For example, if your response has a "NextPageToken" and a slice of "Items" with "Id" fields, +// you could request just those fields like this: +// +// svc.Events.List().Fields("nextPageToken", "items/id").Do() +// +// or if you were also interested in each Item's "Updated" field, you can combine them like this: +// +// svc.Events.List().Fields("nextPageToken", "items(id,updated)").Do() +// +// More information about field formatting can be found here: +// https://developers.google.com/+/api/#fields-syntax +// +// Another way to find field names is through the Google API explorer: +// https://developers.google.com/apis-explorer/#p/ +type Field string + +// CombineFields combines fields into a single string. +func CombineFields(s []Field) string { + r := make([]string, len(s)) + for i, v := range s { + r[i] = string(v) + } + return strings.Join(r, ",") +} diff --git a/_third_party/google.golang.org/api/googleapi/googleapi_test.go b/_third_party/google.golang.org/api/googleapi/googleapi_test.go new file mode 100644 index 0000000000..578e2e65ea --- /dev/null +++ b/_third_party/google.golang.org/api/googleapi/googleapi_test.go @@ -0,0 +1,599 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package googleapi + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "os" + "reflect" + "regexp" + "strconv" + "strings" + "testing" + "time" + + "bosun.org/_third_party/golang.org/x/net/context" +) + +type SetOpaqueTest struct { + in *url.URL + wantRequestURI string +} + +var setOpaqueTests = []SetOpaqueTest{ + // no path + { + &url.URL{ + Scheme: "http", + Host: "www.golang.org", + }, + "http://www.golang.org", + }, + // path + { + &url.URL{ + Scheme: "http", + Host: "www.golang.org", + Path: "/", + }, + "http://www.golang.org/", + }, + // file with hex escaping + { + &url.URL{ + Scheme: "https", + Host: "www.golang.org", + Path: "/file%20one&two", + }, + "https://www.golang.org/file%20one&two", + }, + // query + { + &url.URL{ + Scheme: "http", + Host: "www.golang.org", + Path: "/", + RawQuery: "q=go+language", + }, + "http://www.golang.org/?q=go+language", + }, + // file with hex escaping in path plus query + { + &url.URL{ + Scheme: "https", + Host: "www.golang.org", + Path: "/file%20one&two", + RawQuery: "q=go+language", + }, + "https://www.golang.org/file%20one&two?q=go+language", + }, + // query with hex escaping + { + &url.URL{ + Scheme: "http", + Host: "www.golang.org", + Path: "/", + RawQuery: "q=go%20language", + }, + "http://www.golang.org/?q=go%20language", + }, +} + +// prefixTmpl is a template for the expected prefix of the output of writing +// an HTTP request. +const prefixTmpl = "GET %v HTTP/1.1\r\nHost: %v\r\n" + +func TestSetOpaque(t *testing.T) { + for _, test := range setOpaqueTests { + u := *test.in + SetOpaque(&u) + + w := &bytes.Buffer{} + r := &http.Request{URL: &u} + if err := r.Write(w); err != nil { + t.Errorf("write request: %v", err) + continue + } + + prefix := fmt.Sprintf(prefixTmpl, test.wantRequestURI, test.in.Host) + if got := string(w.Bytes()); !strings.HasPrefix(got, prefix) { + t.Errorf("got %q expected prefix %q", got, prefix) + } + } +} + +type ExpandTest struct { + in string + expansions map[string]string + want string +} + +var expandTests = []ExpandTest{ + // no expansions + { + "http://www.golang.org/", + map[string]string{}, + "http://www.golang.org/", + }, + // one expansion, no escaping + { + "http://www.golang.org/{bucket}/delete", + map[string]string{ + "bucket": "red", + }, + "http://www.golang.org/red/delete", + }, + // one expansion, with hex escapes + { + "http://www.golang.org/{bucket}/delete", + map[string]string{ + "bucket": "red/blue", + }, + "http://www.golang.org/red%2Fblue/delete", + }, + // one expansion, with space + { + "http://www.golang.org/{bucket}/delete", + map[string]string{ + "bucket": "red or blue", + }, + "http://www.golang.org/red%20or%20blue/delete", + }, + // expansion not found + { + "http://www.golang.org/{object}/delete", + map[string]string{ + "bucket": "red or blue", + }, + "http://www.golang.org//delete", + }, + // multiple expansions + { + "http://www.golang.org/{one}/{two}/{three}/get", + map[string]string{ + "one": "ONE", + "two": "TWO", + "three": "THREE", + }, + "http://www.golang.org/ONE/TWO/THREE/get", + }, + // utf-8 characters + { + "http://www.golang.org/{bucket}/get", + map[string]string{ + "bucket": "£100", + }, + "http://www.golang.org/%C2%A3100/get", + }, + // punctuations + { + "http://www.golang.org/{bucket}/get", + map[string]string{ + "bucket": `/\@:,.`, + }, + "http://www.golang.org/%2F%5C%40%3A%2C./get", + }, + // mis-matched brackets + { + "http://www.golang.org/{bucket/get", + map[string]string{ + "bucket": "red", + }, + "http://www.golang.org/{bucket/get", + }, + // "+" prefix for suppressing escape + // See also: http://tools.ietf.org/html/rfc6570#section-3.2.3 + { + "http://www.golang.org/{+topic}", + map[string]string{ + "topic": "/topics/myproject/mytopic", + }, + // The double slashes here look weird, but it's intentional + "http://www.golang.org//topics/myproject/mytopic", + }, +} + +func TestExpand(t *testing.T) { + for i, test := range expandTests { + u := url.URL{ + Path: test.in, + } + Expand(&u, test.expansions) + got := u.Path + if got != test.want { + t.Errorf("got %q expected %q in test %d", got, test.want, i+1) + } + } +} + +type CheckResponseTest struct { + in *http.Response + bodyText string + want error + errText string +} + +var checkResponseTests = []CheckResponseTest{ + { + &http.Response{ + StatusCode: http.StatusOK, + }, + "", + nil, + "", + }, + { + &http.Response{ + StatusCode: http.StatusInternalServerError, + }, + `{"error":{}}`, + &Error{ + Code: http.StatusInternalServerError, + Body: `{"error":{}}`, + }, + `googleapi: got HTTP response code 500 with body: {"error":{}}`, + }, + { + &http.Response{ + StatusCode: http.StatusNotFound, + }, + `{"error":{"message":"Error message for StatusNotFound."}}`, + &Error{ + Code: http.StatusNotFound, + Message: "Error message for StatusNotFound.", + Body: `{"error":{"message":"Error message for StatusNotFound."}}`, + }, + "googleapi: Error 404: Error message for StatusNotFound.", + }, + { + &http.Response{ + StatusCode: http.StatusBadRequest, + }, + `{"error":"invalid_token","error_description":"Invalid Value"}`, + &Error{ + Code: http.StatusBadRequest, + Body: `{"error":"invalid_token","error_description":"Invalid Value"}`, + }, + `googleapi: got HTTP response code 400 with body: {"error":"invalid_token","error_description":"Invalid Value"}`, + }, + { + &http.Response{ + StatusCode: http.StatusBadRequest, + }, + `{"error":{"errors":[{"domain":"usageLimits","reason":"keyInvalid","message":"Bad Request"}],"code":400,"message":"Bad Request"}}`, + &Error{ + Code: http.StatusBadRequest, + Errors: []ErrorItem{ + { + Reason: "keyInvalid", + Message: "Bad Request", + }, + }, + Body: `{"error":{"errors":[{"domain":"usageLimits","reason":"keyInvalid","message":"Bad Request"}],"code":400,"message":"Bad Request"}}`, + Message: "Bad Request", + }, + "googleapi: Error 400: Bad Request, keyInvalid", + }, +} + +func TestCheckResponse(t *testing.T) { + for _, test := range checkResponseTests { + res := test.in + if test.bodyText != "" { + res.Body = ioutil.NopCloser(strings.NewReader(test.bodyText)) + } + g := CheckResponse(res) + if !reflect.DeepEqual(g, test.want) { + t.Errorf("CheckResponse: got %v, want %v", g, test.want) + gotJson, err := json.Marshal(g) + if err != nil { + t.Error(err) + } + wantJson, err := json.Marshal(test.want) + if err != nil { + t.Error(err) + } + t.Errorf("json(got): %q\njson(want): %q", string(gotJson), string(wantJson)) + } + if g != nil && g.Error() != test.errText { + t.Errorf("CheckResponse: unexpected error message.\nGot: %q\nwant: %q", g, test.errText) + } + } +} + +type VariantPoint struct { + Type string + Coordinates []float64 +} + +type VariantTest struct { + in map[string]interface{} + result bool + want VariantPoint +} + +var coords = []interface{}{1.0, 2.0} + +var variantTests = []VariantTest{ + { + in: map[string]interface{}{ + "type": "Point", + "coordinates": coords, + }, + result: true, + want: VariantPoint{ + Type: "Point", + Coordinates: []float64{1.0, 2.0}, + }, + }, + { + in: map[string]interface{}{ + "type": "Point", + "bogus": coords, + }, + result: true, + want: VariantPoint{ + Type: "Point", + }, + }, +} + +func TestVariantType(t *testing.T) { + for _, test := range variantTests { + if g := VariantType(test.in); g != test.want.Type { + t.Errorf("VariantType(%v): got %v, want %v", test.in, g, test.want.Type) + } + } +} + +func TestConvertVariant(t *testing.T) { + for _, test := range variantTests { + g := VariantPoint{} + r := ConvertVariant(test.in, &g) + if r != test.result { + t.Errorf("ConvertVariant(%v): got %v, want %v", test.in, r, test.result) + } + if !reflect.DeepEqual(g, test.want) { + t.Errorf("ConvertVariant(%v): got %v, want %v", test.in, g, test.want) + } + } +} + +type unexpectedReader struct{} + +func (unexpectedReader) Read([]byte) (int, error) { + return 0, fmt.Errorf("unexpected read in test.") +} + +var contentRangeRE = regexp.MustCompile(`^bytes (\d+)\-(\d+)/(\d+)$`) + +func (t *testTransport) RoundTrip(req *http.Request) (*http.Response, error) { + t.req = req + if rng := req.Header.Get("Content-Range"); rng != "" && !strings.HasPrefix(rng, "bytes */") { // Read the data + m := contentRangeRE.FindStringSubmatch(rng) + if len(m) != 4 { + return nil, fmt.Errorf("unable to parse content range: %v", rng) + } + start, err := strconv.ParseInt(m[1], 10, 64) + if err != nil { + return nil, fmt.Errorf("unable to parse content range: %v", rng) + } + end, err := strconv.ParseInt(m[2], 10, 64) + if err != nil { + return nil, fmt.Errorf("unable to parse content range: %v", rng) + } + totalSize, err := strconv.ParseInt(m[3], 10, 64) + if err != nil { + return nil, fmt.Errorf("unable to parse content range: %v", rng) + } + partialSize := end - start + 1 + t.buf, err = ioutil.ReadAll(req.Body) + if err != nil || int64(len(t.buf)) != partialSize { + return nil, fmt.Errorf("unable to read %v bytes from request data, n=%v: %v", partialSize, len(t.buf), err) + } + if totalSize == end+1 { + t.statusCode = 200 // signify completion of transfer + } + } + f := ioutil.NopCloser(unexpectedReader{}) + res := &http.Response{ + Body: f, + StatusCode: t.statusCode, + Header: http.Header{}, + } + if t.rangeVal != "" { + res.Header.Set("Range", t.rangeVal) + } + return res, nil +} + +type testTransport struct { + req *http.Request + statusCode int + rangeVal string + want int64 + buf []byte +} + +var statusTests = []*testTransport{ + &testTransport{statusCode: 308, want: 0}, + &testTransport{statusCode: 308, rangeVal: "bytes=0-0", want: 1}, + &testTransport{statusCode: 308, rangeVal: "bytes=0-42", want: 43}, +} + +func TestTransferStatus(t *testing.T) { + ctx := context.Background() + for _, tr := range statusTests { + rx := &ResumableUpload{ + Client: &http.Client{Transport: tr}, + } + g, _, err := rx.transferStatus(ctx) + if err != nil { + t.Error(err) + } + if g != tr.want { + t.Errorf("transferStatus got %v, want %v", g, tr.want) + } + } +} + +func (t *interruptedTransport) RoundTrip(req *http.Request) (*http.Response, error) { + t.req = req + if rng := req.Header.Get("Content-Range"); rng != "" && !strings.HasPrefix(rng, "bytes */") { + t.interruptCount += 1 + if t.interruptCount%7 == 0 { // Respond with a "service unavailable" error + res := &http.Response{ + StatusCode: http.StatusServiceUnavailable, + Header: http.Header{}, + } + t.rangeVal = fmt.Sprintf("bytes=0-%v", len(t.buf)-1) // Set the response for next time + return res, nil + } + m := contentRangeRE.FindStringSubmatch(rng) + if len(m) != 4 { + return nil, fmt.Errorf("unable to parse content range: %v", rng) + } + start, err := strconv.ParseInt(m[1], 10, 64) + if err != nil { + return nil, fmt.Errorf("unable to parse content range: %v", rng) + } + end, err := strconv.ParseInt(m[2], 10, 64) + if err != nil { + return nil, fmt.Errorf("unable to parse content range: %v", rng) + } + totalSize, err := strconv.ParseInt(m[3], 10, 64) + if err != nil { + return nil, fmt.Errorf("unable to parse content range: %v", rng) + } + partialSize := end - start + 1 + buf, err := ioutil.ReadAll(req.Body) + if err != nil || int64(len(buf)) != partialSize { + return nil, fmt.Errorf("unable to read %v bytes from request data, n=%v: %v", partialSize, len(buf), err) + } + t.buf = append(t.buf, buf...) + if totalSize == end+1 { + t.statusCode = 200 // signify completion of transfer + } + } + f := ioutil.NopCloser(unexpectedReader{}) + res := &http.Response{ + Body: f, + StatusCode: t.statusCode, + Header: http.Header{}, + } + if t.rangeVal != "" { + res.Header.Set("Range", t.rangeVal) + } + return res, nil +} + +type interruptedTransport struct { + req *http.Request + statusCode int + rangeVal string + interruptCount int + buf []byte + progressBuf string +} + +func (tr *interruptedTransport) ProgressUpdate(current, total int64) { + tr.progressBuf += fmt.Sprintf("%v, %v\n", current, total) +} + +func TestInterruptedTransferChunks(t *testing.T) { + f, err := os.Open("googleapi.go") + if err != nil { + t.Fatalf("unable to open googleapi.go: %v", err) + } + defer f.Close() + slurp, err := ioutil.ReadAll(f) + if err != nil { + t.Fatalf("unable to slurp file: %v", err) + } + st, err := f.Stat() + if err != nil { + t.Fatalf("unable to stat googleapi.go: %v", err) + } + tr := &interruptedTransport{ + statusCode: 308, + buf: make([]byte, 0, st.Size()), + } + oldChunkSize := chunkSize + defer func() { chunkSize = oldChunkSize }() + chunkSize = 100 // override to process small chunks for test. + + sleep = func(time.Duration) {} // override time.Sleep + rx := &ResumableUpload{ + Client: &http.Client{Transport: tr}, + Media: f, + MediaType: "text/plain", + ContentLength: st.Size(), + Callback: tr.ProgressUpdate, + } + res, err := rx.Upload(context.Background()) + if err != nil || res == nil || res.StatusCode != http.StatusOK { + if res == nil { + t.Errorf("transferChunks not successful, res=nil: %v", err) + } else { + t.Errorf("transferChunks not successful, statusCode=%v: %v", res.StatusCode, err) + } + } + if len(tr.buf) != len(slurp) || bytes.Compare(tr.buf, slurp) != 0 { + t.Errorf("transferred file corrupted:\ngot %s\nwant %s", tr.buf, slurp) + } + w := "" + for i := chunkSize; i <= st.Size(); i += chunkSize { + w += fmt.Sprintf("%v, %v\n", i, st.Size()) + } + if st.Size()%chunkSize != 0 { + w += fmt.Sprintf("%v, %v\n", st.Size(), st.Size()) + } + if tr.progressBuf != w { + t.Errorf("progress update error, got %v, want %v", tr.progressBuf, w) + } +} + +func TestCancelUpload(t *testing.T) { + f, err := os.Open("googleapi.go") + if err != nil { + t.Fatalf("unable to open googleapi.go: %v", err) + } + defer f.Close() + st, err := f.Stat() + if err != nil { + t.Fatalf("unable to stat googleapi.go: %v", err) + } + tr := &interruptedTransport{ + statusCode: 308, + buf: make([]byte, 0, st.Size()), + } + oldChunkSize := chunkSize + defer func() { chunkSize = oldChunkSize }() + chunkSize = 100 // override to process small chunks for test. + + sleep = func(time.Duration) {} // override time.Sleep + rx := &ResumableUpload{ + Client: &http.Client{Transport: tr}, + Media: f, + MediaType: "text/plain", + ContentLength: st.Size(), + Callback: tr.ProgressUpdate, + } + ctx, cancelFunc := context.WithCancel(context.Background()) + cancelFunc() // stop the upload that hasn't started yet + res, err := rx.Upload(ctx) + if err == nil || res == nil || res.StatusCode != http.StatusRequestTimeout { + if res == nil { + t.Errorf("transferChunks not successful, got res=nil, err=%v, want StatusRequestTimeout", err) + } else { + t.Errorf("transferChunks not successful, got statusCode=%v, err=%v, want StatusRequestTimeout", res.StatusCode, err) + } + } +} diff --git a/_third_party/google.golang.org/api/googleapi/internal/uritemplates/LICENSE b/_third_party/google.golang.org/api/googleapi/internal/uritemplates/LICENSE new file mode 100644 index 0000000000..de9c88cb65 --- /dev/null +++ b/_third_party/google.golang.org/api/googleapi/internal/uritemplates/LICENSE @@ -0,0 +1,18 @@ +Copyright (c) 2013 Joshua Tacoma + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/_third_party/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go b/_third_party/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go new file mode 100644 index 0000000000..8a84813fe5 --- /dev/null +++ b/_third_party/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go @@ -0,0 +1,359 @@ +// Copyright 2013 Joshua Tacoma. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package uritemplates is a level 4 implementation of RFC 6570 (URI +// Template, http://tools.ietf.org/html/rfc6570). +// +// To use uritemplates, parse a template string and expand it with a value +// map: +// +// template, _ := uritemplates.Parse("https://api.github.com/repos{/user,repo}") +// values := make(map[string]interface{}) +// values["user"] = "jtacoma" +// values["repo"] = "uritemplates" +// expanded, _ := template.ExpandString(values) +// fmt.Printf(expanded) +// +package uritemplates + +import ( + "bytes" + "errors" + "fmt" + "reflect" + "regexp" + "strconv" + "strings" +) + +var ( + unreserved = regexp.MustCompile("[^A-Za-z0-9\\-._~]") + reserved = regexp.MustCompile("[^A-Za-z0-9\\-._~:/?#[\\]@!$&'()*+,;=]") + validname = regexp.MustCompile("^([A-Za-z0-9_\\.]|%[0-9A-Fa-f][0-9A-Fa-f])+$") + hex = []byte("0123456789ABCDEF") +) + +func pctEncode(src []byte) []byte { + dst := make([]byte, len(src)*3) + for i, b := range src { + buf := dst[i*3 : i*3+3] + buf[0] = 0x25 + buf[1] = hex[b/16] + buf[2] = hex[b%16] + } + return dst +} + +func escape(s string, allowReserved bool) (escaped string) { + if allowReserved { + escaped = string(reserved.ReplaceAllFunc([]byte(s), pctEncode)) + } else { + escaped = string(unreserved.ReplaceAllFunc([]byte(s), pctEncode)) + } + return escaped +} + +// A UriTemplate is a parsed representation of a URI template. +type UriTemplate struct { + raw string + parts []templatePart +} + +// Parse parses a URI template string into a UriTemplate object. +func Parse(rawtemplate string) (template *UriTemplate, err error) { + template = new(UriTemplate) + template.raw = rawtemplate + split := strings.Split(rawtemplate, "{") + template.parts = make([]templatePart, len(split)*2-1) + for i, s := range split { + if i == 0 { + if strings.Contains(s, "}") { + err = errors.New("unexpected }") + break + } + template.parts[i].raw = s + } else { + subsplit := strings.Split(s, "}") + if len(subsplit) != 2 { + err = errors.New("malformed template") + break + } + expression := subsplit[0] + template.parts[i*2-1], err = parseExpression(expression) + if err != nil { + break + } + template.parts[i*2].raw = subsplit[1] + } + } + if err != nil { + template = nil + } + return template, err +} + +type templatePart struct { + raw string + terms []templateTerm + first string + sep string + named bool + ifemp string + allowReserved bool +} + +type templateTerm struct { + name string + explode bool + truncate int +} + +func parseExpression(expression string) (result templatePart, err error) { + switch expression[0] { + case '+': + result.sep = "," + result.allowReserved = true + expression = expression[1:] + case '.': + result.first = "." + result.sep = "." + expression = expression[1:] + case '/': + result.first = "/" + result.sep = "/" + expression = expression[1:] + case ';': + result.first = ";" + result.sep = ";" + result.named = true + expression = expression[1:] + case '?': + result.first = "?" + result.sep = "&" + result.named = true + result.ifemp = "=" + expression = expression[1:] + case '&': + result.first = "&" + result.sep = "&" + result.named = true + result.ifemp = "=" + expression = expression[1:] + case '#': + result.first = "#" + result.sep = "," + result.allowReserved = true + expression = expression[1:] + default: + result.sep = "," + } + rawterms := strings.Split(expression, ",") + result.terms = make([]templateTerm, len(rawterms)) + for i, raw := range rawterms { + result.terms[i], err = parseTerm(raw) + if err != nil { + break + } + } + return result, err +} + +func parseTerm(term string) (result templateTerm, err error) { + if strings.HasSuffix(term, "*") { + result.explode = true + term = term[:len(term)-1] + } + split := strings.Split(term, ":") + if len(split) == 1 { + result.name = term + } else if len(split) == 2 { + result.name = split[0] + var parsed int64 + parsed, err = strconv.ParseInt(split[1], 10, 0) + result.truncate = int(parsed) + } else { + err = errors.New("multiple colons in same term") + } + if !validname.MatchString(result.name) { + err = errors.New("not a valid name: " + result.name) + } + if result.explode && result.truncate > 0 { + err = errors.New("both explode and prefix modifers on same term") + } + return result, err +} + +// Expand expands a URI template with a set of values to produce a string. +func (self *UriTemplate) Expand(value interface{}) (string, error) { + values, ismap := value.(map[string]interface{}) + if !ismap { + if m, ismap := struct2map(value); !ismap { + return "", errors.New("expected map[string]interface{}, struct, or pointer to struct.") + } else { + return self.Expand(m) + } + } + var buf bytes.Buffer + for _, p := range self.parts { + err := p.expand(&buf, values) + if err != nil { + return "", err + } + } + return buf.String(), nil +} + +func (self *templatePart) expand(buf *bytes.Buffer, values map[string]interface{}) error { + if len(self.raw) > 0 { + buf.WriteString(self.raw) + return nil + } + var zeroLen = buf.Len() + buf.WriteString(self.first) + var firstLen = buf.Len() + for _, term := range self.terms { + value, exists := values[term.name] + if !exists { + continue + } + if buf.Len() != firstLen { + buf.WriteString(self.sep) + } + switch v := value.(type) { + case string: + self.expandString(buf, term, v) + case []interface{}: + self.expandArray(buf, term, v) + case map[string]interface{}: + if term.truncate > 0 { + return errors.New("cannot truncate a map expansion") + } + self.expandMap(buf, term, v) + default: + if m, ismap := struct2map(value); ismap { + if term.truncate > 0 { + return errors.New("cannot truncate a map expansion") + } + self.expandMap(buf, term, m) + } else { + str := fmt.Sprintf("%v", value) + self.expandString(buf, term, str) + } + } + } + if buf.Len() == firstLen { + original := buf.Bytes()[:zeroLen] + buf.Reset() + buf.Write(original) + } + return nil +} + +func (self *templatePart) expandName(buf *bytes.Buffer, name string, empty bool) { + if self.named { + buf.WriteString(name) + if empty { + buf.WriteString(self.ifemp) + } else { + buf.WriteString("=") + } + } +} + +func (self *templatePart) expandString(buf *bytes.Buffer, t templateTerm, s string) { + if len(s) > t.truncate && t.truncate > 0 { + s = s[:t.truncate] + } + self.expandName(buf, t.name, len(s) == 0) + buf.WriteString(escape(s, self.allowReserved)) +} + +func (self *templatePart) expandArray(buf *bytes.Buffer, t templateTerm, a []interface{}) { + if len(a) == 0 { + return + } else if !t.explode { + self.expandName(buf, t.name, false) + } + for i, value := range a { + if t.explode && i > 0 { + buf.WriteString(self.sep) + } else if i > 0 { + buf.WriteString(",") + } + var s string + switch v := value.(type) { + case string: + s = v + default: + s = fmt.Sprintf("%v", v) + } + if len(s) > t.truncate && t.truncate > 0 { + s = s[:t.truncate] + } + if self.named && t.explode { + self.expandName(buf, t.name, len(s) == 0) + } + buf.WriteString(escape(s, self.allowReserved)) + } +} + +func (self *templatePart) expandMap(buf *bytes.Buffer, t templateTerm, m map[string]interface{}) { + if len(m) == 0 { + return + } + if !t.explode { + self.expandName(buf, t.name, len(m) == 0) + } + var firstLen = buf.Len() + for k, value := range m { + if firstLen != buf.Len() { + if t.explode { + buf.WriteString(self.sep) + } else { + buf.WriteString(",") + } + } + var s string + switch v := value.(type) { + case string: + s = v + default: + s = fmt.Sprintf("%v", v) + } + if t.explode { + buf.WriteString(escape(k, self.allowReserved)) + buf.WriteRune('=') + buf.WriteString(escape(s, self.allowReserved)) + } else { + buf.WriteString(escape(k, self.allowReserved)) + buf.WriteRune(',') + buf.WriteString(escape(s, self.allowReserved)) + } + } +} + +func struct2map(v interface{}) (map[string]interface{}, bool) { + value := reflect.ValueOf(v) + switch value.Type().Kind() { + case reflect.Ptr: + return struct2map(value.Elem().Interface()) + case reflect.Struct: + m := make(map[string]interface{}) + for i := 0; i < value.NumField(); i++ { + tag := value.Type().Field(i).Tag + var name string + if strings.Contains(string(tag), ":") { + name = tag.Get("uri") + } else { + name = strings.TrimSpace(string(tag)) + } + if len(name) == 0 { + name = value.Type().Field(i).Name + } + m[name] = value.Field(i).Interface() + } + return m, true + } + return nil, false +} diff --git a/_third_party/google.golang.org/api/googleapi/internal/uritemplates/utils.go b/_third_party/google.golang.org/api/googleapi/internal/uritemplates/utils.go new file mode 100644 index 0000000000..399ef46236 --- /dev/null +++ b/_third_party/google.golang.org/api/googleapi/internal/uritemplates/utils.go @@ -0,0 +1,13 @@ +package uritemplates + +func Expand(path string, expansions map[string]string) (string, error) { + template, err := Parse(path) + if err != nil { + return "", err + } + values := make(map[string]interface{}) + for k, v := range expansions { + values[k] = v + } + return template.Expand(values) +} diff --git a/_third_party/google.golang.org/api/googleapi/types.go b/_third_party/google.golang.org/api/googleapi/types.go new file mode 100644 index 0000000000..a02b4b0716 --- /dev/null +++ b/_third_party/google.golang.org/api/googleapi/types.go @@ -0,0 +1,182 @@ +// Copyright 2013 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package googleapi + +import ( + "encoding/json" + "strconv" +) + +// Int64s is a slice of int64s that marshal as quoted strings in JSON. +type Int64s []int64 + +func (q *Int64s) UnmarshalJSON(raw []byte) error { + *q = (*q)[:0] + var ss []string + if err := json.Unmarshal(raw, &ss); err != nil { + return err + } + for _, s := range ss { + v, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return err + } + *q = append(*q, int64(v)) + } + return nil +} + +// Int32s is a slice of int32s that marshal as quoted strings in JSON. +type Int32s []int32 + +func (q *Int32s) UnmarshalJSON(raw []byte) error { + *q = (*q)[:0] + var ss []string + if err := json.Unmarshal(raw, &ss); err != nil { + return err + } + for _, s := range ss { + v, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return err + } + *q = append(*q, int32(v)) + } + return nil +} + +// Uint64s is a slice of uint64s that marshal as quoted strings in JSON. +type Uint64s []uint64 + +func (q *Uint64s) UnmarshalJSON(raw []byte) error { + *q = (*q)[:0] + var ss []string + if err := json.Unmarshal(raw, &ss); err != nil { + return err + } + for _, s := range ss { + v, err := strconv.ParseUint(s, 10, 64) + if err != nil { + return err + } + *q = append(*q, uint64(v)) + } + return nil +} + +// Uint32s is a slice of uint32s that marshal as quoted strings in JSON. +type Uint32s []uint32 + +func (q *Uint32s) UnmarshalJSON(raw []byte) error { + *q = (*q)[:0] + var ss []string + if err := json.Unmarshal(raw, &ss); err != nil { + return err + } + for _, s := range ss { + v, err := strconv.ParseUint(s, 10, 32) + if err != nil { + return err + } + *q = append(*q, uint32(v)) + } + return nil +} + +// Float64s is a slice of float64s that marshal as quoted strings in JSON. +type Float64s []float64 + +func (q *Float64s) UnmarshalJSON(raw []byte) error { + *q = (*q)[:0] + var ss []string + if err := json.Unmarshal(raw, &ss); err != nil { + return err + } + for _, s := range ss { + v, err := strconv.ParseFloat(s, 64) + if err != nil { + return err + } + *q = append(*q, float64(v)) + } + return nil +} + +func quotedList(n int, fn func(dst []byte, i int) []byte) ([]byte, error) { + dst := make([]byte, 0, 2+n*10) // somewhat arbitrary + dst = append(dst, '[') + for i := 0; i < n; i++ { + if i > 0 { + dst = append(dst, ',') + } + dst = append(dst, '"') + dst = fn(dst, i) + dst = append(dst, '"') + } + dst = append(dst, ']') + return dst, nil +} + +func (s Int64s) MarshalJSON() ([]byte, error) { + return quotedList(len(s), func(dst []byte, i int) []byte { + return strconv.AppendInt(dst, s[i], 10) + }) +} + +func (s Int32s) MarshalJSON() ([]byte, error) { + return quotedList(len(s), func(dst []byte, i int) []byte { + return strconv.AppendInt(dst, int64(s[i]), 10) + }) +} + +func (s Uint64s) MarshalJSON() ([]byte, error) { + return quotedList(len(s), func(dst []byte, i int) []byte { + return strconv.AppendUint(dst, s[i], 10) + }) +} + +func (s Uint32s) MarshalJSON() ([]byte, error) { + return quotedList(len(s), func(dst []byte, i int) []byte { + return strconv.AppendUint(dst, uint64(s[i]), 10) + }) +} + +func (s Float64s) MarshalJSON() ([]byte, error) { + return quotedList(len(s), func(dst []byte, i int) []byte { + return strconv.AppendFloat(dst, s[i], 'g', -1, 64) + }) +} + +/* + * Helper routines for simplifying the creation of optional fields of basic type. + */ + +// Bool is a helper routine that allocates a new bool value +// to store v and returns a pointer to it. +func Bool(v bool) *bool { return &v } + +// Int32 is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it. +func Int32(v int32) *int32 { return &v } + +// Int64 is a helper routine that allocates a new int64 value +// to store v and returns a pointer to it. +func Int64(v int64) *int64 { return &v } + +// Float64 is a helper routine that allocates a new float64 value +// to store v and returns a pointer to it. +func Float64(v float64) *float64 { return &v } + +// Uint32 is a helper routine that allocates a new uint32 value +// to store v and returns a pointer to it. +func Uint32(v uint32) *uint32 { return &v } + +// Uint64 is a helper routine that allocates a new uint64 value +// to store v and returns a pointer to it. +func Uint64(v uint64) *uint64 { return &v } + +// String is a helper routine that allocates a new string value +// to store v and returns a pointer to it. +func String(v string) *string { return &v } diff --git a/_third_party/google.golang.org/api/googleapi/types_test.go b/_third_party/google.golang.org/api/googleapi/types_test.go new file mode 100644 index 0000000000..a6b2045156 --- /dev/null +++ b/_third_party/google.golang.org/api/googleapi/types_test.go @@ -0,0 +1,44 @@ +// Copyright 2013 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package googleapi + +import ( + "encoding/json" + "reflect" + "testing" +) + +func TestTypes(t *testing.T) { + type T struct { + I32 Int32s + I64 Int64s + U32 Uint32s + U64 Uint64s + F64 Float64s + } + v := &T{ + I32: Int32s{-1, 2, 3}, + I64: Int64s{-1, 2, 1 << 33}, + U32: Uint32s{1, 2}, + U64: Uint64s{1, 2, 1 << 33}, + F64: Float64s{1.5, 3.33}, + } + got, err := json.Marshal(v) + if err != nil { + t.Fatal(err) + } + want := `{"I32":["-1","2","3"],"I64":["-1","2","8589934592"],"U32":["1","2"],"U64":["1","2","8589934592"],"F64":["1.5","3.33"]}` + if string(got) != want { + t.Fatalf("Marshal mismatch.\n got: %s\nwant: %s\n", got, want) + } + + v2 := new(T) + if err := json.Unmarshal(got, v2); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if !reflect.DeepEqual(v, v2) { + t.Fatalf("Unmarshal didn't produce same results.\n got: %#v\nwant: %#v\n", v, v2) + } +} diff --git a/_third_party/google.golang.org/api/internal/json.go b/_third_party/google.golang.org/api/internal/json.go new file mode 100644 index 0000000000..64eb0a1610 --- /dev/null +++ b/_third_party/google.golang.org/api/internal/json.go @@ -0,0 +1,173 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package internal contains common code shared by all Google API libraries which is not exported to users of the libraries. +package internal + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" +) + +// MarshalJSON returns a JSON encoding of schema containing only selected fields. +// A field is selected if: +// * it has a non-empty value, or +// * its field name is present in forceSendFields, and +// * it is not a nil pointer or nil interface. +// The JSON key for each selected field is taken from the field's json: struct tag. +func MarshalJSON(schema interface{}, forceSendFields []string) ([]byte, error) { + if len(forceSendFields) == 0 { + return json.Marshal(schema) + } + + mustInclude := make(map[string]struct{}) + for _, f := range forceSendFields { + mustInclude[f] = struct{}{} + } + + dataMap, err := schemaToMap(schema, mustInclude) + if err != nil { + return nil, err + } + return json.Marshal(dataMap) +} + +func schemaToMap(schema interface{}, mustInclude map[string]struct{}) (map[string]interface{}, error) { + m := make(map[string]interface{}) + s := reflect.ValueOf(schema) + st := s.Type() + + for i := 0; i < s.NumField(); i++ { + jsonTag := st.Field(i).Tag.Get("json") + if jsonTag == "" { + continue + } + tag, err := parseJSONTag(jsonTag) + if err != nil { + return nil, err + } + if tag.ignore { + continue + } + + v := s.Field(i) + f := st.Field(i) + if !includeField(v, f, mustInclude) { + continue + } + + // nil maps are treated as empty maps. + if f.Type.Kind() == reflect.Map && v.IsNil() { + m[tag.apiName] = map[string]string{} + continue + } + + // nil slices are treated as empty slices. + if f.Type.Kind() == reflect.Slice && v.IsNil() { + m[tag.apiName] = []bool{} + continue + } + + if tag.stringFormat { + m[tag.apiName] = formatAsString(v, f.Type.Kind()) + } else { + m[tag.apiName] = v.Interface() + } + } + return m, nil +} + +// formatAsString returns a string representation of v, dereferencing it first if possible. +func formatAsString(v reflect.Value, kind reflect.Kind) string { + if kind == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + + return fmt.Sprintf("%v", v.Interface()) +} + +// jsonTag represents a restricted version of the struct tag format used by encoding/json. +// It is used to describe the JSON encoding of fields in a Schema struct. +type jsonTag struct { + apiName string + stringFormat bool + ignore bool +} + +// parseJSONTag parses a restricted version of the struct tag format used by encoding/json. +// The format of the tag must match that generated by the Schema.writeSchemaStruct method +// in the api generator. +func parseJSONTag(val string) (jsonTag, error) { + if val == "-" { + return jsonTag{ignore: true}, nil + } + + var tag jsonTag + + i := strings.Index(val, ",") + if i == -1 || val[:i] == "" { + return tag, fmt.Errorf("malformed json tag: %s", val) + } + + tag = jsonTag{ + apiName: val[:i], + } + + switch val[i+1:] { + case "omitempty": + case "omitempty,string": + tag.stringFormat = true + default: + return tag, fmt.Errorf("malformed json tag: %s", val) + } + + return tag, nil +} + +// Reports whether the struct field "f" with value "v" should be included in JSON output. +func includeField(v reflect.Value, f reflect.StructField, mustInclude map[string]struct{}) bool { + // The regular JSON encoding of a nil pointer is "null", which means "delete this field". + // Therefore, we could enable field deletion by honoring pointer fields' presence in the mustInclude set. + // However, many fields are not pointers, so there would be no way to delete these fields. + // Rather than partially supporting field deletion, we ignore mustInclude for nil pointer fields. + // Deletion will be handled by a separate mechanism. + if f.Type.Kind() == reflect.Ptr && v.IsNil() { + return false + } + + // The "any" type is represented as an interface{}. If this interface + // is nil, there is no reasonable representation to send. We ignore + // these fields, for the same reasons as given above for pointers. + if f.Type.Kind() == reflect.Interface && v.IsNil() { + return false + } + + _, ok := mustInclude[f.Name] + return ok || !isEmptyValue(v) +} + +// isEmptyValue reports whether v is the empty value for its type. This +// implementation is based on that of the encoding/json package, but its +// correctness does not depend on it being identical. What's important is that +// this function return false in situations where v should not be sent as part +// of a PATCH operation. +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + return false +} diff --git a/_third_party/google.golang.org/api/internal/json_test.go b/_third_party/google.golang.org/api/internal/json_test.go new file mode 100644 index 0000000000..d6c1fe81a4 --- /dev/null +++ b/_third_party/google.golang.org/api/internal/json_test.go @@ -0,0 +1,367 @@ +// Copyright 2015 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package internal + +import ( + "encoding/json" + "reflect" + "testing" + + "bosun.org/_third_party/google.golang.org/api/googleapi" +) + +type schema struct { + // Basic types + B bool `json:"b,omitempty"` + F float64 `json:"f,omitempty"` + I int64 `json:"i,omitempty"` + Istr int64 `json:"istr,omitempty,string"` + Str string `json:"str,omitempty"` + + // Pointers to basic types + PB *bool `json:"pb,omitempty"` + PF *float64 `json:"pf,omitempty"` + PI *int64 `json:"pi,omitempty"` + PIStr *int64 `json:"pistr,omitempty,string"` + PStr *string `json:"pstr,omitempty"` + + // Other types + Int64s googleapi.Int64s `json:"i64s,omitempty"` + S []int `json:"s,omitempty"` + M map[string]string `json:"m,omitempty"` + Any interface{} `json:"any,omitempty"` + Child *child `json:"child,omitempty"` + + ForceSendFields []string `json:"-"` +} + +type child struct { + B bool `json:"childbool,omitempty"` +} + +type testCase struct { + s schema + want string +} + +func TestBasics(t *testing.T) { + for _, tc := range []testCase{ + { + s: schema{}, + want: `{}`, + }, + { + s: schema{ + ForceSendFields: []string{"B", "F", "I", "Istr", "Str", "PB", "PF", "PI", "PIStr", "PStr"}, + }, + want: `{"b":false,"f":0.0,"i":0,"istr":"0","str":""}`, + }, + { + s: schema{ + B: true, + F: 1.2, + I: 1, + Istr: 2, + Str: "a", + PB: googleapi.Bool(true), + PF: googleapi.Float64(1.2), + PI: googleapi.Int64(int64(1)), + PIStr: googleapi.Int64(int64(2)), + PStr: googleapi.String("a"), + }, + want: `{"b":true,"f":1.2,"i":1,"istr":"2","str":"a","pb":true,"pf":1.2,"pi":1,"pistr":"2","pstr":"a"}`, + }, + { + s: schema{ + B: false, + F: 0.0, + I: 0, + Istr: 0, + Str: "", + PB: googleapi.Bool(false), + PF: googleapi.Float64(0.0), + PI: googleapi.Int64(int64(0)), + PIStr: googleapi.Int64(int64(0)), + PStr: googleapi.String(""), + }, + want: `{"pb":false,"pf":0.0,"pi":0,"pistr":"0","pstr":""}`, + }, + { + s: schema{ + B: false, + F: 0.0, + I: 0, + Istr: 0, + Str: "", + PB: googleapi.Bool(false), + PF: googleapi.Float64(0.0), + PI: googleapi.Int64(int64(0)), + PIStr: googleapi.Int64(int64(0)), + PStr: googleapi.String(""), + ForceSendFields: []string{"B", "F", "I", "Istr", "Str", "PB", "PF", "PI", "PIStr", "PStr"}, + }, + want: `{"b":false,"f":0.0,"i":0,"istr":"0","str":"","pb":false,"pf":0.0,"pi":0,"pistr":"0","pstr":""}`, + }, + } { + checkMarshalJSON(t, tc) + } +} + +func TestSliceFields(t *testing.T) { + for _, tc := range []testCase{ + { + s: schema{}, + want: `{}`, + }, + { + s: schema{S: []int{}, Int64s: googleapi.Int64s{}}, + want: `{}`, + }, + { + s: schema{S: []int{1}, Int64s: googleapi.Int64s{1}}, + want: `{"s":[1],"i64s":["1"]}`, + }, + { + s: schema{ + ForceSendFields: []string{"S", "Int64s"}, + }, + want: `{"s":[],"i64s":[]}`, + }, + { + s: schema{ + S: []int{}, + Int64s: googleapi.Int64s{}, + ForceSendFields: []string{"S", "Int64s"}, + }, + want: `{"s":[],"i64s":[]}`, + }, + { + s: schema{ + S: []int{1}, + Int64s: googleapi.Int64s{1}, + ForceSendFields: []string{"S", "Int64s"}, + }, + want: `{"s":[1],"i64s":["1"]}`, + }, + } { + checkMarshalJSON(t, tc) + } +} + +func TestMapField(t *testing.T) { + for _, tc := range []testCase{ + { + s: schema{}, + want: `{}`, + }, + { + s: schema{M: make(map[string]string)}, + want: `{}`, + }, + { + s: schema{M: map[string]string{"a": "b"}}, + want: `{"m":{"a":"b"}}`, + }, + { + s: schema{ + ForceSendFields: []string{"M"}, + }, + want: `{"m":{}}`, + }, + { + s: schema{ + M: make(map[string]string), + ForceSendFields: []string{"M"}, + }, + want: `{"m":{}}`, + }, + { + s: schema{ + M: map[string]string{"a": "b"}, + ForceSendFields: []string{"M"}, + }, + want: `{"m":{"a":"b"}}`, + }, + } { + checkMarshalJSON(t, tc) + } +} + +type anyType struct { + Field int +} + +func (a anyType) MarshalJSON() ([]byte, error) { + return []byte(`"anyType value"`), nil +} + +func TestAnyField(t *testing.T) { + // ForceSendFields has no effect on nil interfaces and interfaces that contain nil pointers. + var nilAny *anyType + for _, tc := range []testCase{ + { + s: schema{}, + want: `{}`, + }, + { + s: schema{Any: nilAny}, + want: `{"any": null}`, + }, + { + s: schema{Any: &anyType{}}, + want: `{"any":"anyType value"}`, + }, + { + s: schema{Any: anyType{}}, + want: `{"any":"anyType value"}`, + }, + { + s: schema{ + ForceSendFields: []string{"Any"}, + }, + want: `{}`, + }, + { + s: schema{ + Any: nilAny, + ForceSendFields: []string{"Any"}, + }, + want: `{"any": null}`, + }, + { + s: schema{ + Any: &anyType{}, + ForceSendFields: []string{"Any"}, + }, + want: `{"any":"anyType value"}`, + }, + { + s: schema{ + Any: anyType{}, + ForceSendFields: []string{"Any"}, + }, + want: `{"any":"anyType value"}`, + }, + } { + checkMarshalJSON(t, tc) + } +} + +func TestSubschema(t *testing.T) { + // Subschemas are always stored as pointers, so ForceSendFields has no effect on them. + for _, tc := range []testCase{ + { + s: schema{}, + want: `{}`, + }, + { + s: schema{ + ForceSendFields: []string{"Child"}, + }, + want: `{}`, + }, + { + s: schema{Child: &child{}}, + want: `{"child":{}}`, + }, + { + s: schema{ + Child: &child{}, + ForceSendFields: []string{"Child"}, + }, + want: `{"child":{}}`, + }, + { + s: schema{Child: &child{B: true}}, + want: `{"child":{"childbool":true}}`, + }, + + { + s: schema{ + Child: &child{B: true}, + ForceSendFields: []string{"Child"}, + }, + want: `{"child":{"childbool":true}}`, + }, + } { + checkMarshalJSON(t, tc) + } +} + +// checkMarshalJSON verifies that calling schemaToMap on tc.s yields a result which is equivalent to tc.want. +func checkMarshalJSON(t *testing.T, tc testCase) { + doCheckMarshalJSON(t, tc.s, tc.s.ForceSendFields, tc.want) + if len(tc.s.ForceSendFields) == 0 { + // verify that the code path used when ForceSendFields + // is non-empty produces the same output as the fast + // path that is used when it is empty. + doCheckMarshalJSON(t, tc.s, []string{"dummy"}, tc.want) + } +} + +func doCheckMarshalJSON(t *testing.T, s schema, forceSendFields []string, wantJSON string) { + encoded, err := MarshalJSON(s, forceSendFields) + if err != nil { + t.Fatalf("encoding json:\n got err: %v", err) + } + + // The expected and obtained JSON can differ in field ordering, so unmarshal before comparing. + var got interface{} + var want interface{} + err = json.Unmarshal(encoded, &got) + if err != nil { + t.Fatalf("decoding json:\n got err: %v", err) + } + err = json.Unmarshal([]byte(wantJSON), &want) + if err != nil { + t.Fatalf("decoding json:\n got err: %v", err) + } + if !reflect.DeepEqual(got, want) { + t.Errorf("schemaToMap:\ngot :%s\nwant:%s", got, want) + } +} + +func TestParseJSONTag(t *testing.T) { + for _, tc := range []struct { + tag string + want jsonTag + }{ + { + tag: "-", + want: jsonTag{ignore: true}, + }, { + tag: "name,omitempty", + want: jsonTag{apiName: "name"}, + }, { + tag: "name,omitempty,string", + want: jsonTag{apiName: "name", stringFormat: true}, + }, + } { + got, err := parseJSONTag(tc.tag) + if err != nil { + t.Fatalf("parsing json:\n got err: %v\ntag: %q", err, tc.tag) + } + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("parseJSONTage:\ngot :%s\nwant:%s", got, tc.want) + } + } +} +func TestParseMalformedJSONTag(t *testing.T) { + for _, tag := range []string{ + "", + "name", + "name,", + "name,blah", + "name,blah,string", + ",omitempty", + ",omitempty,string", + "name,omitempty,string,blah", + } { + _, err := parseJSONTag(tag) + if err == nil { + t.Fatalf("parsing json: expected err, got nil for tag: %v", tag) + } + } +} diff --git a/_third_party/google.golang.org/cloud/compute/metadata/go13.go b/_third_party/google.golang.org/cloud/compute/metadata/go13.go new file mode 100644 index 0000000000..c979f43906 --- /dev/null +++ b/_third_party/google.golang.org/cloud/compute/metadata/go13.go @@ -0,0 +1,37 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build go1.3 + +package metadata + +import ( + "net" + "time" +) + +// This is a workaround for https://github.com/golang/oauth2/issues/70, where +// net.Dialer.KeepAlive is unavailable on Go 1.2 (which App Engine as of +// Jan 2015 still runs). +// +// TODO(bradfitz,jbd,adg): remove this once App Engine supports Go +// 1.3+. +func init() { + go13Dialer = func() *net.Dialer { + return &net.Dialer{ + Timeout: 750 * time.Millisecond, + KeepAlive: 30 * time.Second, + } + } +} diff --git a/_third_party/google.golang.org/cloud/compute/metadata/metadata.go b/_third_party/google.golang.org/cloud/compute/metadata/metadata.go new file mode 100644 index 0000000000..a88d0176ac --- /dev/null +++ b/_third_party/google.golang.org/cloud/compute/metadata/metadata.go @@ -0,0 +1,267 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package metadata provides access to Google Compute Engine (GCE) +// metadata and API service accounts. +// +// This package is a wrapper around the GCE metadata service, +// as documented at https://developers.google.com/compute/docs/metadata. +package metadata + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net" + "net/http" + "strings" + "sync" + "time" + + "bosun.org/_third_party/google.golang.org/cloud/internal" +) + +type cachedValue struct { + k string + trim bool + mu sync.Mutex + v string +} + +var ( + projID = &cachedValue{k: "project/project-id", trim: true} + projNum = &cachedValue{k: "project/numeric-project-id", trim: true} + instID = &cachedValue{k: "instance/id", trim: true} +) + +var metaClient = &http.Client{ + Transport: &internal.Transport{ + Base: &http.Transport{ + Dial: dialer().Dial, + ResponseHeaderTimeout: 750 * time.Millisecond, + }, + }, +} + +// go13Dialer is nil until we're using Go 1.3+. +// This is a workaround for https://github.com/golang/oauth2/issues/70, where +// net.Dialer.KeepAlive is unavailable on Go 1.2 (which App Engine as of +// Jan 2015 still runs). +// +// TODO(bradfitz,jbd,adg,dsymonds): remove this once App Engine supports Go +// 1.3+ and go-app-builder also supports 1.3+, or when Go 1.2 is no longer an +// option on App Engine. +var go13Dialer func() *net.Dialer + +func dialer() *net.Dialer { + if fn := go13Dialer; fn != nil { + return fn() + } + return &net.Dialer{ + Timeout: 750 * time.Millisecond, + } +} + +// NotDefinedError is returned when requested metadata is not defined. +// +// The underlying string is the suffix after "/computeMetadata/v1/". +// +// This error is not returned if the value is defined to be the empty +// string. +type NotDefinedError string + +func (suffix NotDefinedError) Error() string { + return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix)) +} + +// Get returns a value from the metadata service. +// The suffix is appended to "http://metadata/computeMetadata/v1/". +// +// If the requested metadata is not defined, the returned error will +// be of type NotDefinedError. +func Get(suffix string) (string, error) { + // Using 169.254.169.254 instead of "metadata" here because Go + // binaries built with the "netgo" tag and without cgo won't + // know the search suffix for "metadata" is + // ".google.internal", and this IP address is documented as + // being stable anyway. + url := "http://169.254.169.254/computeMetadata/v1/" + suffix + req, _ := http.NewRequest("GET", url, nil) + req.Header.Set("Metadata-Flavor", "Google") + res, err := metaClient.Do(req) + if err != nil { + return "", err + } + defer res.Body.Close() + if res.StatusCode == http.StatusNotFound { + return "", NotDefinedError(suffix) + } + if res.StatusCode != 200 { + return "", fmt.Errorf("status code %d trying to fetch %s", res.StatusCode, url) + } + all, err := ioutil.ReadAll(res.Body) + if err != nil { + return "", err + } + return string(all), nil +} + +func getTrimmed(suffix string) (s string, err error) { + s, err = Get(suffix) + s = strings.TrimSpace(s) + return +} + +func (c *cachedValue) get() (v string, err error) { + defer c.mu.Unlock() + c.mu.Lock() + if c.v != "" { + return c.v, nil + } + if c.trim { + v, err = getTrimmed(c.k) + } else { + v, err = Get(c.k) + } + if err == nil { + c.v = v + } + return +} + +var onGCE struct { + sync.Mutex + set bool + v bool +} + +// OnGCE reports whether this process is running on Google Compute Engine. +func OnGCE() bool { + defer onGCE.Unlock() + onGCE.Lock() + if onGCE.set { + return onGCE.v + } + onGCE.set = true + + // We use the DNS name of the metadata service here instead of the IP address + // because we expect that to fail faster in the not-on-GCE case. + res, err := metaClient.Get("http://metadata.google.internal") + if err != nil { + return false + } + onGCE.v = res.Header.Get("Metadata-Flavor") == "Google" + return onGCE.v +} + +// ProjectID returns the current instance's project ID string. +func ProjectID() (string, error) { return projID.get() } + +// NumericProjectID returns the current instance's numeric project ID. +func NumericProjectID() (string, error) { return projNum.get() } + +// InternalIP returns the instance's primary internal IP address. +func InternalIP() (string, error) { + return getTrimmed("instance/network-interfaces/0/ip") +} + +// ExternalIP returns the instance's primary external (public) IP address. +func ExternalIP() (string, error) { + return getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip") +} + +// Hostname returns the instance's hostname. This will probably be of +// the form "INSTANCENAME.c.PROJECT.internal" but that isn't +// guaranteed. +// +// TODO: what is this defined to be? Docs say "The host name of the +// instance." +func Hostname() (string, error) { + return getTrimmed("network-interfaces/0/ip") +} + +// InstanceTags returns the list of user-defined instance tags, +// assigned when initially creating a GCE instance. +func InstanceTags() ([]string, error) { + var s []string + j, err := Get("instance/tags") + if err != nil { + return nil, err + } + if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil { + return nil, err + } + return s, nil +} + +// InstanceID returns the current VM's numeric instance ID. +func InstanceID() (string, error) { + return instID.get() +} + +// InstanceAttributes returns the list of user-defined attributes, +// assigned when initially creating a GCE VM instance. The value of an +// attribute can be obtained with InstanceAttributeValue. +func InstanceAttributes() ([]string, error) { return lines("instance/attributes/") } + +// ProjectAttributes returns the list of user-defined attributes +// applying to the project as a whole, not just this VM. The value of +// an attribute can be obtained with ProjectAttributeValue. +func ProjectAttributes() ([]string, error) { return lines("project/attributes/") } + +func lines(suffix string) ([]string, error) { + j, err := Get(suffix) + if err != nil { + return nil, err + } + s := strings.Split(strings.TrimSpace(j), "\n") + for i := range s { + s[i] = strings.TrimSpace(s[i]) + } + return s, nil +} + +// InstanceAttributeValue returns the value of the provided VM +// instance attribute. +// +// If the requested attribute is not defined, the returned error will +// be of type NotDefinedError. +// +// InstanceAttributeValue may return ("", nil) if the attribute was +// defined to be the empty string. +func InstanceAttributeValue(attr string) (string, error) { + return Get("instance/attributes/" + attr) +} + +// ProjectAttributeValue returns the value of the provided +// project attribute. +// +// If the requested attribute is not defined, the returned error will +// be of type NotDefinedError. +// +// ProjectAttributeValue may return ("", nil) if the attribute was +// defined to be the empty string. +func ProjectAttributeValue(attr string) (string, error) { + return Get("project/attributes/" + attr) +} + +// Scopes returns the service account scopes for the given account. +// The account may be empty or the string "default" to use the instance's +// main account. +func Scopes(serviceAccount string) ([]string, error) { + if serviceAccount == "" { + serviceAccount = "default" + } + return lines("instance/service-accounts/" + serviceAccount + "/scopes") +} diff --git a/_third_party/google.golang.org/cloud/internal/cloud.go b/_third_party/google.golang.org/cloud/internal/cloud.go new file mode 100644 index 0000000000..b0f82c8878 --- /dev/null +++ b/_third_party/google.golang.org/cloud/internal/cloud.go @@ -0,0 +1,128 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package internal provides support for the cloud packages. +// +// Users should not import this package directly. +package internal + +import ( + "fmt" + "net/http" + "sync" + + "bosun.org/_third_party/golang.org/x/net/context" +) + +type contextKey struct{} + +func WithContext(parent context.Context, projID string, c *http.Client) context.Context { + if c == nil { + panic("nil *http.Client passed to WithContext") + } + if projID == "" { + panic("empty project ID passed to WithContext") + } + return context.WithValue(parent, contextKey{}, &cloudContext{ + ProjectID: projID, + HTTPClient: c, + }) +} + +const userAgent = "gcloud-golang/0.1" + +type cloudContext struct { + ProjectID string + HTTPClient *http.Client + + mu sync.Mutex // guards svc + svc map[string]interface{} // e.g. "storage" => *rawStorage.Service +} + +// Service returns the result of the fill function if it's never been +// called before for the given name (which is assumed to be an API +// service name, like "datastore"). If it has already been cached, the fill +// func is not run. +// It's safe for concurrent use by multiple goroutines. +func Service(ctx context.Context, name string, fill func(*http.Client) interface{}) interface{} { + return cc(ctx).service(name, fill) +} + +func (c *cloudContext) service(name string, fill func(*http.Client) interface{}) interface{} { + c.mu.Lock() + defer c.mu.Unlock() + + if c.svc == nil { + c.svc = make(map[string]interface{}) + } else if v, ok := c.svc[name]; ok { + return v + } + v := fill(c.HTTPClient) + c.svc[name] = v + return v +} + +// Transport is an http.RoundTripper that appends +// Google Cloud client's user-agent to the original +// request's user-agent header. +type Transport struct { + // Base represents the actual http.RoundTripper + // the requests will be delegated to. + Base http.RoundTripper +} + +// RoundTrip appends a user-agent to the existing user-agent +// header and delegates the request to the base http.RoundTripper. +func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { + req = cloneRequest(req) + ua := req.Header.Get("User-Agent") + if ua == "" { + ua = userAgent + } else { + ua = fmt.Sprintf("%s %s", ua, userAgent) + } + req.Header.Set("User-Agent", ua) + return t.Base.RoundTrip(req) +} + +// cloneRequest returns a clone of the provided *http.Request. +// The clone is a shallow copy of the struct and its Header map. +func cloneRequest(r *http.Request) *http.Request { + // shallow copy of the struct + r2 := new(http.Request) + *r2 = *r + // deep copy of the Header + r2.Header = make(http.Header) + for k, s := range r.Header { + r2.Header[k] = s + } + return r2 +} + +func ProjID(ctx context.Context) string { + return cc(ctx).ProjectID +} + +func HTTPClient(ctx context.Context) *http.Client { + return cc(ctx).HTTPClient +} + +// cc returns the internal *cloudContext (cc) state for a context.Context. +// It panics if the user did it wrong. +func cc(ctx context.Context) *cloudContext { + if c, ok := ctx.Value(contextKey{}).(*cloudContext); ok { + return c + } + panic("invalid context.Context type; it should be created with cloud.NewContext") +} From 2f392e58f2d435d3fa887c0ad3a1c5192e25e8d9 Mon Sep 17 00:00:00 2001 From: Jason Harvey Date: Mon, 26 Oct 2015 16:33:27 -0800 Subject: [PATCH 2/2] Add google_analytics collector. --- cmd/scollector/collectors/google_analytics.go | 110 ++++++++++++++++++ cmd/scollector/conf/conf.go | 14 +++ 2 files changed, 124 insertions(+) create mode 100644 cmd/scollector/collectors/google_analytics.go diff --git a/cmd/scollector/collectors/google_analytics.go b/cmd/scollector/collectors/google_analytics.go new file mode 100644 index 0000000000..ba70d009d6 --- /dev/null +++ b/cmd/scollector/collectors/google_analytics.go @@ -0,0 +1,110 @@ +package collectors + +import ( + "bytes" + "encoding/base64" + "encoding/gob" + "fmt" + "net/http" + "strconv" + "time" + + analytics "bosun.org/_third_party/google.golang.org/api/analytics/v3" + + "bosun.org/_third_party/golang.org/x/net/context" + "bosun.org/_third_party/golang.org/x/oauth2" + "bosun.org/_third_party/golang.org/x/oauth2/google" + "bosun.org/cmd/scollector/conf" + "bosun.org/metadata" + "bosun.org/opentsdb" +) + +func init() { + registerInit(func(c *conf.Conf) { + for _, g := range c.GoogleAnalytics { + collectors = append(collectors, &IntervalCollector{ + F: func() (opentsdb.MultiDataPoint, error) { + return c_google_analytics(g.ClientID, g.Secret, g.Token, g.Sites) + }, + name: "c_google_analytics", + Interval: time.Minute * 1, + }) + } + }) +} + +func c_google_analytics(clientid string, secret string, tokenstr string, sites []conf.GoogleAnalyticsSite) (opentsdb.MultiDataPoint, error) { + var md opentsdb.MultiDataPoint + + c, err := analyticsClient(clientid, secret, tokenstr) + if err != nil { + return nil, err + } + svc, err := analytics.New(c) + if err != nil { + return nil, err + } + + for _, site := range sites { + call := svc.Data.Realtime.Get("ga:"+site.Profile, "rt:pageviews").Dimensions("rt:minutesAgo") + data, err := call.Do() + if err != nil { + return md, err + } + + // If no offset was specified, the minute we care about is '1', or the most + // recently gathered, completed datapoint. Minute '0' is the current minute, + // and as such is incomplete. + offset := site.Offset + if offset == 0 { + offset = 1 + } + time := time.Now().Add(time.Duration(-1*offset) * time.Minute).Unix() + pageviews := 0 + // Iterates through the response data and returns the time slice we + // actually care about when we find it. + for _, row := range data.Rows { + // row == [2]string{"0", "123"} + // First item is the minute, second is the data (pageviews in this case) + minute, err := strconv.Atoi(row[0]) + if err != nil { + return md, fmt.Errorf("Error parsing GA data: %s", err) + } + if minute == offset { + if pageviews, err = strconv.Atoi(row[1]); err != nil { + return md, fmt.Errorf("Error parsing GA data: %s", err) + } + break + } + } + AddTS(&md, "google.analytics.realtime.pageviews", time, pageviews, opentsdb.TagSet{"site": site.Name}, metadata.Gauge, metadata.Count, "Number of pageviews tracked by GA in one minute") + } + + return md, err +} + +// analyticsClient() takes in a clientid, secret, and a base64'd gob representing the cached oauth token. +// Generating the token is left as an exercise to the reader. (TODO) +func analyticsClient(clientid string, secret string, tokenstr string) (*http.Client, error) { + ctx := context.Background() + + config := &oauth2.Config{ + ClientID: clientid, + ClientSecret: secret, + Endpoint: google.Endpoint, + Scopes: []string{analytics.AnalyticsScope}, + } + + token := new(oauth2.Token) + // Decode the base64'd gob + by, err := base64.StdEncoding.DecodeString(tokenstr) + if err != nil { + return nil, err + } + b := bytes.Buffer{} + b.Write(by) + d := gob.NewDecoder(&b) + err = d.Decode(&token) + + return config.Client(ctx, token), nil +} diff --git a/cmd/scollector/conf/conf.go b/cmd/scollector/conf/conf.go index 97165a782d..4a048c41fd 100644 --- a/cmd/scollector/conf/conf.go +++ b/cmd/scollector/conf/conf.go @@ -51,6 +51,7 @@ type Conf struct { ElasticIndexFilters []string RabbitMQ []RabbitMQ Nexpose []Nexpose + GoogleAnalytics []GoogleAnalytics } type HAProxy struct { @@ -71,6 +72,19 @@ type Nexpose struct { Insecure bool } +type GoogleAnalytics struct { + ClientID string + Secret string + Token string + Sites []GoogleAnalyticsSite +} + +type GoogleAnalyticsSite struct { + Name string + Profile string + Offset int +} + type ICMP struct { Host string }