ga-shikomi 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NThjZDViNTQ0MDRmNjZiMTBjMThjOWUyYWUyODcyMTZiZDg0YzI3Mw==
5
+ data.tar.gz: !binary |-
6
+ ZDhhM2U1MDgxMzIxZmFhZjM5NWRlNGYyYWQ3YTE1MmMwYjQzMjgyOQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YmUwYzJkMjc4NjdlODdjZjUyNTIwZDMwNThkN2U4NDFmOWYyMTQ1YTQyYmVh
10
+ MTYzMTBkYzQ2OWE3ZTRjYTczNmQ5YTQ3ZWJmOTg5ODhkZWNlZDA1ZjQwZWQ3
11
+ YmE1ZWUwZDYzYzY2YThmNjk1YmQ0YTVhMzYwYTRmODgzNDM2NDQ=
12
+ data.tar.gz: !binary |-
13
+ ZTQwYjJhOWU3N2RiYjExZDE1NWZmNTk4YjkyZDM0M2EwNDgxMzA0YjdjNmMz
14
+ M2E1ZmRkMmFlZmYwNGEyODNjYTg4ZmZhMmQzZjc5NGM2MWUzZmVkNGQyZDll
15
+ NDI5ZDNiOWNjOTE4YmEyY2YyYjRhYmZkODBkOTQ0NDJiMGY2OTY=
@@ -0,0 +1,7 @@
1
+ *~
2
+ /.bundle
3
+ /vendor
4
+ .ga-cli-credential
5
+ client_secrets.json
6
+ Gemfile.lock
7
+ /pkg/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # -*- mode: ruby -*-
2
+ source "https://rubygems.org"
3
+
4
+ gemspec
@@ -0,0 +1,33 @@
1
+ # GAShikomi
2
+
3
+ Google Analytics API wrapper for CLI written in Ruby.
4
+
5
+ ## Installation
6
+
7
+ Now, You can fetch general ga data.
8
+
9
+ ```ruby
10
+ gem 'ga-shikomi'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install ga-shikomi
20
+
21
+ ## Usage
22
+
23
+ type
24
+
25
+ shikomi help
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it ( https://github.com/[my-github-username]/ga-cli/fork )
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create a new Pull Request
@@ -0,0 +1,8 @@
1
+ # -*- mode: ruby -*-
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:spec) do |t|
7
+ t.pattern = 'spec/**/*_spec.rb'
8
+ end
@@ -0,0 +1,5 @@
1
+ #! /usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+
4
+ require_relative '../lib/ga_shikomi'
5
+ GAShikomi::Command.start
@@ -0,0 +1,30 @@
1
+ # -*- mode: ruby; coding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ga_shikomi/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ga-shikomi"
8
+ spec.version = GAShikomi::VERSION
9
+ spec.authors = ["wtnabe"]
10
+ spec.email = ["wtnabe@gmail.com"]
11
+ spec.summary = %q{Google Analytics API wrapper for CLI written in Ruby.}
12
+ spec.description = %q{Now, You can fetch general ga data.}
13
+ spec.homepage = ""
14
+ spec.license = "BSD"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "google-api-client"
22
+ spec.add_runtime_dependency "thor"
23
+ spec.add_runtime_dependency "hirb"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.7"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "minitest", "> 5"
28
+ spec.add_development_dependency "minitest-power_assert"
29
+ spec.add_development_dependency "minitest-reporters", "> 1"
30
+ end
@@ -0,0 +1,4 @@
1
+ module GAShikomi; end
2
+
3
+ require_relative './ga_shikomi/version'
4
+ Dir.glob(File.dirname(__FILE__) + '/ga_shikomi/*.rb').each {|f| require f}
@@ -0,0 +1,67 @@
1
+ require 'google/api_client'
2
+ require 'google/api_client/client_secrets'
3
+ require 'google/api_client/auth/installed_app'
4
+ require 'google/api_client/auth/file_storage'
5
+ require 'json'
6
+
7
+ module GAShikomi
8
+ class Api
9
+ class InexpectantResponse < StandardError; end
10
+
11
+ #
12
+ # [param] String store
13
+ #
14
+ def initialize(store)
15
+ @client = nil
16
+ @analytics = nil
17
+ @last_request = nil
18
+
19
+ init_and_auth_analytics(store)
20
+ end
21
+ attr_reader :client, :analytics, :last_request
22
+
23
+ #
24
+ # [param] String store
25
+ #
26
+ def init_and_auth_analytics(store)
27
+ @client = ::Google::APIClient.new(
28
+ :application_name => :gacli,
29
+ :application_version => VERSION)
30
+
31
+ credential = ::Google::APIClient::FileStorage.new(store)
32
+ secrets = ::Google::APIClient::ClientSecrets.load(File.dirname(store))
33
+
34
+ if credential.authorization.nil?
35
+ flow = ::Google::APIClient::InstalledAppFlow.new(
36
+ :client_id => secrets.client_id,
37
+ :client_secret => secrets.client_secret,
38
+ :scope => ['https://www.googleapis.com/auth/analytics',
39
+ 'https://www.googleapis.com/auth/analytics.edit'])
40
+
41
+ client.authorization = flow.authorize
42
+ credential.write_credentials(client.authorization)
43
+ else
44
+ client.authorization = credential.authorization
45
+ end
46
+
47
+ @analytics = client.discovered_api('analytics', 'v3')
48
+ end
49
+
50
+ #
51
+ # [param] Object method
52
+ # [return] Hash
53
+ #
54
+ def execute(method, params = {})
55
+ @last_request = client.execute(
56
+ :api_method => method,
57
+ :parameters => params)
58
+
59
+ result = JSON.parse(last_request.response.body)
60
+ if result['error']
61
+ raise InexpectantResponse, result['error']
62
+ else
63
+ result
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,87 @@
1
+ require 'thor'
2
+ Dir.glob(File.dirname(__FILE__) + '/subcommand/*.rb').each {|f| require f}
3
+
4
+ module GAShikomi
5
+ class Command < Thor
6
+ class_option :config_file
7
+ class_option :credential_store
8
+ class_option :format, :type => :string
9
+ class_option :with_csv_header, :type => :boolean
10
+
11
+ def initialize(*args)
12
+ super
13
+
14
+ if args.last[:current_command].name != 'help'
15
+ store = (!options.nil? && options['credential-store']) || File.join(Dir.pwd, '.ga-cli-credential')
16
+ @api = Api.new(store)
17
+ @config = Config.new(options['config_file']).config if options['config_file']
18
+ end
19
+ end
20
+ attr_reader :api, :config
21
+
22
+ desc 'ga', 'fetch and display ga data with profile'
23
+ option :profile_id, :type => :string, :required => true
24
+ option :start_date, :type => :string, :required => true
25
+ option :end_date, :type => :string, :required => true
26
+ option :metrics, :type => :string, :default => 'ga:pageviews,ga:users'
27
+ def ga
28
+ Renderer.new(Subcommand::Ga.new(api, options).get(config), options).render_ga
29
+ end
30
+
31
+ desc 'accounts', 'display accounts'
32
+ def accounts
33
+ Renderer.new(Subcommand::Accounts.new(api).list, options).render_accounts
34
+ end
35
+
36
+ desc 'properties', 'display properties'
37
+ option :account_id, :type => :string, :required => true
38
+ def properties
39
+ Renderer.new(Subcommand::Webproperties.new(api, options).list, options).render_properties
40
+ end
41
+
42
+ desc 'property', 'display property'
43
+ option :account_id, :type => :string, :required => true
44
+ option :property_id, :type => :string, :required => true
45
+ def property
46
+ Renderer.new(Subcommand::Webproperties.new(api, options).get, options).render_properties
47
+ end
48
+
49
+ desc 'profiles', 'display profiles (with property)'
50
+ option :account_id, :type => :string, :required => true
51
+ option :property_id, :type => :string, :required => true
52
+ def profiles
53
+ Renderer.new(Subcommand::Profiles.new(api, options).list, options).render_profiles
54
+ end
55
+
56
+ desc 'filters', 'display filters (with profile)'
57
+ option :account_id, :type => :string, :required => true
58
+ def filters
59
+ Renderer.new(Subcommand::Filters.new(api, options).list, options).render_filters
60
+ end
61
+
62
+ desc 'goals', 'display goals (with profile)'
63
+ option :account_id, :type => :string, :required => true
64
+ option :property_id, :type => :string, :required => true
65
+ option :profile_id, :type => :string, :required => true
66
+ def goals
67
+ Renderer.new(Subcommand::Goals.new(api, options).list, options).render_goals
68
+ end
69
+
70
+ desc 'metrices', 'display metrics'
71
+ option :include_deprecated, :type => :boolean
72
+ def metrics
73
+ Renderer.new(Subcommand::Metadata.new(api, options).metrics, options).render_metadata
74
+ end
75
+
76
+ desc 'dimensions', 'display dimensions'
77
+ option :include_deprecated, :type => :boolean
78
+ def dimensions
79
+ Renderer.new(Subcommand::Metadata.new(api, options).dimensions, options).render_metadata
80
+ end
81
+
82
+ desc 'segments', 'display segments'
83
+ def segments
84
+ Renderer.new(Subcommand::Segments.new(api).list, options).render_segments
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,20 @@
1
+ module GAShikomi
2
+ class Config
3
+ class FileNotFound < StandardError; end
4
+
5
+ def initialize(file)
6
+ @config = {}
7
+
8
+ load(file)
9
+ end
10
+ attr_reader :config
11
+
12
+ def load(file)
13
+ if File.exist? file
14
+ @config = YAML.load_file(file)
15
+ else
16
+ raise FileNotFound, "config_file #{file}"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,167 @@
1
+ require 'hirb'
2
+ require 'pp'
3
+
4
+ module GAShikomi
5
+ class Renderer
6
+ #
7
+ # [param] Array records
8
+ # [param] Hash oprions
9
+ #
10
+ def initialize(records, options)
11
+ @records = records
12
+ @options = options
13
+ end
14
+ attr_reader :records, :options
15
+
16
+ def raw
17
+ pp records
18
+ end
19
+
20
+ #
21
+ # [param] Array
22
+ # [param] Proc preprocess
23
+ #
24
+ def render(fields, &preprocess)
25
+ if options[:format] == 'original'
26
+ pp records
27
+ else
28
+ result = records.map {|e| preprocess.call(e)}
29
+
30
+ case options[:format]
31
+ when 'csv'
32
+ csv(result, :fields => fields)
33
+ else
34
+ table(result, :fields => fields)
35
+ end
36
+ end
37
+ end
38
+
39
+ def render_ga
40
+ case records.size
41
+ when 1
42
+ render(records.first.keys) {|record| record}
43
+ else
44
+ fields = [''] + records['totalsForAllResults'].keys
45
+
46
+ @records = records['rows'].map {|row|
47
+ Hash[*fields.zip(row).flatten]
48
+ } + [records['totalsForAllResults'].merge('' => 'totalsForAllResults')]
49
+
50
+ render(fields) {|record| record}
51
+ end
52
+ end
53
+
54
+ def render_accounts
55
+ render(%w(id permissions)) {|record|
56
+ {
57
+ 'id' => record['id'],
58
+ 'permissions' => record['permissions']['effective'].join(',')
59
+ }
60
+ }
61
+ end
62
+
63
+ def render_properties
64
+ render(%w(id name websiteUrl permissions)) {|record|
65
+ {
66
+ 'id' => record['id'],
67
+ 'name' => record['name'],
68
+ 'websiteUrl' => record['websiteUrl'],
69
+ 'permissions' => record['permissions']['effective'].join(',')
70
+ }
71
+ }
72
+ end
73
+
74
+ def render_profiles
75
+ render(%w(id name websiteUrl permissions)) {|record|
76
+ {
77
+ 'id' => record['id'],
78
+ 'name' => record['name'],
79
+ 'websiteUrl' => record['websiteUrl'],
80
+ 'permissions' => record['permissions']['effective'].join(',')
81
+ }
82
+ }
83
+ end
84
+
85
+ def render_filters
86
+ render(%w(id name type details)) {|record|
87
+ pick_id_name_type_and_details(record)
88
+ }
89
+ end
90
+
91
+ def render_goals
92
+ render(%w(id name type details)) {|record|
93
+ pick_id_name_type_and_details(record)
94
+ }
95
+ end
96
+
97
+ def render_metadata
98
+ render(%w(id description)) {|record| pick_id_and_description(record)}
99
+ end
100
+
101
+ def render_segments
102
+ fields = %w(id segmentId name type)
103
+
104
+ render(fields) {|record|
105
+ Hash[*fields.map {|f| [f, record[f]]}.flatten]
106
+ }
107
+ end
108
+
109
+ #
110
+ # [param] Hash item
111
+ # [return] Hash
112
+ #
113
+ def pick_id_and_description(item)
114
+ {
115
+ 'id' => item['id'],
116
+ 'description' => item['attributes']['description']
117
+ }
118
+ end
119
+
120
+ #
121
+ # [param] Hash item
122
+ # [return] Hash
123
+ #
124
+ def pick_id_name_type_and_details(item)
125
+ {
126
+ 'id' => item['id'],
127
+ 'name' => item['name'],
128
+ 'type' => item['type'],
129
+ 'details' => item["#{small_camelize(item['type'])}Details"]
130
+ }
131
+ end
132
+
133
+ #
134
+ # [param] String str
135
+ # [return] String str
136
+ #
137
+ def small_camelize(str)
138
+ str.split('_').map {|e| e.capitalize}.tap {|a| a.first.downcase!}.join
139
+ end
140
+
141
+ #
142
+ # [param] Array result
143
+ # [param] Hash opts
144
+ #
145
+ def table(result, opts = {})
146
+ require 'hirb'
147
+ puts Hirb::Helpers::AutoTable.render(result, opts)
148
+ end
149
+
150
+ #
151
+ # [param] Array result
152
+ # [param] Hash opts
153
+ #
154
+ def csv(result, opts = {})
155
+ require 'csv'
156
+
157
+ fields = opts[:fields] || result.first.keys.sort
158
+
159
+ puts CSV.generate {|csv|
160
+ csv << fields if options[:with_csv_header]
161
+ result.each {|r|
162
+ csv << fields.map {|f| r[f]}
163
+ }
164
+ }
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,19 @@
1
+ require_relative './base'
2
+
3
+ module GACli
4
+ module Subcommand
5
+ class Accounts < Base
6
+ #
7
+ # [{
8
+ # "id": "",
9
+ # "permission": []
10
+ # }]
11
+ #
12
+ # [return] Array
13
+ #
14
+ def list
15
+ api.execute(api.analytics.management.accounts.list)['items']
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ module GACli
2
+ module Subcommand
3
+ class Base
4
+ def initialize(api, options = {})
5
+ @api = api
6
+ @options = options
7
+ end
8
+ attr_reader :api, :options
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module GACli
2
+ module Subcommand
3
+ class Filters < Base
4
+ def list
5
+ api.execute(api.analytics.management.filters.list, :accountId => options['account_id'])['items']
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,43 @@
1
+ module GACli
2
+ module Subcommand
3
+ class Ga < Base
4
+ #
5
+ # require
6
+ # --profile-id
7
+ # --begin-date
8
+ # --end-date
9
+ # --metrics
10
+ def get(config)
11
+ opts = {
12
+ 'ids' => options['profile_id'],
13
+ 'start-date' => options['start_date'],
14
+ 'end-date' => options['end_date'],
15
+ 'metrics' => options['metrics']
16
+ }
17
+ %w(ids
18
+ metrics
19
+ dimensions
20
+ filters
21
+ max-results
22
+ output
23
+ samplingLevel
24
+ segment
25
+ sort
26
+ start-index
27
+ fields).each {|e|
28
+ opts[e] = config[e] if config[e]
29
+ } if config
30
+
31
+ result = api.execute(api.analytics.data.ga.get, opts)
32
+
33
+ case result['rows'].size
34
+ when 1
35
+ [result['totalsForAllResults']]
36
+ else
37
+ fields = %w(columnHeaders totalsForAllResults rows)
38
+ fields.map {|e| {e => result[e]}}.reduce(:merge)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ module GACli
2
+ module Subcommand
3
+ class Goals < Base
4
+ def list
5
+ api.execute(
6
+ api.analytics.management.goals.list,
7
+ :accountId => options['account_id'],
8
+ :webPropertyId => options['property_id'],
9
+ :profileId => options['profile_id'])['items']
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,47 @@
1
+ require_relative './base'
2
+
3
+ module GACli
4
+ module Subcommand
5
+ class Metadata < Base
6
+ #
7
+ # [return] Hash
8
+ #
9
+ def original
10
+ api.execute(api.analytics.metadata.columns.list, {:reportType => 'ga'})
11
+ end
12
+
13
+ #
14
+ # [return] Array
15
+ #
16
+ def items
17
+ original['items']
18
+ end
19
+
20
+ #
21
+ # [return] Array
22
+ #
23
+ def metrics
24
+ items.select {|m| m['attributes']['type'] == 'METRIC' && visible?(m)}
25
+ end
26
+
27
+ #
28
+ # [return] Array
29
+ #
30
+ def dimensions
31
+ items.select {|m| m['attributes']['type'] == 'DIMENSION' && visible?(m)}
32
+ end
33
+
34
+ #
35
+ # [param] Hash item
36
+ # [return] Boolean
37
+ #
38
+ def visible?(item)
39
+ if options[:include_deprecated]
40
+ true
41
+ else
42
+ item['attributes']['status'] == 'PUBLIC'
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,9 @@
1
+ module GACli
2
+ module Subcommand
3
+ class Profiles < Base
4
+ def list
5
+ api.execute(api.analytics.management.profiles.list, :accountId => options['account_id'], :webPropertyId => options['property_id'])['items']
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module GACli
2
+ module Subcommand
3
+ class Segments < Base
4
+ def list
5
+ api.execute(api.analytics.management.segments.list)['items']
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ module GACli
2
+ module Subcommand
3
+ class Webproperties < Base
4
+ #
5
+ # [{
6
+ # "id": "UA-xxxx-x",
7
+ # "internalWebPropertyId": xxxx,
8
+ # "permissions": []
9
+ # "websiteUrl": "",
10
+ # }]
11
+ #
12
+ # [return] Array
13
+ #
14
+ def list
15
+ api.execute(api.analytics.management.webproperties.list, :accountId => options["account_id"])['items']
16
+ end
17
+
18
+ #
19
+ # {
20
+ # "id": "UA-xxxx-xx",
21
+ # "websiteUrl": "",
22
+ # "permissions": []
23
+ # }
24
+ #
25
+ # [return] Array
26
+ #
27
+ def get
28
+ [api.execute(api.analytics.management.webproperties.get, :accountId => options['account_id'], :webPropertyId => options['property_id'])]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module GAShikomi
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'spec_helper'
2
+
3
+ module GAShikomi
4
+ describe Renderer do
5
+ include MetadataDouble
6
+
7
+ describe '#table' do
8
+ describe '--verbose' do
9
+ it {
10
+ Renderer.new(metadata_double, :format => 'table', :verbose => true).render_metadata
11
+ }
12
+ end
13
+ describe 'picked' do
14
+ it {
15
+ Renderer.new(metadata_double, :format => 'table').render_metadata
16
+ }
17
+ end
18
+ end
19
+
20
+ describe '#csv' do
21
+ it {
22
+ Renderer.new(metadata_double, :format => 'csv').render_metadata
23
+ }
24
+ end
25
+ end
26
+
27
+ describe '#render_ga' do
28
+ include GaDouble
29
+ it {
30
+ Renderer.new(multi_rows, {}).render_ga
31
+ }
32
+ end
33
+ end
34
+
@@ -0,0 +1,8 @@
1
+ require_relative "../lib/ga_shikomi"
2
+ Dir.glob(File.dirname(__FILE__) + '/support/*.rb').each {|f| require f}
3
+
4
+ require "minitest/spec"
5
+ require "minitest/autorun"
6
+ require "minitest-power_assert"
7
+ require "minitest/reporters"
8
+ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
@@ -0,0 +1,45 @@
1
+ module GAShikomi
2
+ module GaDouble
3
+ def multi_rows
4
+ {
5
+ "columnHeaders"=>[
6
+ {
7
+ "name" => "ga:deviceCategory",
8
+ "columnType" => "DIMENSION",
9
+ "dataType" => "STRING"
10
+ },
11
+ {
12
+ "name" => "ga:pageviews",
13
+ "columnType" => "METRIC",
14
+ "dataType" => "INTEGER"},
15
+ {
16
+ "name" => "ga:sessions",
17
+ "columnType" => "METRIC",
18
+ "dataType" => "INTEGER"
19
+ },
20
+ {
21
+ "name" => "ga:pageviewsPerSession",
22
+ "columnType" => "METRIC",
23
+ "dataType" => "FLOAT"
24
+ },
25
+ {
26
+ "name" => "ga:goal1Value",
27
+ "columnType" => "METRIC",
28
+ "dataType" => "CURRENCY"
29
+ }
30
+ ],
31
+ "totalsForAllResults" => {
32
+ "ga:pageviews" => "4090",
33
+ "ga:sessions" => "3649",
34
+ "ga:pageviewsPerSession" => "1.1208550287750068",
35
+ "ga:goal1Value" => "0.0"
36
+ },
37
+ "rows" => [
38
+ ["desktop", "3846", "3442", "1.1173736199883788", "0.0"],
39
+ ["mobile", "172", "141", "1.2198581560283688", "0.0"],
40
+ ["tablet", "72", "66", "1.0909090909090908", "0.0"]
41
+ ]
42
+ }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,29 @@
1
+ module GAShikomi
2
+ module MetadataDouble
3
+ def metadata_double
4
+ [
5
+ {
6
+ 'id' => 1,
7
+ 'attributes' => {
8
+ 'description' => 'description1',
9
+ 'foobar' => 'foobar1'
10
+ }
11
+ },
12
+ {
13
+ 'id' => 2,
14
+ 'attributes' => {
15
+ 'description' => 'description2',
16
+ 'foobar' => 'foobar2'
17
+ }
18
+ },
19
+ {
20
+ 'id' => 3,
21
+ 'attributes' => {
22
+ 'description' => 'description3',
23
+ 'foobar' => 'foobar3'
24
+ }
25
+ }
26
+ ]
27
+ end
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,186 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ga-shikomi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - wtnabe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: google-api-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: hirb
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>'
88
+ - !ruby/object:Gem::Version
89
+ version: '5'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>'
95
+ - !ruby/object:Gem::Version
96
+ version: '5'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest-power_assert
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: minitest-reporters
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>'
116
+ - !ruby/object:Gem::Version
117
+ version: '1'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>'
123
+ - !ruby/object:Gem::Version
124
+ version: '1'
125
+ description: Now, You can fetch general ga data.
126
+ email:
127
+ - wtnabe@gmail.com
128
+ executables:
129
+ - shikomi
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - Gemfile
135
+ - README.md
136
+ - Rakefile
137
+ - bin/shikomi
138
+ - ga_shikomi.gemspec
139
+ - lib/ga_shikomi.rb
140
+ - lib/ga_shikomi/api.rb
141
+ - lib/ga_shikomi/command.rb
142
+ - lib/ga_shikomi/config.rb
143
+ - lib/ga_shikomi/renderer.rb
144
+ - lib/ga_shikomi/subcommand/accounts.rb
145
+ - lib/ga_shikomi/subcommand/base.rb
146
+ - lib/ga_shikomi/subcommand/filters.rb
147
+ - lib/ga_shikomi/subcommand/ga.rb
148
+ - lib/ga_shikomi/subcommand/goals.rb
149
+ - lib/ga_shikomi/subcommand/metadata.rb
150
+ - lib/ga_shikomi/subcommand/profiles.rb
151
+ - lib/ga_shikomi/subcommand/segments.rb
152
+ - lib/ga_shikomi/subcommand/webproperties.rb
153
+ - lib/ga_shikomi/version.rb
154
+ - spec/renderer_spec.rb
155
+ - spec/spec_helper.rb
156
+ - spec/support/ga_double.rb
157
+ - spec/support/metadata_double.rb
158
+ homepage: ''
159
+ licenses:
160
+ - BSD
161
+ metadata: {}
162
+ post_install_message:
163
+ rdoc_options: []
164
+ require_paths:
165
+ - lib
166
+ required_ruby_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ! '>='
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ required_rubygems_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ! '>='
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ requirements: []
177
+ rubyforge_project:
178
+ rubygems_version: 2.4.6
179
+ signing_key:
180
+ specification_version: 4
181
+ summary: Google Analytics API wrapper for CLI written in Ruby.
182
+ test_files:
183
+ - spec/renderer_spec.rb
184
+ - spec/spec_helper.rb
185
+ - spec/support/ga_double.rb
186
+ - spec/support/metadata_double.rb