ga-shikomi 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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