TokiCLI 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24126edaca561eab0623a449445132dddf6697a0
4
- data.tar.gz: bec8ef8903fd53c79b8ef96696dc04fde69e9e7b
3
+ metadata.gz: 2b09a54e6095cd0db8771b463d7b0b42abcce848
4
+ data.tar.gz: a38757d420d82bba26f791d5db014034ddd0ca69
5
5
  SHA512:
6
- metadata.gz: 985a22eda651b23467d18db8e7198edd24c5454275a09958e31b4d38a74f9a4d44031e30033302dd7cba00a3485b0b7301470464f605ce94170d2e1f7a8ab2f3
7
- data.tar.gz: 8168f8fa325678e6e4d332476ee0d889a9819bbcf9a917e0cf89d7442b29c5295350f049a0f1ad5f19168f69193fb723df3ff0354767d00dab3247970d71dbac
6
+ metadata.gz: c038040cc9efe49a44e23b70e9c3341ccfbba70619248ebd1a198997f1f8ad1436f9ceae4f7e6e1a7256b605938f4cfa4f8e879cd93c48d8c620c88e79659097
7
+ data.tar.gz: b2301f6b6608aea4cbc75f616893c18f8e484223fece39d13cb7e4dc05a1e5ab42d229e1a1bde9c0833407cd65f18a81ecf446660ecbf06ff6ed8e88fc4b76b1
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # 0.0.2
2
+
3
+ - Repo URL
4
+ - Better description
5
+ - Readme
6
+ - New command: top
7
+ - Results are sorted
8
+
9
+ # 0.0.1
10
+
11
+ - DB: total + log
12
+ - ADN: total + log
data/README.md CHANGED
@@ -1,13 +1,84 @@
1
1
  # TokiCLI
2
2
 
3
- TODO: Write a gem description
3
+ Toki.app command-line client.
4
+
5
+ Access your Toki data from the local database or from the App.net backup channel.
4
6
 
5
7
  ## Installation
6
8
 
7
- $ gem install TokiCLI
9
+ gem install TokiCLI
8
10
 
9
11
  ## Usage
10
12
 
11
- TODO: Write usage instructions here
13
+ ### Log
14
+
15
+ The **log** command shows the entire log (history) for one app.
16
+
17
+ You don't have to specify the exact name of the identifier: for example, typing 'iterm' will find 'com.googlecod.iterm2'.
18
+
19
+ `toki log iterm`
20
+
21
+ The results are sorted by ascending date and time.
22
+
23
+ When pulling the data from ADN instead of the local database, the results are sorted by ascending synced message.
24
+
25
+ ### Total
26
+
27
+ The **total** command shows the total usage time for all apps.
28
+
29
+ `toki total`
30
+
31
+ The results are sorted by ascending usage time.
32
+
33
+ ### Top
34
+
35
+ The **top** command shows your top used apps.
36
+
37
+ `toki top`
38
+
39
+ TokiCLI shows the top 5 by default, but you can specify a number with the `-n` option:
40
+
41
+ `toki top -n 10`
42
+
43
+ ### Auth
44
+
45
+ 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
+
47
+ The last step is simply to do `toki auth` and paste the token.
48
+
49
+ ### Global option
50
+
51
+ TokiCLI accesses the local Toki database by default.
52
+
53
+ If you want to access the App.net backup channel instead, you have to specify the `-a` option:
54
+
55
+ `toki total -a`
56
+
57
+ `toki log vlc -a`
58
+
59
+ `toki top -n 10 -a`
60
+
61
+
62
+ ## Toki
63
+
64
+ [Toki](https://itunes.apple.com/fr/app/toki/id861749202?mt=12) is a Mac OS X app written by [Keitaroh Kobayashi](http://app.net/keita).
65
+
66
+ It's a time tracker for your apps that sits in the menu bar.
67
+
68
+ ## Important
69
+
70
+ **TokiCLI does _not_ track your apps.**
71
+
72
+ **Tracking is the job of Toki.app by @keita.**
73
+
74
+ TokiCLI interacts only with the Toki.app database or the App.net backup channel.
75
+
76
+ ## Next
77
+
78
+ Teasing: TokiCLI has only read-only commands... for now. ;)
79
+
80
+ ## Thanks
12
81
 
