# encoding: utf-8 module TokiCLI class Toki CLIENT_ID = 'm6AccJFM56ENCn58Vde9cSg3uSpbvAAs' CALLBACK_URL = 'http://aya.io/toki_cli/auth.html' def initialize(token, channel_id) @token = token @channel_id = channel_id end def get_content(options) if options[:adn] get_adn_data.reverse.map {|obj| make_obj_from_adn(obj)} else get_db_data.map {|obj| make_obj_from_db(obj)} end end def get_app(app, synced) name_regex = /#{app.downcase}/ app_data = {} totals = {} totals[:app] = 0 found = synced.select {|obj| obj.app[:name].downcase =~ name_regex} found.each do |obj| totals[:app] += obj.app[:total] app_data[obj.msg[:id]] = { from: Time.at(obj.app[:active_from]).strftime("%Y/%m/%d %Hh:%Mm:%Ss"), to: Time.at(obj.app[:active_to]).strftime("%Y/%m/%d %Hh:%Mm:%Ss"), duration: humanized_date(obj.app[:total]), name: obj.app[:name], raw_from: obj.app[:active_from] } end app_data['total'] = humanized_date(totals[:app]) app_data end def all_data(synced) sorted = get_sorted_totals(synced) sorted.inject({}) do |bundles, obj| bundles.merge(obj[0] => humanized_date(obj[1])) #name, total end end def top(synced, number = 5) number = -number sorted = get_sorted_totals(synced) humanized = sorted.map {|n,t| [n, humanized_date(t)]} humanized[number..-1] end def get_day(date, entries, options) min_epoch = date.to_time.to_i max_epoch = date.next_day.to_time.to_i get_between(min_epoch, max_epoch, entries) end def get_range(day1, day2, entries, options) min_epoch = day1.to_time.to_i max_epoch = day2.next_day.to_time.to_i # between start of 1 and end of 2 get_between(min_epoch, max_epoch, entries) end private def get_between(epoch1, epoch2, entries) range = entries.select {|obj| obj.app[:active_from] > epoch1 && obj.app[:active_from] < epoch2} day_totals = sort_totals get_totals(range) day_totals.map {|n,t| [n, humanized_date(t)]} end def get_sorted_totals(synced) sort_totals(get_totals(synced)) end def humanized_date(epoch) human = epoch_to_human(epoch) "#{human[:hours]}h #{human[:minutes]}m #{human[:seconds]}s" end def sort_totals(totals) totals.sort_by { |k,v| v } end def get_totals(synced) synced.inject({}) do |result, obj| result.merge(obj.app[:name] => app_total(obj, result)) end end def app_total(obj, totals) totals[obj.app[:name]].nil? ? obj.app[:total] : totals[obj.app[:name]] + obj.app[:total] end def epoch_to_human(epoch) hours = epoch / 3600 minutes = (epoch / 60 - hours * 60) seconds = (epoch - (minutes * 60 + hours * 3600)) {hours: hours, minutes: minutes, seconds: seconds} end def get_adn_data channels = ADNChannels::GetMessages.new(@token) channels.get_messages(@channel_id) end def get_db_data db = open_db data = db.execute("SELECT * FROM KKAppActivity") db.close data end def open_db toki_path = "#{Dir.home}/.TokiCLI" db_path = "#{Dir.home}/Library/Containers/us.kkob.Toki/Data/Documents/toki_data.sqlite3" abort(Status.no_db) unless File.exist? db_path FileUtils.mkdir_p(toki_path) unless Dir.exist?(toki_path) FileUtils.copy(db_path, "#{toki_path}/toki_data.sqlite3.bak") Amalgalite::Database.new(db_path) end def make_obj_from_adn(obj) msg = {} usr = {} app = {} d = obj['annotations'][0]['value']['d'] msg[:id] = obj['id'] msg[:thread] = obj['thread_id'] msg[:date] = parsed_date obj['created_at'] usr[:username] = obj['user']['username'] usr[:name] = obj['user']['name'] usr[:id] = obj['user']['id'] app[:id] = d['id'] app[:uuid] = d['UUID'] app[:name] = d['bundleIdentifier'] app[:active_to] = d['activeTo'] app[:active_from] = d['activeFrom'] app[:total] = d['totalSeconds'] OpenStruct.new(app: app, msg: msg, usr: usr) end def make_obj_from_db(obj) # content is an array: # id (INTEGER) 0, bundleIdentifier (VARCHAR) 1, activeFrom (INTEGER) 2, activeTo (INTEGER) 3, totalSeconds (INTEGER) 4, UUID (VARCHAR) 5, synced (INTEGER) 6, availableToSync (INTEGER) 7 msg = {} usr = {} app = {} msg[:id] = obj[0] msg[:thread] = msg[:id] msg[:date] = Time.now usr[:username] = ENV['USERNAME'] usr[:name] = usr[:username] usr[:id] = obj[5] app[:id] = msg[:id] app[:uuid] = obj[5] app[:name] = obj[1] app[:active_to] = obj[3] app[:active_from] = obj[2] app[:total] = obj[4] OpenStruct.new(app: app, msg: msg, usr: usr) end def parsed_date(string) "#{string[0...10]} #{string[11...19]}" end end end