lib/ayadn/workers.rb in ayadn-1.8.2 vs lib/ayadn/workers.rb in ayadn-2.0

- old
+ new

@@ -1,92 +1,113 @@ # encoding: utf-8 module Ayadn class Workers def initialize - @shell = Thor::Shell::Color.new + @thor = Thor::Shell::Color.new + @status = Status.new end + def table_borders + if Settings.options[:formats][:table][:borders] == true + { :width => Settings.options[:formats][:table][:width], border_x: '—', border_i: '+', border_y: '|' } + else + { :width => Settings.options[:formats][:table][:width], border_x: ' ', border_i: ' ', border_y: ' ' } + end + end + def build_aliases_list(list) table = init_table table.title = "List of your channel aliases".color(:cyan) + "".color(:white) - table.style = {border_x: '~', border_i: '+', border_y: ':'} - list.each {|k,v| table << ["#{k}".color(:green), "#{v}".color(:red)]} + table.style = table_borders() + table.headings = [ 'Channel', 'Alias' ] + list.each_with_index do |obj, index| + table << [obj[0].to_s.color(:green), obj[1].color(:red)] + if index + 1 != list.length && Settings.options[:timeline][:compact] == false + table << :separator + end + end table end def build_blacklist_list(list) table = init_table table.title = "Your blacklist".color(:cyan) + "".color(:white) - table.style = {border_x: '~', border_i: '+', border_y: ':'} - list = list.sort_by {|k,v| v} # no sort_by! for Daybreak dbs - list.each {|k,v| table << ["#{v.capitalize}".color(:green), "#{k}".color(:red)]} + table.style = table_borders() + table.headings = [ 'Name', 'Type' ] + list.sort! + list.each_with_index do |obj, index| + table << ["#{obj[1].capitalize}".color(:green), "#{obj[0]}".color(:red)] + if index + 1 != list.length && Settings.options[:timeline][:compact] == false + table << :separator + end + end table end def build_reposted_list(list, target) table = init_table table.title = "List of users who reposted post ".color(:cyan) + "#{target}".color(:red) + "".color(:white) users_list = [] list.each do |obj| obj['name'].nil? ? name = "" : name = obj['name'] - users_list << {:username => obj['username'], :name => name, :you_follow => obj['you_follow'], :follows_you => obj['follows_you'], :id => obj['id']} + users_list << {:username => obj['username'], :name => name, :you_follow => obj['you_follow'], :follows_you => obj['follows_you'], :id => obj['id'], :posts => obj['counts']['posts']} end - table.style = {border_x: ' ', border_i: ' ', border_y: ' '} + table.style = table_borders() return users_list, table end def build_starred_list(list, target) table = init_table table.title = "List of users who starred post ".color(:cyan) + "#{target}".color(:red) + "".color(:white) users_list = [] list.each do |obj| obj['name'].nil? ? name = "" : name = obj['name'] - users_list << {:username => obj['username'], :name => name, :you_follow => obj['you_follow'], :follows_you => obj['follows_you'], :id => obj['id']} + users_list << {:username => obj['username'], :name => name, :you_follow => obj['you_follow'], :follows_you => obj['follows_you'], :id => obj['id'], :posts => obj['counts']['posts']} end - table.style = {border_x: ' ', border_i: ' ', border_y: ' '} + table.style = table_borders() return users_list, table end - def build_followings_list(list, target) #takes a hash of users with ayadn format + def build_followings_list(list, target, options = {}) #takes a hash of users with ayadn format table = init_table table.title = if target == "me" "List of users you're following".color(:cyan) + "".color(:white) else "List of users ".color(:cyan) + "#{target}".color(:red) + " is following ".color(:cyan) + "".color(:white) end - table.style = {border_x: ' ', border_i: ' ', border_y: ' '} + table.style = table_borders() users_list = build_users_array(list) - build_users_list(users_list, table) + build_users_list(users_list, table, options) end - def build_followers_list(list, target) + def build_followers_list(list, target, options = {}) table = init_table table.title = if target == "me" "List of your followers".color(:cyan) + "".color(:white) else "List of users following ".color(:cyan) + "#{target}".color(:red) + "".color(:white) end - table.style = {border_x: ' ', border_i: ' ', border_y: ' '} - build_users_list(build_users_array(list), table) + table.style = table_borders() + build_users_list(build_users_array(list), table, options) end - def build_muted_list(list) + def build_muted_list(list, options = {}) table = init_table table.title = "List of users you muted".color(:cyan) + "".color(:white) - table.style = {border_x: ' ', border_i: ' ', border_y: ' '} - build_users_list(build_users_array(list), table) + table.style = table_borders() + build_users_list(build_users_array(list), table, options) end - def build_blocked_list(list) + def build_blocked_list(list, options = {}) table = init_table table.title = "List of users you blocked".color(:cyan) + "".color(:white) - table.style = {border_x: ' ', border_i: ' ', border_y: ' '} - build_users_list(build_users_array(list), table) + table.style = table_borders() + build_users_list(build_users_array(list), table, options) end - def build_users_list(list, table) + def build_users_list(list, table, options = {}) users = at(list.map {|obj| obj[:username]}) ids = list.map {|obj| obj[:id].to_i} ranks = NiceRank.new.from_ids(ids) indexed_ranks = {} ranks.each do |r| @@ -95,13 +116,22 @@ break else indexed_ranks[r['user_id']] = r end end - table << ['USERNAME'.color(:red), 'NAME'.color(:red), 'POSTS/DAY'.color(:red)] + table << ['USERNAME'.color(:red), 'NAME'.color(:red), 'POSTS'.color(:red), 'POSTS/DAY'.color(:red)] table << :separator - list.each_with_index do |obj, index| + arr = [] + if options[:username] + list.sort_by! { |obj| obj[:username] } + elsif options[:name] + list.sort_by! { |obj| obj[:name].downcase } + elsif options[:posts] + list.sort_by! { |obj| [obj[:posts], obj[:username]] } + end + list.each do |obj| + obj[:name] = "" if obj[:name].nil? unless indexed_ranks == false details = indexed_ranks[obj[:id].to_i] if details['user']['posts_day'] == -1 posts_day = 'ignored' else @@ -109,17 +139,25 @@ end else posts_day = 'unknown' end obj[:username].length > 23 ? username = "#{obj[:username][0..20]}..." : username = obj[:username] - unless obj[:name].nil? || obj[:name].empty? - obj[:name].length > 23 ? name = "#{obj[:name][0..20]}..." : name = obj[:name] - table << [ "@#{username} ".color(Settings.options[:colors][:username]), "#{name}", posts_day ] - else - table << [ "@#{username} ".color(Settings.options[:colors][:username]), "", posts_day ] - end - if index + 1 != list.length && Settings.options[:timeline][:compact] == false + obj[:name].length > 23 ? name = "#{obj[:name][0..20]}..." : name = obj[:name] + arr << [ "@#{username} ".color(Settings.options[:colors][:username]), "#{name}", obj[:posts], posts_day ] + end + if options[:posts_day] + arr.sort_by! { |obj| obj[3].to_f } + end + if options[:reverse] + arr.reverse! + end + if Settings.options[:formats][:list][:reverse] == true + arr.reverse! + end + arr.each_with_index do |obj, index| + table << arr[index] + if index + 1 != arr.length && Settings.options[:timeline][:compact] == false table << :separator end end table end @@ -127,42 +165,50 @@ # builds a hash of hashes, each hash is a normalized post with post id as a key def build_posts(data, niceranks = {}) # skip objects in blacklist unless force posts = {} data.each.with_index(1) do |post, index| - unless Settings.options[:force] - if Databases.blacklist[post['source']['name'].downcase] - Debug.skipped({source: post['source']['name']}) - next + unless Settings.global[:force] == true + if Settings.options[:blacklist][:active] == true + if Databases.is_in_blacklist?('client', post['source']['name'].downcase) + Debug.skipped({source: post['source']['name']}) + next + end end end - unless Settings.options[:force] - if Databases.blacklist["-@#{post['user']['username'].downcase}"] - Debug.skipped({user: post['user']['username']}) - next + unless Settings.global[:force] == true + if Settings.options[:blacklist][:active] == true + if Databases.is_in_blacklist?('user', post['user']['username'].downcase) + Debug.skipped({user: post['user']['username']}) + next + end end end hashtags = extract_hashtags(post) @skip = false - unless Settings.options[:force] - hashtags.each do |h| - if Databases.blacklist[h.downcase] - @skip = true - Debug.skipped({hashtag: h}) - break + unless Settings.global[:force] == true + if Settings.options[:blacklist][:active] == true + hashtags.each do |h| + if Databases.is_in_blacklist?('hashtag', h.downcase) + @skip = true + Debug.skipped({hashtag: h}) + break + end end end end next if @skip mentions= [] post['entities']['mentions'].each { |m| mentions << m['name'] } - unless Settings.options[:force] - mentions.each do |m| - if Databases.blacklist["@#{m.downcase}"] - @skip = true - Debug.skipped({mention: m}) - break + unless Settings.global[:force] == true + if Settings.options[:blacklist][:active] == true + mentions.each do |m| + if Databases.is_in_blacklist?('mention', m.downcase) + @skip = true + Debug.skipped({mention: m}) + break + end end end end next if @skip @@ -172,11 +218,11 @@ is_human = niceranks[post['user']['id'].to_i][:is_human] real_person = niceranks[post['user']['id'].to_i][:real_person] else rank = false is_human = 'unknown' - real_person = nil + real_person = 'unknown' end if post['user'].has_key?('name') name = post['user']['name'].to_s.force_encoding("UTF-8") else @@ -196,10 +242,11 @@ is_human: is_human, real_person: real_person, handle: "@#{post['user']['username']}", type: post['user']['type'], date: parsed_time(post['created_at']), + date_short: parsed_time_short(post['created_at']), you_starred: post['you_starred'], source_name: source, source_link: post['source']['link'], canonical_url: post['canonical_url'], tags: hashtags, @@ -256,21 +303,22 @@ end posts[post['id'].to_i] = values end + posts end def extract_links(post) links = post['entities']['links'].map { |l| l['url'] } unless post['annotations'].nil? || post['annotations'].empty? post['annotations'].each do |ann| if ann['type'] == "net.app.core.oembed" if ann['value']['embeddable_url'] links << ann['value']['embeddable_url'] - elsif ann['value']['url'] && Settings.options[:timeline][:show_channel_oembed] == true + elsif ann['value']['url'] && Settings.options[:channels][:links] == true links << ann['value']['url'] end end end end @@ -289,52 +337,56 @@ }, 'data' => links } filename = "#{Settings.config[:identity][:handle]}_#{origin}_links.json" FileOps.save_links(obj, filename) - puts Status.links_saved(filename) + @status.links_saved(filename) end def extract_hashtags(post) post['entities']['hashtags'].map { |h| h['name'] } end def build_channels(data, options = {}) bucket = [] data = [data] unless data.is_a?(Array) if options[:channels] - puts "Downloading list of channels and their users credentials.\n\nPlease wait, it could take a while if there are many results and users...".color(:cyan) + @thor.say_status :downloading, "list of channels and their users credentials", :yellow + @thor.say_status :info, "it could take a while if there are many results and users", :cyan else - puts "Downloading the channels and recording their users attributes (owners, writers, editors and readers).\n\nThe users are recorded in a database for later filtering and analyzing.\n\nPlease wait, it could take a while the first time if you have many channels.\n\n".color(:cyan) + @thor.say_status :downloading, "the channels and their users attributes (owners, writers, editors and readers)", :yellow + @thor.say_status :info, "users are recorded in a database for later filtering and analyzing", :cyan + @thor.say_status :info, "it could take a while if there are many results", :cyan end chan = Struct.new(:id, :num_messages, :subscribers, :type, :owner, :annotations, :readers, :editors, :writers, :you_subscribed, :unread, :recent_message_id, :recent_message) no_user = {} + @api = API.new data.each do |ch| unless ch['writers']['user_ids'].empty? - @shell.say_status :parsing, "channel #{ch['id']}", :cyan + @thor.say_status :parsing, "channel #{ch['id']}", :cyan usernames = [] ch['writers']['user_ids'].each do |id| next if no_user[id] - db = Databases.users[id] + db = Databases.find_user_by_id(id) if db.nil? - @shell.say_status :downloading, "user #{id}" - resp = API.new.get_user(id) + @thor.say_status :downloading, "user #{id}", :yellow + resp = @api.get_user(id) if resp['meta']['code'] != 200 - @shell.say_status :error, "can't get user #{id}'s data, skipping", :red + @thor.say_status :error, "can't get user #{id}'s data, skipping", :red no_user[id] = true next end the_username = resp['data']['username'] - @shell.say_status :recording, "@#{the_username}", :green + @thor.say_status :recording, "@#{the_username}", :yellow usernames << "@" + the_username Databases.add_to_users_db(id, the_username, resp['data']['name']) else - the_username = "@" + db.keys.first - @shell.say_status :match, "#{the_username} is already in the database", :blue + the_username = "@#{db}" + @thor.say_status :match, "#{the_username} is already in the database", :blue usernames << the_username end end usernames << Settings.config[:identity][:handle] unless usernames.length == 1 && usernames.first == Settings.config[:identity][:handle] @@ -345,37 +397,27 @@ if ch['has_unread'] unread = "This channel has unread message(s)" else unread = "No unread messages" end - @shell.say_status :recording, "channel #{ch['id']}", :green - Databases.add_channel_object(ch) bucket << chan.new(ch['id'], ch['counts']['messages'], ch['counts']['subscribers'], ch['type'], ch['owner'], ch['annotations'], ch['readers'], ch['editors'], writers, ch['you_subscribed'], unread, ch['recent_message_id'], ch['recent_message']) end puts "\e[H\e[2J" bucket end def parsed_time(string) "#{string[0...10]} #{string[11...19]}" end - def at usernames #TODO: consolidate - usernames.map do |user| - if user == 'me' - 'me' - elsif user[0] == '@' - user - else - "@#{user}" - end - end + def parsed_time_short(string) + "#{string[11...19]}" end def get_original_id(post_id, resp) if resp['data']['repost_of'] - puts Status.redirecting + @status.redirecting id = resp['data']['repost_of']['id'] Errors.repost(post_id, id) return id else return post_id @@ -386,11 +428,11 @@ unless channel_id.is_integer? orig = channel_id channel_id = Databases.get_channel_id(orig) if channel_id.nil? Errors.warn("Alias '#{orig}' doesn't exist.") - puts Status.no_alias + @status.no_alias exit end end channel_id end @@ -403,13 +445,13 @@ Databases.get_post_from_index id end def get_real_post_id post_id id = post_id.to_i - if id > 0 && id <= length_of_index + if id <= 200 resp = get_post_from_index(id) - post_id = resp[:id] + post_id = resp['id'] end post_id end def add_arobase username @@ -433,11 +475,11 @@ temp.join end args end - def add_arobases_to_usernames args #TODO: replace all these arobase legacy methods by a unique one + def add_arobases_to_usernames args args.map do |username| if username == 'me' who_am_i else temp = username.chars @@ -445,20 +487,30 @@ temp.join end end end + def at usernames + usernames.map do |user| + if user == 'me' + 'me' + elsif user[0] == '@' + user + else + "@#{user}" + end + end + end + def who_am_i - db = Databases.init(Dir.home + "/ayadn/accounts.db") - active = db['ACTIVE'] - db[active][:handle] + Databases.active_account(Amalgalite::Database.new(Dir.home + "/ayadn/accounts.sqlite"))[2] end def extract_users(resp) users_hash = {} resp['data'].each do |item| - users_hash[item['id']] = [item['username'], item['name'], item['you_follow'], item['follows_you']] + users_hash[item['id']] = [item['username'], item['name'], item['you_follow'], item['follows_you'], item['counts']['posts']] end users_hash end def colorize_text(text, mentions, hashtags) @@ -541,10 +593,14 @@ def all_but_me usernames arr = usernames.select {|user| user != 'me'} at(arr) end + def self.epoch_to_date(epoch) + Time.at(epoch).to_time + end + private def def_str(word, reg_split) splitted = word.split(/#{reg_split}/) if word =~ /#{reg_split}/ if splitted @@ -562,16 +618,12 @@ end end def build_users_array(list) users = list.map do |key, value| - {:username => value[0], :name => value[1], :you_follow => value[2], :follows_you => value[3], :id => key} + {:username => value[0], :name => value[1], :you_follow => value[2], :follows_you => value[3], :id => key, :posts => value[4]} end - if Settings.options[:formats][:list][:reverse] - return users.reverse - else - return users - end + return users end def extract_checkins(post) has_checkins = false checkins = {}