82
+ Keita was super nice and said "Awesome!" instead of just "Yes" or "GTFO" when I asked him if I could use the 'Toki' name for this companion Gem.
13
83
 
84
+ Many thanks and congrats to Keita! :)
data/TokiCLI.gemspec CHANGED
@@ -8,9 +8,9 @@ Gem::Specification.new do |spec|
8
8
  spec.version = TokiCLI::VERSION
9
9
  spec.authors = ["Eric Dejonckheere"]
10
10
  spec.email = ["eric@aya.io"]
11
- spec.summary = %q{Toki command-line client}
12
- spec.description = %q{Toki command-line client: read your Toki data from the local database or from the App.net backup channel}
13
- spec.homepage = ""
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, delete data from both...}
13
+ spec.homepage = "https://github.com/ericdke/TokiCLI"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
data/bin/toki CHANGED
@@ -2,7 +2,7 @@
2
2
  # encoding: utf-8
3
3
  # Toki command-line client
4
4
  # Author: Eric Dejonckheere (http://app.net/ericd)
5
- # Toki by: Keita Kobayashi (http://app.net/keita)
5
+ # Toki by: Keitaroh Kobayashi (http://app.net/keita)
6
6
 
7
7
  $PROGRAM_NAME = 'toki'
8
8
  require_relative '../lib/TokiCLI'
data/lib/TokiCLI/app.rb CHANGED
@@ -7,38 +7,39 @@ module TokiCLI
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
9
  def total
10
- if options[:adn]
11
- toki = total_adn
12
- else
13
- toki = total_db
14
- end
10
+ toki = create_toki(options)
15
11
  get_total(toki, options)
16
12
  end
17
13
 
14
+ desc "top", "Shows your most used apps"
15
+ option :adn, aliases: '-a', type: :boolean, desc: 'Select ADN channel as source (toki top -a)'
16
+ option :number, aliases: '-n', type: :numeric, desc: 'Specifi the number of apps (toki top -n 10)'
17
+ def top
18
+ toki = create_toki(options)
19
+ entries = toki.get_content(options)
20
+ clear
21
+ hits = toki.top(entries, options[:number] || 5)
22
+ puts TokiCLI::View.new.hits_table(hits.reverse)
23
+ puts "\n"
24
+ end
25
+
18
26
  desc "auth", "Input your App.net token for authorization"
19
27
  def auth
20
28
  puts Status.paste_token
21
29
  token = STDIN.gets.chomp!
22
- unless token.nil?
23
- save_token(token)
24
- else
25
- abort(Status.no_token)
26
- end
30
+ abort(Status.no_token) if token == ''
31
+ save_token(token)
27
32
  puts Status.done
28
33
  end
29
34
 
30
35
  desc "log APP", "Shows the complete log for an app"
31
- option :adn, aliases: '-a', type: :boolean, desc: 'Select ADN channel as source (toki total -a)'
36
+ option :adn, aliases: '-a', type: :boolean, desc: 'Select ADN channel as source (toki log -a)'
32
37
  def log(*args)
33
38
  abort(Status.specify_name) if args.empty?
34
- if options[:adn]
35
- toki = total_adn
36
- else
37
- toki = total_db
38
- end
39
39
  asked = args[0]
40
- synced = toki.get_content(options)
41
- app_data = toki.get_app(asked, synced)
40
+ toki = create_toki(options)
41
+ entries = toki.get_content(options)
42
+ app_data = toki.get_app(asked, entries)
42
43
  v = TokiCLI::View.new
43
44
  puts v.app_table(asked, app_data)
44
45
  puts "\n"
