# encoding: utf-8 module TokiCLI class Toki def initialize(token, channel_id) @token = token @channel_id = channel_id end def get_content(options) synced = [] if options[:adn] get_adn_data.reverse.each do |obj| synced << make_obj_from_adn(obj) end else get_db_data.each do |obj| synced << make_obj_from_db(obj) end end synced end def get_app(app, synced) name_regex = /#{app.downcase}/ app_data = {} totals = {} synced.each do |obj| next unless obj.app[:name].downcase =~ name_regex if totals[:app].nil? totals[:app] = obj.app[:total] else totals[:app] = totals[:app] + obj.app[:total] end 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) bundles = {} sorted.each {|name, total| bundles[name] = humanized_date(total)} bundles end def top(synced, number = 5) number = -number sorted = get_sorted_totals(synced) humanized = [] sorted.each {|n,t| humanized << [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) humanized = [] day_totals.each {|n,t| humanized << [n, humanized_date(t)]} humanized 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) totals = {} synced.each do |obj| totals[obj.app[:name]] = app_total(obj, totals) end totals end def app_total(obj, totals) unless totals[obj.app[:name]].nil? totals[obj.app[:name]] + obj.app[:total] else obj.app[:total] end 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) #ericd 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 tmp_path = "#{Dir.home}/temp/toki/" db_path = "#{Dir.home}/Library/Containers/us.kkob.Toki/Data/Documents/toki_data.sqlite3" FileUtils.mkdir_p(tmp_path) FileUtils.copy(db_path, "#{tmp_path}/toki_data.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