TokiCLI 0.2.1 → 0.3.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.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.gitignore +9 -17
- data/.rspec +3 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +4 -0
- data/README.md +99 -163
- data/Rakefile +5 -0
- data/TokiCLI.gemspec +5 -4
- data/bin/toki +2 -2
- data/lib/API/helpers.rb +27 -170
- data/lib/API/toki_api.rb +227 -0
- data/lib/API/toki_db.rb +67 -0
- data/lib/TokiCLI.rb +270 -5
- data/lib/TokiCLI/adnimport.rb +202 -0
- data/lib/TokiCLI/fileops.rb +187 -0
- data/lib/TokiCLI/status.rb +49 -37
- data/lib/TokiCLI/version.rb +1 -1
- data/lib/TokiCLI/view.rb +133 -86
- data/lib/TokiServer/.bowerrc +3 -0
- data/lib/TokiServer/.gitignore +2 -0
- data/lib/TokiServer/Gemfile +1 -0
- data/lib/TokiServer/bower.json +0 -0
- data/lib/TokiServer/bower_components/fastclick/.bower.json +4 -4
- data/lib/TokiServer/bower_components/fastclick/bower.json +1 -1
- data/lib/TokiServer/bower_components/fastclick/lib/fastclick.js +33 -2
- data/lib/TokiServer/bower_components/foundation/.bower.json +5 -4
- data/lib/TokiServer/bower_components/foundation/bower.json +2 -1
- data/lib/TokiServer/bower_components/foundation/css/foundation.css +2173 -922
- data/lib/TokiServer/bower_components/foundation/css/foundation.css.map +7 -0
- data/lib/TokiServer/bower_components/foundation/css/normalize.css +53 -16
- data/lib/TokiServer/bower_components/foundation/css/normalize.css.map +7 -0
- data/lib/TokiServer/bower_components/foundation/js/foundation.js +782 -542
- data/lib/TokiServer/bower_components/foundation/js/foundation.min.js +4 -3
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.abide.js +45 -31
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.accordion.js +12 -6
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.alert.js +5 -5
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.clearing.js +34 -10
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.dropdown.js +83 -29
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.equalizer.js +3 -3
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.interchange.js +25 -12
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.joyride.js +112 -40
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.js +19 -5
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.magellan.js +22 -11
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.offcanvas.js +52 -8
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.orbit.js +133 -271
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.reveal.js +27 -20
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.slider.js +73 -33
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.tab.js +88 -31
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.tooltip.js +7 -5
- data/lib/TokiServer/bower_components/foundation/js/foundation/foundation.topbar.js +44 -24
- data/lib/TokiServer/bower_components/foundation/js/vendor/fastclick.js +2 -2
- data/lib/TokiServer/bower_components/foundation/js/vendor/modernizr.js +2 -2
- data/lib/TokiServer/bower_components/foundation/scss/foundation.scss +38 -38
- data/lib/TokiServer/bower_components/foundation/scss/foundation/_functions.scss +3 -3
- data/lib/TokiServer/bower_components/foundation/scss/foundation/_settings.scss +417 -271
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_accordion.scss +110 -6
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_alert-boxes.scss +2 -2
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_block-grid.scss +2 -2
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_breadcrumbs.scss +8 -3
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_button-groups.scss +99 -9
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_buttons.scss +66 -28
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_clearing.scss +5 -5
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_dropdown-buttons.scss +4 -4
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_dropdown.scss +48 -35
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_forms.scss +104 -32
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_global.scss +48 -30
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_grid.scss +19 -4
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_icon-bar.scss +293 -0
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_joyride.scss +11 -9
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_keystrokes.scss +4 -4
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_labels.scss +4 -2
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_magellan.scss +1 -1
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_offcanvas.scss +193 -35
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_orbit.scss +92 -147
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_pagination.scss +22 -10
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_panels.scss +10 -7
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_pricing-tables.scss +11 -11
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_progress-bars.scss +2 -2
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_range-slider.scss +29 -9
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_reveal.scss +60 -56
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_side-nav.scss +3 -2
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_split-buttons.scss +2 -2
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_sub-nav.scss +2 -2
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_switches.scss +226 -0
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_tables.scss +13 -7
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_tabs.scss +22 -8
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_thumbs.scss +2 -4
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_toolbar.scss +70 -0
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_tooltips.scss +9 -7
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_top-bar.scss +77 -44
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_type.scss +21 -9
- data/lib/TokiServer/bower_components/modernizr/.bower.json +4 -4
- data/lib/TokiServer/bower_components/modernizr/feature-detects/workers-blobworkers.js +2 -2
- data/lib/TokiServer/bower_components/modernizr/grunt.js +1 -1
- data/lib/TokiServer/bower_components/modernizr/modernizr.js +2 -2
- data/lib/TokiServer/config.rb +0 -0
- data/lib/TokiServer/humans.txt +0 -0
- data/lib/TokiServer/{itunesicon.rb → itunesicons.rb} +25 -23
- data/lib/TokiServer/js/app.js +0 -0
- data/lib/TokiServer/public/stylesheets/app.css +2636 -1610
- data/lib/TokiServer/robots.txt +0 -0
- data/lib/TokiServer/scss/_settings.scss +0 -0
- data/lib/TokiServer/scss/app.scss +7 -1
- data/lib/TokiServer/tokiserver.rb +239 -244
- data/lib/TokiServer/views/activity.erb +42 -0
- data/lib/TokiServer/views/apps_total.erb +8 -2
- data/lib/TokiServer/views/error.erb +13 -4
- data/lib/TokiServer/views/index.erb +36 -27
- data/lib/TokiServer/views/logs_total.erb +34 -0
- data/spec/TokiCLI_spec.rb +354 -0
- data/spec/mock/mock.sqlite3 +0 -0
- data/spec/spec_helper.rb +26 -0
- metadata +78 -23
- data/lib/API/dbapi.rb +0 -488
- data/lib/TokiCLI/app.rb +0 -389
- data/lib/TokiCLI/authorize.rb +0 -77
- data/lib/TokiCLI/export.rb +0 -81
- data/lib/TokiCLI/get_channels.rb +0 -22
- data/lib/TokiCLI/get_messages.rb +0 -32
- data/lib/TokiCLI/import.rb +0 -122
- data/lib/TokiCLI/scan.rb +0 -19
- data/lib/TokiCLI/search_messages.rb +0 -23
- data/lib/TokiServer/README.md +0 -37
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_reveal-new.scss +0 -0
- data/lib/TokiServer/bower_components/foundation/scss/foundation/components/_switch.scss +0 -294
- data/lib/TokiServer/views/name_log.erb +0 -50
- data/lib/TokiServer/views/name_split.erb +0 -37
- data/lib/TokiServer/views/name_total.erb +0 -34
data/TokiCLI.gemspec
CHANGED
|
@@ -18,8 +18,6 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
|
|
21
|
-
spec.required_ruby_version = '>= 2.0.0'
|
|
22
|
-
|
|
23
21
|
spec.add_dependency "thor", "~> 0.18"
|
|
24
22
|
spec.add_dependency "rest-client", "~> 1.6"
|
|
25
23
|
spec.add_dependency "amalgalite", "~> 1.3"
|
|
@@ -28,7 +26,10 @@ Gem::Specification.new do |spec|
|
|
|
28
26
|
spec.add_dependency 'sinatra', '~> 1.4', '>= 1.4.5'
|
|
29
27
|
spec.add_dependency "thin", "~> 1.6"
|
|
30
28
|
spec.add_dependency 'sinatra-assetpack', "~> 0.3", '>= 0.3.2'
|
|
29
|
+
spec.add_dependency "sinatra-contrib", '~> 1.4', '>= 1.4.2'
|
|
31
30
|
|
|
32
|
-
spec.add_development_dependency "bundler", "~> 1.
|
|
33
|
-
spec.add_development_dependency "rake"
|
|
31
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
|
32
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
33
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
|
34
|
+
spec.add_development_dependency "coveralls"
|
|
34
35
|
end
|
data/bin/toki
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# encoding: utf-8
|
|
3
3
|
# Toki command-line client
|
|
4
|
-
#
|
|
5
|
-
# Toki by: Keitaroh Kobayashi (http://app.net/keita)
|
|
4
|
+
# TokiCLI by: Eric Dejonckheere (http://app.net/ericd)
|
|
5
|
+
# Toki.app by: Keitaroh Kobayashi (http://app.net/keita)
|
|
6
6
|
|
|
7
7
|
$PROGRAM_NAME = 'toki'
|
|
8
8
|
require_relative '../lib/TokiCLI'
|
data/lib/API/helpers.rb
CHANGED
|
@@ -1,195 +1,52 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
-
module TokiCLI
|
|
3
|
-
class Helpers
|
|
4
|
-
|
|
5
|
-
attr_accessor :table, :bundles, :bundles_file, :home_path, :toki_path, :db_path
|
|
6
|
-
attr_reader :db
|
|
7
|
-
|
|
8
|
-
def initialize
|
|
9
|
-
@home_path = Dir.home
|
|
10
|
-
@toki_path = "#{@home_path}/.TokiCLI"
|
|
11
|
-
FileUtils.mkdir_p(@toki_path) unless Dir.exist?(@toki_path)
|
|
12
|
-
@db_path = "#{@home_path}/Library/Containers/us.kkob.Toki/Data/Documents/toki_data.sqlite3"
|
|
13
|
-
if File.exist? @db_path
|
|
14
|
-
FileUtils.copy @db_path, "#{@toki_path}/toki_data.sqlite3.bak"
|
|
15
|
-
@db = Amalgalite::Database.new @db_path
|
|
16
|
-
else
|
|
17
|
-
raise 'No DB'
|
|
18
|
-
end
|
|
19
|
-
@table = 'KKAppActivity'
|
|
20
|
-
@bundles_file = "#{@toki_path}/apps.json"
|
|
21
|
-
@bundles = if File.exist? @bundles_file
|
|
22
|
-
JSON.parse(File.read @bundles_file)
|
|
23
|
-
else
|
|
24
|
-
{}
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
# Returns the app name if exists
|
|
30
|
-
def find_app_name bundle_id
|
|
31
|
-
if @bundles[bundle_id]
|
|
32
|
-
@bundles[bundle_id]
|
|
33
|
-
else
|
|
34
|
-
nil
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
2
|
|
|
38
|
-
|
|
39
|
-
human = seconds_to_time epoch
|
|
40
|
-
"#{'%.2d' % human[:hours]}h #{'%.2d' % human[:minutes]}m #{'%.2d' % human[:seconds]}s"
|
|
41
|
-
end
|
|
3
|
+
module TokiCLI
|
|
42
4
|
|
|
43
|
-
|
|
44
|
-
human = seconds_to_time epoch
|
|
45
|
-
"#{'%.2d' % human[:minutes]}m #{'%.2d' % human[:seconds]}s"
|
|
46
|
-
end
|
|
5
|
+
class Helpers
|
|
47
6
|
|
|
48
|
-
def
|
|
7
|
+
def sec_to_time(secs)
|
|
49
8
|
begin
|
|
50
|
-
hours =
|
|
51
|
-
minutes = (
|
|
52
|
-
seconds = (
|
|
53
|
-
{hours
|
|
9
|
+
hours = secs / 3600
|
|
10
|
+
minutes = (secs / 60 - hours * 60)
|
|
11
|
+
seconds = (secs - (minutes * 60 + hours * 3600))
|
|
12
|
+
{'hours' => hours, 'minutes' => minutes, 'seconds' => seconds}
|
|
54
13
|
rescue Exception => e
|
|
55
|
-
|
|
14
|
+
raise e, Status.wtf
|
|
56
15
|
end
|
|
57
16
|
end
|
|
58
17
|
|
|
59
|
-
def
|
|
60
|
-
puts "\nOOPS! A gremlin crashed the app.\n\n"
|
|
61
|
-
puts "STACK: #{caller}\n\n"
|
|
62
|
-
puts "GREMLIN: #{error}\n\n"
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def epoch_to_date epoch
|
|
18
|
+
def epoch_to_date(epoch)
|
|
66
19
|
Time.at(epoch).to_time
|
|
67
20
|
end
|
|
68
21
|
|
|
69
|
-
def
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def scan params = {}
|
|
75
|
-
bundle_ids = get_bundle_ids params
|
|
76
|
-
f = File.new "#{@toki_path}/apps.json", "w"
|
|
77
|
-
f.write bundle_ids.to_json
|
|
78
|
-
f.close
|
|
79
|
-
bundle_ids
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def scan_app_icons
|
|
83
|
-
@bundles.each do |k,v|
|
|
84
|
-
gs = v.gsub(' ', '\ ')
|
|
85
|
-
where = "/Applications/#{gs}.app/Contents/Resources/*.icns"
|
|
86
|
-
files = Dir.glob(where)
|
|
87
|
-
candidates = files.select {|f| File.basename(f) == "Icon.icns" || File.basename(f, ".icns").downcase =~ /#{v.downcase}/}
|
|
88
|
-
puts "#{v} => #{candidates}"
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# Scan for names from bundle ids
|
|
93
|
-
def get_bundle_ids params = {}
|
|
94
|
-
@infos = {}
|
|
95
|
-
get_bundles(get_plists("/Applications/*/Contents/*"), params)
|
|
96
|
-
get_bundles(get_plists("/Applications/Utilities/*/Contents/*"), params)
|
|
97
|
-
get_bundles(get_plists("#{@home_path}/Applications/*/Contents/*"), params)
|
|
98
|
-
specials = {
|
|
99
|
-
'com.evernote.EvernoteHelper' => 'Evernote Helper',
|
|
100
|
-
'com.apple.finder' => 'Finder',
|
|
101
|
-
'com.apple.ReportPanic' => 'Kernel Panic',
|
|
102
|
-
'com.apple.coreservices.uiagent' => 'CoreServices UIAgent',
|
|
103
|
-
'com.apple.installer' => 'Apple Installer',
|
|
104
|
-
'com.apple.frameworks.diskimages.diuiagent' => 'Apple Disk Images Agent',
|
|
105
|
-
'com.mediaatelier.CheatSheet' => 'Cheat Sheet',
|
|
106
|
-
'com.vyprvpn.authorization' => 'VyprVPN',
|
|
107
|
-
'com.apple.WebKit.WebContent' => 'Safari module',
|
|
108
|
-
'com.apple.ProblemReporter' => 'Apple Problem Reporter',
|
|
109
|
-
'org.andymatuschak.sparkle.finish-installation' => 'Sparkle Install',
|
|
110
|
-
'com.noodlesoft.HazelHelper' => 'Hazel Helper',
|
|
111
|
-
'de.appsolute.MAMP' => 'MAMP',
|
|
112
|
-
'com.apple.KeyboardSetupAssistant' => 'Apple Keyboard Setup Assistant',
|
|
113
|
-
'com.apple.NetAuthAgent' => 'Apple Net Auth Agent',
|
|
114
|
-
'com.adobe.acc.AdobeCreativeCloud' => 'Adobe Creative Cloud',
|
|
115
|
-
'com.apple.iphonesimulator' => 'Apple iPhone Simulator',
|
|
116
|
-
'com.macromates.TextMate.preview' => 'TextMate',
|
|
117
|
-
'com.alfredapp.Alfred' => 'Alfred',
|
|
118
|
-
'com.runningwithcrayons.Alfred-Preferences' => 'Alfred Preferences',
|
|
119
|
-
'com.apple.WebKit.PluginProcess' => 'Safari Plugin',
|
|
120
|
-
'com.apple.ScreenSharing' => 'Apple Screen Sharing',
|
|
121
|
-
'org.virtualbox.app.VirtualBoxVM' => 'VirtualBox',
|
|
122
|
-
'2BUA8C4S2C.com.agilebits.onepassword-osx-helper' => '1Password Helper'
|
|
123
|
-
}
|
|
124
|
-
specials.each do |k, v|
|
|
125
|
-
@infos[k] = v
|
|
126
|
-
end
|
|
127
|
-
@infos
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def get_bundle_from_name name
|
|
131
|
-
(@bundles).each do |k,v|
|
|
132
|
-
if v.downcase =~ /#{name.downcase}/
|
|
133
|
-
return [v, k]
|
|
134
|
-
end
|
|
22
|
+
def check_date_validity(day)
|
|
23
|
+
begin
|
|
24
|
+
DateTime.strptime(day, '%Y-%m-%d')
|
|
25
|
+
rescue ArgumentError, TypeError => e
|
|
26
|
+
false
|
|
135
27
|
end
|
|
136
|
-
[]
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def meta_nodata
|
|
140
|
-
{
|
|
141
|
-
code: 404,
|
|
142
|
-
message: 'No data returned from the database'
|
|
143
|
-
}
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def json_nodata
|
|
147
|
-
{
|
|
148
|
-
meta: meta_nodata,
|
|
149
|
-
data: {}
|
|
150
|
-
}.to_json
|
|
151
28
|
end
|
|
152
29
|
|
|
153
|
-
def
|
|
154
|
-
|
|
155
|
-
list = []
|
|
156
|
-
tracked['data']['apps'].each {|v| list << v['bundle']}
|
|
157
|
-
list
|
|
30
|
+
def readable_time(obj)
|
|
31
|
+
"#{obj['hours']}h #{'%.2d' % obj['minutes']}m #{'%.2d' % obj['seconds']}s"
|
|
158
32
|
end
|
|
159
33
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def get_plists path
|
|
163
|
-
Dir.glob(path).select {|f| (File.split f).last == 'Info.plist'}
|
|
34
|
+
def readable_time_log(obj)
|
|
35
|
+
"#{'%.2d' % obj['minutes']}m #{'%.2d' % obj['seconds']}s"
|
|
164
36
|
end
|
|
165
37
|
|
|
166
|
-
def
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
pl = CFPropertyList::List.new(:file => obj)
|
|
171
|
-
rescue CFFormatError
|
|
172
|
-
bundles_error if params[:verbose] == true
|
|
173
|
-
next
|
|
174
|
-
rescue NoMethodError
|
|
175
|
-
bundles_error if params[:verbose] == true
|
|
176
|
-
next
|
|
177
|
-
end
|
|
178
|
-
data = CFPropertyList.native_types(pl.value)
|
|
179
|
-
name = data['CFBundleName']
|
|
180
|
-
bundle_id = data['CFBundleIdentifier']
|
|
181
|
-
if name.nil?
|
|
182
|
-
name = data['CFBundleExecutable']
|
|
183
|
-
end
|
|
184
|
-
next if name.nil?
|
|
185
|
-
next if bundle_id.nil? || bundle_id.empty?
|
|
186
|
-
@infos[bundle_id] = name
|
|
187
|
-
end
|
|
38
|
+
def calc_apps_total(data)
|
|
39
|
+
total = 0
|
|
40
|
+
data.each { |obj| total += obj['total']['seconds'] }
|
|
41
|
+
return total
|
|
188
42
|
end
|
|
189
43
|
|
|
190
|
-
def
|
|
191
|
-
|
|
44
|
+
def calc_logs_total(data)
|
|
45
|
+
total = 0
|
|
46
|
+
data.each { |k, v| total += v['duration']['seconds'] }
|
|
47
|
+
return total
|
|
192
48
|
end
|
|
193
49
|
|
|
194
50
|
end
|
|
51
|
+
|
|
195
52
|
end
|
data/lib/API/toki_api.rb
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module TokiCLI
|
|
4
|
+
|
|
5
|
+
class TokiAPI
|
|
6
|
+
|
|
7
|
+
require 'json'
|
|
8
|
+
require 'amalgalite'
|
|
9
|
+
|
|
10
|
+
require_relative 'helpers'
|
|
11
|
+
require_relative 'toki_db'
|
|
12
|
+
|
|
13
|
+
attr_reader :bundles, :response, :helpers
|
|
14
|
+
|
|
15
|
+
def initialize(db_path, bundles = nil)
|
|
16
|
+
@db = TokiCLI::TokiDB.new(db_path)
|
|
17
|
+
@helpers = TokiCLI::Helpers.new
|
|
18
|
+
@bundles = bundles
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def apps_total
|
|
22
|
+
request = {command: 'apps_total', type: 'apps', args: [], processed_at: Time.now}
|
|
23
|
+
resp = @db.apps_total
|
|
24
|
+
return response_wrapper(request, resp) { make_apps_list(resp) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def apps_top(number = 5)
|
|
28
|
+
request = {command: 'apps_top', type: 'apps', args: [number], processed_at: Time.now}
|
|
29
|
+
resp = @db.apps_total
|
|
30
|
+
return invalid_response(request) if resp.empty?
|
|
31
|
+
index = -number
|
|
32
|
+
list = make_apps_list(resp)[index..-1]
|
|
33
|
+
@response = make_basic_response(request, list)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def apps_day(day)
|
|
37
|
+
request = {command: 'apps_day', type: 'apps', args: [day], processed_at: Time.now}
|
|
38
|
+
date = @helpers.check_date_validity(day)
|
|
39
|
+
return invalid_response(request) if date == false
|
|
40
|
+
resp = @db.apps_range(date.to_time.to_i, date.next_day.to_time.to_i)
|
|
41
|
+
return response_wrapper(request, resp) { make_apps_list(resp) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def apps_range(day1, day2)
|
|
45
|
+
request = {command: 'apps_range', type: 'apps', args: [day1, day2], processed_at: Time.now}
|
|
46
|
+
starting, ending = @helpers.check_date_validity(day1), @helpers.check_date_validity(day2)
|
|
47
|
+
return invalid_response(request) if starting == false || ending == false || starting > ending
|
|
48
|
+
resp = @db.apps_range(starting.to_time.to_i, ending.to_time.to_i)
|
|
49
|
+
return response_wrapper(request, resp) { make_apps_list(resp) }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def apps_since(day)
|
|
53
|
+
request = {command: 'apps_since', type: 'apps', args: [day], processed_at: Time.now}
|
|
54
|
+
starting = @helpers.check_date_validity(day)
|
|
55
|
+
return invalid_response(request) if starting == false
|
|
56
|
+
resp = @db.apps_since(starting.to_time.to_i)
|
|
57
|
+
return response_wrapper(request, resp) { make_apps_list(resp) }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def apps_before(day)
|
|
61
|
+
request = {command: 'apps_before', type: 'apps', args: [day], processed_at: Time.now}
|
|
62
|
+
ending = @helpers.check_date_validity(day)
|
|
63
|
+
return invalid_response(request) if ending == false
|
|
64
|
+
resp = @db.apps_before(ending.to_time.to_i)
|
|
65
|
+
return response_wrapper(request, resp) { make_apps_list(resp) }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def bundle_log(bundle)
|
|
69
|
+
request = {command: 'bundle_log', type: 'log', args: [bundle], processed_at: Time.now}
|
|
70
|
+
resp = @db.bundle_log(bundle)
|
|
71
|
+
return response_wrapper(request, resp) { make_log_objects(resp) }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def bundle_log_since(bundle, date)
|
|
75
|
+
request = {command: 'bundle_log_since', type: 'log', args: [bundle, date], processed_at: Time.now}
|
|
76
|
+
starting = @helpers.check_date_validity(date)
|
|
77
|
+
return invalid_response(request) if starting == false
|
|
78
|
+
resp = @db.bundle_log_since(bundle, starting.to_time.to_i)
|
|
79
|
+
return response_wrapper(request, resp) { make_log_objects(resp) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def bundle_log_before(bundle, date)
|
|
83
|
+
request = {command: 'bundle_log_before', type: 'log', args: [bundle, date], processed_at: Time.now}
|
|
84
|
+
ending = @helpers.check_date_validity(date)
|
|
85
|
+
return invalid_response(request) if ending == false
|
|
86
|
+
resp = @db.bundle_log_before(bundle, ending.to_time.to_i)
|
|
87
|
+
return response_wrapper(request, resp) { make_log_objects(resp) }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def bundle_log_range(bundle, day1, day2)
|
|
91
|
+
request = {command: 'bundle_log_range', type: 'log', args: [bundle, day1, day2], processed_at: Time.now}
|
|
92
|
+
starting, ending = @helpers.check_date_validity(day1), @helpers.check_date_validity(day2)
|
|
93
|
+
return invalid_response(request) if starting == false || ending == false || starting > ending
|
|
94
|
+
resp = @db.bundle_log_range(bundle, starting.to_time.to_i, ending.to_time.to_i)
|
|
95
|
+
return response_wrapper(request, resp) { make_log_objects(resp) }
|
|
96
|
+
end
|
|
97
|
+
def bundle_log_day(bundle, day)
|
|
98
|
+
starting = @helpers.check_date_validity(day)
|
|
99
|
+
return invalid_response(request) if starting == false
|
|
100
|
+
next_day = starting.next_day.strftime('%Y-%m-%d')
|
|
101
|
+
bundle_log_range(bundle, day, next_day)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def log_since(day = nil)
|
|
105
|
+
request = {command: 'log_since', type: 'log', args: [day], processed_at: Time.now}
|
|
106
|
+
starting = if day.nil?
|
|
107
|
+
@helpers.check_date_validity(Time.now.to_s[0..9])
|
|
108
|
+
else
|
|
109
|
+
@helpers.check_date_validity(day)
|
|
110
|
+
end
|
|
111
|
+
resp = @db.log_since(starting.to_time.to_i)
|
|
112
|
+
return response_wrapper(request, resp) { make_log_objects(resp) }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def log_day(day)
|
|
116
|
+
request = {command: 'log_range', type: 'log', args: [day], processed_at: Time.now}
|
|
117
|
+
starting = @helpers.check_date_validity(day)
|
|
118
|
+
return invalid_response(request) if starting == false
|
|
119
|
+
ending = @helpers.check_date_validity(starting.next_day.strftime('%Y-%m-%d'))
|
|
120
|
+
resp = @db.log_range(starting.to_time.to_i, ending.to_time.to_i)
|
|
121
|
+
return response_wrapper(request, resp) { make_log_objects(resp) }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# ---
|
|
125
|
+
|
|
126
|
+
def delete_bundle(bundle_id)
|
|
127
|
+
request = {command: 'delete_bundle', type: 'action', args: [bundle_id], processed_at: Time.now}
|
|
128
|
+
resp = @db.delete_bundle(bundle_id)
|
|
129
|
+
if resp.empty? # success
|
|
130
|
+
resp = [{'deleted' => bundle_id}]
|
|
131
|
+
@response = make_basic_response(request, resp)
|
|
132
|
+
else
|
|
133
|
+
@response = bad_request(request)
|
|
134
|
+
end
|
|
135
|
+
return @response
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# ---
|
|
139
|
+
|
|
140
|
+
def invalid_response(request)
|
|
141
|
+
@response = bad_request(request)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
private
|
|
145
|
+
|
|
146
|
+
def response_wrapper(request, resp)
|
|
147
|
+
return invalid_response(request) if resp.empty?
|
|
148
|
+
list = yield
|
|
149
|
+
@response = make_basic_response(request, list)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def make_apps_list(resp)
|
|
153
|
+
result = make_apps_objects(resp)
|
|
154
|
+
result.sort_by {|obj| obj[:total][:seconds]}
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def make_basic_response(request, list)
|
|
158
|
+
{
|
|
159
|
+
meta: {
|
|
160
|
+
code: 200,
|
|
161
|
+
request: request
|
|
162
|
+
},
|
|
163
|
+
data: list
|
|
164
|
+
}.to_json
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def make_apps_objects(db_resp)
|
|
168
|
+
if @bundles.nil?
|
|
169
|
+
db_resp.map do |id, sec|
|
|
170
|
+
{
|
|
171
|
+
bundle: id,
|
|
172
|
+
total: {
|
|
173
|
+
seconds: sec,
|
|
174
|
+
time: @helpers.sec_to_time(sec)
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
end
|
|
178
|
+
else
|
|
179
|
+
db_resp.map do |id, sec|
|
|
180
|
+
{
|
|
181
|
+
bundle: id,
|
|
182
|
+
name: @bundles[id],
|
|
183
|
+
total: {
|
|
184
|
+
seconds: sec,
|
|
185
|
+
time: @helpers.sec_to_time(sec)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def make_log_objects(db_resp)
|
|
193
|
+
result = {}
|
|
194
|
+
sorted = db_resp.sort_by { |arr| arr[2] }
|
|
195
|
+
sorted.each do |arr|
|
|
196
|
+
name = if @bundles.nil?
|
|
197
|
+
arr[1]
|
|
198
|
+
else
|
|
199
|
+
@bundles[arr[1]]
|
|
200
|
+
end
|
|
201
|
+
result[arr[0]] = {
|
|
202
|
+
bundle: arr[1],
|
|
203
|
+
name: name,
|
|
204
|
+
start: @helpers.epoch_to_date(arr[2]),
|
|
205
|
+
duration: {
|
|
206
|
+
seconds: arr[4],
|
|
207
|
+
time: @helpers.sec_to_time(arr[4])
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
end
|
|
211
|
+
return result
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def bad_request(request)
|
|
215
|
+
{
|
|
216
|
+
meta: {
|
|
217
|
+
code: 403,
|
|
218
|
+
request: request,
|
|
219
|
+
message: 'Bad request.'
|
|
220
|
+
},
|
|
221
|
+
data: []
|
|
222
|
+
}.to_json
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
end
|