@@ -46,6 +47,14 @@ module TokiCLI
46
47
 
47
48
  private
48
49
 
50
+ def create_toki(options)
51
+ if options[:adn]
52
+ total_adn
53
+ else
54
+ total_db
55
+ end
56
+ end
57
+
49
58
  def total_adn
50
59
  clear
51
60
  puts Status.get_all
@@ -54,7 +63,7 @@ module TokiCLI
54
63
 
55
64
  def total_db
56
65
  clear
57
- puts "getting data from db\n"
66
+ #puts "getting data from db\n"
58
67
  init_toki_db
59
68
  end
60
69
 
@@ -35,7 +35,9 @@ module TokiCLI
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: "#{human[:hours]}h #{human[:minutes]}m #{human[:seconds]}s"
38
+ duration: "#{human[:hours]}h #{human[:minutes]}m #{human[:seconds]}s",
39
+ name: obj.app[:name],
40
+ raw_from: obj.app[:active_from]
39
41
  }
40
42
  end
41
43
  human = epoch_to_human(totals[:app])
@@ -43,16 +45,9 @@ module TokiCLI
43
45
  app_data
44
46
  end
45
47
  def all_data(synced)
46
- totals = {}
47
- synced.each do |obj|
48
- unless totals[obj.app[:name]].nil?
49
- totals[obj.app[:name]] = totals[obj.app[:name]] + obj.app[:total]
50
- else
51
- totals[obj.app[:name]] = obj.app[:total]
52
- end
53
- end
48
+ totals = get_totals(synced)
54
49
  bundles = {}
55
- sorted = totals.sort_by{ |k,v| v }
50
+ sorted = sort_totals(totals)
56
51
  sorted.each do |name, total|
57
52
  human = epoch_to_human(total)
58
53
  if human[:hours] < 1
@@ -63,9 +58,44 @@ module TokiCLI
63
58
  end
64
59
  bundles
65
60
  end
61
+ def top(synced, number = 5)
62
+ number = -number
63
+ totals = get_totals(synced)
64
+ sorted = sort_totals(totals)
65
+ humanized = []
66
+ sorted.each do |n,t|
67
+ humanized << [n, humanized_date(t)]
68
+ end
69
+ humanized[number..-1]
70
+ end
66
71
 
67
72
  private
68
73
 
74
+ def humanized_date(epoch)
75
+ human = epoch_to_human(epoch)
76
+ "#{human[:hours]}h #{human[:minutes]}m #{human[:seconds]}s"
77
+ end
78
+
79
+ def sort_totals(totals)
80
+ totals.sort_by { |k,v| v }
81
+ end
82
+
83
+ def get_totals(synced)
84
+ totals = {}
85
+ synced.each do |obj|
86
+ totals[obj.app[:name]] = app_total(obj, totals)
87
+ end
88
+ totals
89
+ end
90
+
91
+ def app_total(obj, totals)
92
+ unless totals[obj.app[:name]].nil?
93
+ totals[obj.app[:name]] + obj.app[:total]
94
+ else
95
+ obj.app[:total]
96
+ end
97
+ end
98
+
69
99
  def epoch_to_human(epoch)
70
100
  hours = epoch / 3600
71
101
  minutes = (epoch / 60 - hours * 60)
@@ -81,11 +111,10 @@ module TokiCLI
81
111
  def get_db_data
82
112
  db = open_db
83
113
  data = db.execute("SELECT * FROM KKAppActivity")
114
+ db.close
84
115
  data
85
116
  end
86
117
 
87
-
88
-
89
118
  def open_db
90
119
  tmp_path = "#{Dir.home}/temp/toki/"
91
120
  db_path = "#{Dir.home}/Library/Containers/us.kkob.Toki/Data/Documents/toki_data.sqlite3"
@@ -120,13 +149,13 @@ module TokiCLI
120
149
  msg = {}
121
150
  usr = {}
122
151
  app = {}
