TokiCLI 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +31 -2
- data/TokiCLI.gemspec +1 -1
- data/lib/TokiCLI/app.rb +88 -14
- data/lib/TokiCLI/module.rb +40 -26
- data/lib/TokiCLI/status.rb +6 -0
- data/lib/TokiCLI/version.rb +1 -1
- data/lib/TokiCLI/view.rb +29 -8
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3cc53491a92de90d5c231b3494d66aee6d8e3a5
|
4
|
+
data.tar.gz: 443389d76b7e0e0544bf95d1e90f12c062a2f305
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19cd81f0e087c55785c0bbdfe45821803fd47e75c3b353356d9f905083c926a18e994355b4ee74c3c6826f6bf472a173fb9fa26853aaeaa4f7d89855a91d87bb
|
7
|
+
data.tar.gz: 810aec844f4f02afb7d9950374a6517133b6145ec3b79941e990f6199a8b2dfb80c01bb5b5abd52b4d17884551ca531b6a84addc1afa99c1243a636f4423a937
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -4,6 +4,9 @@ Toki.app command-line client.
|
|
4
4
|
|
5
5
|
Access your Toki data from the local database or from the App.net backup channel.
|
6
6
|
|
7
|
+

|
8
|
+
|
9
|
+
|
7
10
|
## Installation
|
8
11
|
|
9
12
|
gem install TokiCLI
|
@@ -40,13 +43,29 @@ TokiCLI shows the top 5 by default, but you can specify a number with the `-n` o
|
|
40
43
|
|
41
44
|
`toki top -n 10`
|
42
45
|
|
46
|
+
### Day
|
47
|
+
|
48
|
+
The **day** command shows your top used apps on a specific day.
|
49
|
+
|
50
|
+
The date you type has to be formatted like this: year-month-day
|
51
|
+
|
52
|
+
`toki day 2014-04-19`
|
53
|
+
|
54
|
+
### Range
|
55
|
+
|
56
|
+
The **range** command shows your top used apps between two specific days.
|
57
|
+
|
58
|
+
The dates you type have to be formatted like this: year-month-day and separated by a single space.
|
59
|
+
|
60
|
+
`toki range 2014-04-17 2014-04-19`
|
61
|
+
|
43
62
|
### Auth
|
44
63
|
|
45
64
|
In order to be able to access your ADN channel (optional), you have to obtain a "token" (secret code) from App.net: go to your App.net account page, click "Your apps" then find "Create a token for yourself."
|
46
65
|
|
47
66
|
The last step is simply to do `toki auth` and paste the token.
|
48
67
|
|
49
|
-
### Global option
|
68
|
+
### Global option: ADN
|
50
69
|
|
51
70
|
TokiCLI accesses the local Toki database by default.
|
52
71
|
|
@@ -56,7 +75,17 @@ If you want to access the App.net backup channel instead, you have to specify th
|
|
56
75
|
|
57
76
|
`toki log vlc -a`
|
58
77
|
|
59
|
-
`toki top -n 10 -a`
|
78
|
+
`toki top -n 10 -a`
|
79
|
+
|
80
|
+
### Global option: JSON
|
81
|
+
|
82
|
+
Export the Toki results as a JSON file with the `-j` option:
|
83
|
+
|
84
|
+
`toki total -j`
|
85
|
+
|
86
|
+
`toki day 2014-04-18 -j`
|
87
|
+
|
88
|
+
`toki top -n 10 -j`
|
60
89
|
|
61
90
|
|
62
91
|
## Toki
|
data/TokiCLI.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Eric Dejonckheere"]
|
10
10
|
spec.email = ["eric@aya.io"]
|
11
11
|
spec.summary = %q{Toki.app command-line client}
|
12
|
-
spec.description = %q{Toki.app command-line client: read your Toki data from the local database or from the App.net backup channel,
|
12
|
+
spec.description = %q{Toki.app command-line client: read your Toki data from the local database or from the App.net backup channel. Show the log for an app, the top apps, the grand total, usage by day or range of days, etc.}
|
13
13
|
spec.homepage = "https://github.com/ericdke/TokiCLI"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/lib/TokiCLI/app.rb
CHANGED
@@ -6,21 +6,26 @@ module TokiCLI
|
|
6
6
|
|
7
7
|
desc "total", "Shows the total usage of all apps"
|
8
8
|
option :adn, aliases: '-a', type: :boolean, desc: 'Select ADN channel as source (toki total -a)'
|
9
|
+
option :json, aliases: '-j', type: :boolean, desc: 'Export the results as a JSON file'
|
9
10
|
def total
|
10
11
|
toki = create_toki(options)
|
11
|
-
get_total(toki, options)
|
12
|
+
apps = get_total(toki, options)
|
13
|
+
clear
|
14
|
+
puts TokiCLI::View.new.total_table(apps)
|
15
|
+
puts "\n"
|
16
|
+
export(:json, apps, "toki-total-#{Time.now.to_s[0..9]}") if options[:json]
|
12
17
|
end
|
13
18
|
|
14
19
|
desc "top", "Shows your most used apps"
|
15
20
|
option :adn, aliases: '-a', type: :boolean, desc: 'Select ADN channel as source (toki top -a)'
|
16
|
-
option :number, aliases: '-n', type: :numeric, desc: '
|
21
|
+
option :number, aliases: '-n', type: :numeric, desc: 'Specify the number of apps (toki top -n 10)'
|
22
|
+
option :json, aliases: '-j', type: :boolean, desc: 'Export the results as a JSON file'
|
17
23
|
def top
|
18
|
-
toki =
|
19
|
-
entries = toki.get_content(options)
|
24
|
+
toki, entries = init(options)
|
20
25
|
clear
|
21
26
|
hits = toki.top(entries, options[:number] || 5)
|
22
|
-
|
23
|
-
|
27
|
+
view_hits_table(hits)
|
28
|
+
export(:json, hits, "toki-top-#{Time.now.to_s[0..9]}") if options[:json]
|
24
29
|
end
|
25
30
|
|
26
31
|
desc "auth", "Input your App.net token for authorization"
|
@@ -34,19 +39,90 @@ module TokiCLI
|
|
34
39
|
|
35
40
|
desc "log APP", "Shows the complete log for an app"
|
36
41
|
option :adn, aliases: '-a', type: :boolean, desc: 'Select ADN channel as source (toki log -a)'
|
42
|
+
option :json, aliases: '-j', type: :boolean, desc: 'Export the results as a JSON file'
|
37
43
|
def log(*args)
|
38
44
|
abort(Status.specify_name) if args.empty?
|
39
45
|
asked = args[0]
|
40
|
-
toki =
|
41
|
-
entries = toki.get_content(options)
|
46
|
+
toki, entries = init(options)
|
42
47
|
app_data = toki.get_app(asked, entries)
|
43
|
-
|
44
|
-
|
45
|
-
|
48
|
+
view_app_table(asked, app_data)
|
49
|
+
export(:json, app_data, "toki-log-#{asked}-#{Time.now.to_s[0..9]}") if options[:json]
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "day DATE", "Shows all apps used on a specific day (toki day 2014-04-19)"
|
53
|
+
option :adn, aliases: '-a', type: :boolean, desc: 'Select ADN channel as source (toki day 2014-04-19 -a)'
|
54
|
+
option :json, aliases: '-j', type: :boolean, desc: 'Export the results as a JSON file'
|
55
|
+
def day(*args)
|
56
|
+
abort(Status.specify_day) if args.empty?
|
57
|
+
begin
|
58
|
+
date = DateTime.strptime(args[0], '%Y-%m-%d')
|
59
|
+
rescue ArgumentError
|
60
|
+
abort(Status.specify_day)
|
61
|
+
end
|
62
|
+
toki, entries = init(options)
|
63
|
+
day_data = toki.get_day(date, entries, options)
|
64
|
+
clear
|
65
|
+
view_day_table(args[0], day_data)
|
66
|
+
export(:json, day_data, "toki-day-#{args[0]}") if options[:json]
|
46
67
|
end
|
47
68
|
|
69
|
+
desc "range DAY1 DAY2", "Shows all apps used between day 1 and day 2 (toki range 2014-04-16 2014-04-18)"
|
70
|
+
option :adn, aliases: '-a', type: :boolean, desc: 'Select ADN channel as source (toki range 2014-04-16 2014-04-18 -a)'
|
71
|
+
option :json, aliases: '-j', type: :boolean, desc: 'Export the results as a JSON file'
|
72
|
+
def range(*args)
|
73
|
+
abort(Status.specify_range) if args.empty? || args.length != 2
|
74
|
+
begin
|
75
|
+
day1 = DateTime.strptime(args[0], '%Y-%m-%d')
|
76
|
+
day2 = DateTime.strptime(args[1], '%Y-%m-%d')
|
77
|
+
rescue ArgumentError
|
78
|
+
abort(Status.specify_range)
|
79
|
+
end
|
80
|
+
toki, entries = init(options)
|
81
|
+
range_data = toki.get_range(day1, day2, entries, options)
|
82
|
+
clear
|
83
|
+
view_range_table(args[0], args[1], range_data)
|
84
|
+
export(:json, range_data, "toki-range-#{args[0]}_#{args[1]}") if options[:json]
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
48
90
|
private
|
49
91
|
|
92
|
+
def export(type, data, filename)
|
93
|
+
case type
|
94
|
+
when :json
|
95
|
+
name = Dir.home + "/temp/toki/#{filename}.json"
|
96
|
+
File.write(name, data.to_h.to_json)
|
97
|
+
puts "File converted and exported to #{name}\n\n"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def view_range_table(start, to, range_data)
|
102
|
+
puts TokiCLI::View.new.range_table(start, to, range_data)
|
103
|
+
puts "\n"
|
104
|
+
end
|
105
|
+
|
106
|
+
def view_day_table(date, day_data)
|
107
|
+
puts TokiCLI::View.new.day_table(date, day_data)
|
108
|
+
puts "\n"
|
109
|
+
end
|
110
|
+
|
111
|
+
def view_app_table(asked, app_data)
|
112
|
+
puts TokiCLI::View.new.app_table(asked, app_data)
|
113
|
+
puts "\n"
|
114
|
+
end
|
115
|
+
|
116
|
+
def view_hits_table(hits)
|
117
|
+
puts TokiCLI::View.new.hits_table(hits.reverse)
|
118
|
+
puts "\n"
|
119
|
+
end
|
120
|
+
|
121
|
+
def init(options)
|
122
|
+
toki = create_toki(options)
|
123
|
+
return toki, toki.get_content(options)
|
124
|
+
end
|
125
|
+
|
50
126
|
def create_toki(options)
|
51
127
|
if options[:adn]
|
52
128
|
total_adn
|
@@ -77,9 +153,7 @@ module TokiCLI
|
|
77
153
|
puts Status.error(e)
|
78
154
|
exit
|
79
155
|
end
|
80
|
-
|
81
|
-
puts TokiCLI::View.new.total_table(apps)
|
82
|
-
puts "\n"
|
156
|
+
apps
|
83
157
|
end
|
84
158
|
|
85
159
|
def init_toki_db
|
data/lib/TokiCLI/module.rb
CHANGED
@@ -1,76 +1,90 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module TokiCLI
|
3
3
|
class Toki
|
4
|
+
|
4
5
|
def initialize(token, channel_id)
|
5
6
|
@token = token
|
6
7
|
@channel_id = channel_id
|
7
8
|
end
|
9
|
+
|
8
10
|
def get_content(options)
|
9
11
|
synced = []
|
10
12
|
if options[:adn]
|
11
|
-
|
12
|
-
messages.reverse.each do |obj|
|
13
|
+
get_adn_data.reverse.each do |obj|
|
13
14
|
synced << make_obj_from_adn(obj)
|
14
15
|
end
|
15
16
|
else
|
16
|
-
|
17
|
-
content.each do |obj|
|
17
|
+
get_db_data.each do |obj|
|
18
18
|
synced << make_obj_from_db(obj)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
synced
|
22
22
|
end
|
23
|
+
|
23
24
|
def get_app(app, synced)
|
24
25
|
name_regex = /#{app.downcase}/
|
25
26
|
app_data = {}
|
26
27
|
totals = {}
|
27
28
|
synced.each do |obj|
|
28
29
|
next unless obj.app[:name].downcase =~ name_regex
|
29
|
-
|
30
|
-
totals[:app] = totals[:app] + obj.app[:total]
|
31
|
-
else
|
30
|
+
if totals[:app].nil?
|
32
31
|
totals[:app] = obj.app[:total]
|
32
|
+
else
|
33
|
+
totals[:app] = totals[:app] + obj.app[:total]
|
33
34
|
end
|
34
|
-
human = epoch_to_human(obj.app[:total])
|
35
35
|
app_data[obj.msg[:id]] = {
|
36
36
|
from: Time.at(obj.app[:active_from]).strftime("%Y/%m/%d %Hh:%Mm:%Ss"),
|
37
37
|
to: Time.at(obj.app[:active_to]).strftime("%Y/%m/%d %Hh:%Mm:%Ss"),
|
38
|
-
duration:
|
38
|
+
duration: humanized_date(obj.app[:total]),
|
39
39
|
name: obj.app[:name],
|
40
40
|
raw_from: obj.app[:active_from]
|
41
41
|
}
|
42
42
|
end
|
43
|
-
|
44
|
-
app_data['total'] = "#{human[:hours]}h #{human[:minutes]}m #{human[:seconds]}s"
|
43
|
+
app_data['total'] = humanized_date(totals[:app])
|
45
44
|
app_data
|
46
45
|
end
|
46
|
+
|
47
47
|
def all_data(synced)
|
48
|
-
|
48
|
+
sorted = get_sorted_totals(synced)
|
49
49
|
bundles = {}
|
50
|
-
sorted =
|
51
|
-
sorted.each do |name, total|
|
52
|
-
human = epoch_to_human(total)
|
53
|
-
if human[:hours] < 1
|
54
|
-
bundles[name] = "#{human[:minutes]}m #{human[:seconds]}s"
|
55
|
-
else
|
56
|
-
bundles[name] = "#{human[:hours]}h #{human[:minutes]}m #{human[:seconds]}s"
|
57
|
-
end
|
58
|
-
end
|
50
|
+
sorted.each {|name, total| bundles[name] = humanized_date(total)}
|
59
51
|
bundles
|
60
52
|
end
|
53
|
+
|
61
54
|
def top(synced, number = 5)
|
62
55
|
number = -number
|
63
|
-
|
64
|
-
sorted = sort_totals(totals)
|
56
|
+
sorted = get_sorted_totals(synced)
|
65
57
|
humanized = []
|
66
|
-
sorted.each
|
67
|
-
humanized << [n, humanized_date(t)]
|
68
|
-
end
|
58
|
+
sorted.each {|n,t| humanized << [n, humanized_date(t)]}
|
69
59
|
humanized[number..-1]
|
70
60
|
end
|
71
61
|
|
62
|
+
def get_day(date, entries, options)
|
63
|
+
min_epoch = date.to_time.to_i
|
64
|
+
max_epoch = date.next_day.to_time.to_i
|
65
|
+
get_between(min_epoch, max_epoch, entries)
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_range(day1, day2, entries, options)
|
69
|
+
min_epoch = day1.to_time.to_i
|
70
|
+
max_epoch = day2.next_day.to_time.to_i # between start of 1 and end of 2
|
71
|
+
get_between(min_epoch, max_epoch, entries)
|
72
|
+
end
|
73
|
+
|
72
74
|
private
|
73
75
|
|
76
|
+
def get_between(epoch1, epoch2, entries)
|
77
|
+
range = entries.select {|obj| obj.app[:active_from] > epoch1 && obj.app[:active_from] < epoch2}
|
78
|
+
day_totals = sort_totals get_totals(range)
|
79
|
+
humanized = []
|
80
|
+
day_totals.each {|n,t| humanized << [n, humanized_date(t)]}
|
81
|
+
humanized
|
82
|
+
end
|
83
|
+
|
84
|
+
def get_sorted_totals(synced)
|
85
|
+
sort_totals(get_totals(synced))
|
86
|
+
end
|
87
|
+
|
74
88
|
def humanized_date(epoch)
|
75
89
|
human = epoch_to_human(epoch)
|
76
90
|
"#{human[:hours]}h #{human[:minutes]}m #{human[:seconds]}s"
|
data/lib/TokiCLI/status.rb
CHANGED
@@ -25,6 +25,12 @@ module TokiCLI
|
|
25
25
|
def self.specify_name
|
26
26
|
"\nPlease specify the name of the app (or part of it).\n\n"
|
27
27
|
end
|
28
|
+
def self.specify_day
|
29
|
+
"\nPlease specify the date with this format: 2014-04-19\n\n"
|
30
|
+
end
|
31
|
+
def self.specify_range
|
32
|
+
"\nPlease specify the range with this format: 2014-04-17 2014-04-19\n\n"
|
33
|
+
end
|
28
34
|
def self.run_auth
|
29
35
|
"\nPlease run `toki auth` first.\n\n"
|
30
36
|
end
|
data/lib/TokiCLI/version.rb
CHANGED
data/lib/TokiCLI/view.rb
CHANGED
@@ -4,18 +4,27 @@ module TokiCLI
|
|
4
4
|
def total_table(list)
|
5
5
|
table = init_table
|
6
6
|
table.title = "Your apps monitored by Toki"
|
7
|
-
list
|
8
|
-
|
9
|
-
|
10
|
-
table
|
7
|
+
table_2(list, table)
|
8
|
+
end
|
9
|
+
def day_table(day, list)
|
10
|
+
table = init_table
|
11
|
+
table.title = "Your apps monitored by Toki on #{day}"
|
12
|
+
table_2(list, table)
|
13
|
+
end
|
14
|
+
def range_table(day1, day2, list)
|
15
|
+
table = init_table
|
16
|
+
table.title = "Your apps monitored by Toki between #{day1} and #{day2}"
|
17
|
+
table_2(list, table)
|
18
|
+
end
|
19
|
+
def hours_table(hour1, hour2, list)
|
20
|
+
table = init_table
|
21
|
+
table.title = "Your apps monitored by Toki between #{hour1} and #{hour2}"
|
22
|
+
table_2(list, table)
|
11
23
|
end
|
12
24
|
def hits_table(list)
|
13
25
|
table = init_table
|
14
26
|
table.title = "Your top apps monitored by Toki"
|
15
|
-
list
|
16
|
-
table << ["#{index}", "#{obj[0]}", "#{obj[1]}"]
|
17
|
-
end
|
18
|
-
table
|
27
|
+
table2_index(list, table)
|
19
28
|
end
|
20
29
|
def app_table(asked, app_data)
|
21
30
|
table = init_table
|
@@ -45,5 +54,17 @@ module TokiCLI
|
|
45
54
|
t.style = { :width => 75 }
|
46
55
|
end
|
47
56
|
end
|
57
|
+
def table_2(list, table)
|
58
|
+
list.each do |k,v|
|
59
|
+
table << ["#{k}", "#{v}"]
|
60
|
+
end
|
61
|
+
table
|
62
|
+
end
|
63
|
+
def table2_index(list, table)
|
64
|
+
list.each.with_index(1) do |obj,index|
|
65
|
+
table << ["#{index}", "#{obj[0]}", "#{obj[1]}"]
|
66
|
+
end
|
67
|
+
table
|
68
|
+
end
|
48
69
|
end
|
49
70
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: TokiCLI
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Dejonckheere
|
@@ -95,7 +95,8 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
description: 'Toki.app command-line client: read your Toki data from the local database
|
98
|
-
or from the App.net backup channel,
|
98
|
+
or from the App.net backup channel. Show the log for an app, the top apps, the grand
|
99
|
+
total, usage by day or range of days, etc.'
|
99
100
|
email:
|
100
101
|
- eric@aya.io
|
101
102
|
executables:
|