ga-shikomi 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +7 -0
- data/Gemfile +4 -0
- data/README.md +33 -0
- data/Rakefile +8 -0
- data/bin/shikomi +5 -0
- data/ga_shikomi.gemspec +30 -0
- data/lib/ga_shikomi.rb +4 -0
- data/lib/ga_shikomi/api.rb +67 -0
- data/lib/ga_shikomi/command.rb +87 -0
- data/lib/ga_shikomi/config.rb +20 -0
- data/lib/ga_shikomi/renderer.rb +167 -0
- data/lib/ga_shikomi/subcommand/accounts.rb +19 -0
- data/lib/ga_shikomi/subcommand/base.rb +11 -0
- data/lib/ga_shikomi/subcommand/filters.rb +9 -0
- data/lib/ga_shikomi/subcommand/ga.rb +43 -0
- data/lib/ga_shikomi/subcommand/goals.rb +13 -0
- data/lib/ga_shikomi/subcommand/metadata.rb +47 -0
- data/lib/ga_shikomi/subcommand/profiles.rb +9 -0
- data/lib/ga_shikomi/subcommand/segments.rb +9 -0
- data/lib/ga_shikomi/subcommand/webproperties.rb +32 -0
- data/lib/ga_shikomi/version.rb +3 -0
- data/spec/renderer_spec.rb +34 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/ga_double.rb +45 -0
- data/spec/support/metadata_double.rb +29 -0
- metadata +186 -0
checksums.yaml
ADDED
@@ -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=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
data/bin/shikomi
ADDED
data/ga_shikomi.gemspec
ADDED
@@ -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
|
data/lib/ga_shikomi.rb
ADDED
@@ -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,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,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,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
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -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
|