123
- msg[:id] = rand(100000000)
152
+ msg[:id] = obj[0]
124
153
  msg[:thread] = msg[:id]
125
154
  msg[:date] = Time.now
126
155
  usr[:username] = ENV['USERNAME']
127
156
  usr[:name] = usr[:username]
128
157
  usr[:id] = obj[5]
129
- app[:id] = obj[0]
158
+ app[:id] = msg[:id]
130
159
  app[:uuid] = obj[5]
131
160
  app[:name] = obj[1]
132
161
  app[:active_to] = obj[3]
@@ -1,3 +1,3 @@
1
1
  module TokiCLI
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/TokiCLI/view.rb CHANGED
@@ -9,23 +9,32 @@ module TokiCLI
9
9
  end
10
10
  table
11
11
  end
12
+ def hits_table(list)
13
+ table = init_table
14
+ table.title = "Your top apps monitored by Toki"
15
+ list.each.with_index(1) do |obj,index|
16
+ table << ["#{index}", "#{obj[0]}", "#{obj[1]}"]
17
+ end
18
+ table
19
+ end
12
20
  def app_table(asked, app_data)
13
21
  table = init_table
14
- table.title = "Toki time tracking for '#{asked}'"
15
- table.headings = ['From', 'To', 'Duration']
22
+ table.style = { :width => 100 }
23
+ table.title = "Toki time tracking for '#{asked}' => #{app_data.first[1][:name]}"
24
+ table.headings = ['From', 'To', 'Duration', 'Sync id']
16
25
  @index = 0
17
26
  @length = app_data.length - 1
18
- app_data.each do |id, log|
19
- if id == 'total'
20
- @total = log
21
- next
22
- end
27
+ @total = app_data.select {|k,v| k == 'total'}
28
+ app_data.delete('total')
29
+ data = app_data.to_a
30
+ data.sort_by! {|k,v| v[:raw_from] }
31
+ data.each do |id, log|
23
32
  @index += 1
24
- table << ["#{log[:from]}", "#{log[:to]}", "#{log[:duration]}"]
33
+ table << ["#{log[:from]}", "#{log[:to]}", "#{log[:duration]}", "#{id}"]
25
34
  table << :separator unless @index == @length
26
35
  end
27
36
  table << :separator
28
- table << [{ :value => "Total: #{@total}", :colspan => 3, :alignment => :center }]
37
+ table << [{ :value => "Total: #{@total['total']}", :colspan => 4, :alignment => :center }]
29
38
  table
30
39
  end
31
40
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: TokiCLI
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Dejonckheere
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-18 00:00:00.000000000 Z
11
+ date: 2014-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -94,8 +94,8 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- description: 'Toki command-line client: read your Toki data from the local database
98
- or from the App.net backup channel'
97
+ description: 'Toki.app command-line client: read your Toki data from the local database
98
+ or from the App.net backup channel, delete data from both...'
99
99
  email:
100
100
  - eric@aya.io
101
101
  executables:
@@ -104,6 +104,7 @@ extensions: []
104
104
  extra_rdoc_files: []
105
105
  files:
106
106
  - ".gitignore"
107
+ - CHANGELOG.md
107
108
  - Gemfile
108
109
  - LICENSE.txt
109
110
  - README.md
@@ -119,7 +120,7 @@ files:
119
120
  - lib/TokiCLI/status.rb
120
121
  - lib/TokiCLI/version.rb
121
122
  - lib/TokiCLI/view.rb
122
- homepage: ''
123
+ homepage: https://github.com/ericdke/TokiCLI
123
124
  licenses:
124
125
  - MIT
125
126
  metadata: {}
@@ -142,6 +143,6 @@ rubyforge_project:
142
143
  rubygems_version: 2.2.2
143
144
  signing_key:
144
145
  specification_version: 4
145
- summary: Toki command-line client
146
+ summary: Toki.app command-line client
146
147
  test_files: []
147
148
  has_rdoc: