module ExTwitter::NewApi
Public Instance Methods
_count_users_with_two_sided_threshold(users, options)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 179 def _count_users_with_two_sided_threshold(users, options) min = options.has_key?(:min) ? options[:min] : 0 max = options.has_key?(:max) ? options[:max] : 1000 users.each_with_object(Hash.new(0)) { |u, memo| memo[u.id] += 1 }. select { |_k, v| min <= v && v <= max }. sort_by { |_, v| -v }.to_h end
_extract_favorite_users(favs, options = {})
click to toggle source
# File lib/ex_twitter/new_api.rb, line 187 def _extract_favorite_users(favs, options = {}) counted_value = _count_users_with_two_sided_threshold(favs.map { |t| t.user }, options) counted_value.map do |uid, cnt| fav = favs.find { |f| f.user.id.to_i == uid.to_i } Array.new(cnt, fav.user) end.flatten end
_extract_inactive_users(users, options = {})
click to toggle source
# File lib/ex_twitter/new_api.rb, line 220 def _extract_inactive_users(users, options = {}) authorized = options.delete(:authorized) two_weeks_ago = 2.weeks.ago.to_i users.select do |u| if authorized (Time.parse(u.status.created_at).to_i < two_weeks_ago) rescue false else false end end end
_extract_screen_names(tweets)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 113 def _extract_screen_names(tweets) tweets.map do |t| $1 if t.text =~ /^(?:\.)?@(\w+)( |\W)/ # include statuses starts with . end.compact end
_extract_uids(tweets)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 148 def _extract_uids(tweets) tweets.map do |t| t.user.id.to_i if t.text =~ /^(?:\.)?@(\w+)( |\W)/ # include statuses starts with . end.compact end
_extract_users(tweets, uids)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 154 def _extract_users(tweets, uids) uids.map { |uid| tweets.find { |t| t.user.id.to_i == uid.to_i } }.map { |t| t.user }.compact end
_fetch_parallelly(signatures)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 15 def _fetch_parallelly(signatures) # [{method: :friends, args: ['ts_3156', ...], {...}] result = Array.new(signatures.size) Parallel.each_with_index(signatures, in_threads: result.size) do |signature, i| result[i] = send(signature[:method], *signature[:args]) end result end
close_friends(*args)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 235 def close_friends(*args) options = {uniq: false}.merge(args.extract_options!) min_max = { min: options.has_key?(:min) ? options.delete(:min) : 0, max: options.has_key?(:max) ? options.delete(:max) : 1000 } _replying, _replied, _favoriting = if args.empty? [replying(options), replied(options), favoriting(options)] elsif uid_or_screen_name?(args[0]) [replying(args[0], options), replied(args[0], options), favoriting(args[0], options)] elsif (m_names = %i(replying replied favoriting)).all? { |m_name| args[0].respond_to?(m_name) } m_names.map { |mn| args[0].send(mn) } else raise end _users = _replying + _replied + _favoriting return [] if _users.empty? scores = _count_users_with_two_sided_threshold(_users, min_max) replying_scores = _count_users_with_two_sided_threshold(_replying, min_max) replied_scores = _count_users_with_two_sided_threshold(_replied, min_max) favoriting_scores = _count_users_with_two_sided_threshold(_favoriting, min_max) scores.keys.map { |uid| _users.find { |u| u.id.to_i == uid.to_i } }. map do |u| u[:score] = scores[u.id] u[:replying_score] = replying_scores[u.id] u[:replied_score] = replied_scores[u.id] u[:favoriting_score] = favoriting_scores[u.id] u end end
clusters_assigned_to()
click to toggle source
# File lib/ex_twitter/new_api.rb, line 327 def clusters_assigned_to raise NotImplementedError.new end
clusters_belong_to(text)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 299 def clusters_belong_to(text) return [] if text.blank? exclude_words = JSON.parse(File.read(Rails.configuration.x.constants['cluster_bad_words_path'])) special_words = JSON.parse(File.read(Rails.configuration.x.constants['cluster_good_words_path'])) # クラスタ用の単語の出現回数を記録 cluster_word_counter = special_words.map { |sw| [sw, text.scan(sw)] } .delete_if { |item| item[1].empty? } .each_with_object(Hash.new(1)) { |item, memo| memo[item[0]] = item[1].size } # 同一文字種の繰り返しを見付ける。漢字の繰り返し、ひらがなの繰り返し、カタカナの繰り返し、など text.scan(/[一-龠〆ヵヶ々]+|[ぁ-んー~]+|[ァ-ヴー~]+|[a-zA-Z0-9]+|[、。!!??]+/). # 複数回繰り返される文字を除去 map { |w| w.remove /[?!?!。、w]|(ー{2,})/ }. # 文字数の少なすぎる単語、ひらがなだけの単語、除外単語を除去する delete_if { |w| w.length <= 1 || (w.length <= 2 && w =~ /^[ぁ-んー~]+$/) || exclude_words.include?(w) }. # 出現回数を記録 each { |w| cluster_word_counter[w] += 1 } # 複数個以上見付かった単語のみを残し、出現頻度順にソート cluster_word_counter.select { |_, v| v > 3 }.sort_by { |_, v| -v }.to_h end
common_followers(me, you)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 83 def common_followers(me, you) if uid_or_screen_name?(me) && uid_or_screen_name?(you) followers_parallelly(me).to_a & followers_parallelly(you).to_a elsif me.respond_to?(:followers) && you.respond_to?(:followers) me.followers.to_a & you.followers.to_a else raise end end
common_friends(me, you)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 73 def common_friends(me, you) if uid_or_screen_name?(me) && uid_or_screen_name?(you) friends_parallelly(me).to_a & friends_parallelly(you).to_a elsif me.respond_to?(:friends) && you.respond_to?(:friends) me.friends.to_a & you.friends.to_a else raise end end
favorited_by(*args)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 232 def favorited_by(*args) end
favoriting(*args)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 195 def favoriting(*args) options = args.extract_options! favs = if args.empty? favorites(options) elsif uid_or_screen_name?(args[0]) favorites(args[0], options) elsif args[0].kind_of?(Array) && args[0].all? { |t| t.respond_to?(:text) } args[0] else raise end result = _extract_favorite_users(favs, options) if options.has_key?(:uniq) && !options[:uniq] result else result.uniq { |r| r.id } end rescue => e logger.warn "#{__method__} #{user.inspect} #{e.class} #{e.message}" raise e end
followers_parallelly(*args)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 9 def followers_parallelly(*args) options = {super_operation: __method__}.merge(args.extract_options!) _follower_ids = follower_ids(*(args + [options])) users(_follower_ids.map { |id| id.to_i }, options) end
friends_and_followers(*args)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 25 def friends_and_followers(*args) _fetch_parallelly( [ {method: :friends_parallelly, args: args}, {method: :followers_parallelly, args: args}]) end
friends_followers_and_statuses(*args)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 32 def friends_followers_and_statuses(*args) _fetch_parallelly( [ {method: :friends_parallelly, args: args}, {method: :followers_parallelly, args: args}, {method: :user_timeline, args: args}]) end
friends_parallelly(*args)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 3 def friends_parallelly(*args) options = {super_operation: __method__}.merge(args.extract_options!) _friend_ids = friend_ids(*(args + [options])) users(_friend_ids.map { |id| id.to_i }, options) end
inactive_followers(user = nil)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 285 def inactive_followers(user = nil) if user.blank? _extract_inactive_users(followers_parallelly, authorized: true) elsif uid_or_screen_name?(user) authorized = authenticating_user?(user) || authorized_user?(user) _extract_inactive_users(followers_parallelly(user), authorized: authorized) elsif user.respond_to?(:followers) authorized = authenticating_user?(user.uid.to_i) || authorized_user?(user.uid.to_i) _extract_inactive_users(user.followers, authorized: authorized) else raise end end
inactive_friends(user = nil)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 271 def inactive_friends(user = nil) if user.blank? _extract_inactive_users(friends_parallelly, authorized: true) elsif uid_or_screen_name?(user) authorized = authenticating_user?(user) || authorized_user?(user) _extract_inactive_users(friends_parallelly(user), authorized: authorized) elsif user.respond_to?(:friends) authorized = authenticating_user?(user.uid.to_i) || authorized_user?(user.uid.to_i) _extract_inactive_users(user.friends, authorized: authorized) else raise end end
mutual_friends(me)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 62 def mutual_friends(me) if uid_or_screen_name?(me) # TODO use friends_and_followers friends_parallelly(me).to_a & followers_parallelly(me).to_a elsif me.respond_to?(:friends) && me.respond_to?(:followers) me.friends.to_a & me.followers.to_a else raise end end
one_sided_followers(me)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 51 def one_sided_followers(me) if uid_or_screen_name?(me) # TODO use friends_and_followers followers_parallelly(me).to_a - friends_parallelly(me).to_a elsif me.respond_to?(:friends) && me.respond_to?(:followers) me.followers.to_a - me.friends.to_a else raise end end
one_sided_following(me)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 40 def one_sided_following(me) if uid_or_screen_name?(me) # TODO use friends_and_followers friends_parallelly(me).to_a - followers_parallelly(me).to_a elsif me.respond_to?(:friends) && me.respond_to?(:followers) me.friends.to_a - me.followers.to_a else raise end end
removed(pre_me, cur_me)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 103 def removed(pre_me, cur_me) if uid_or_screen_name?(pre_me) && uid_or_screen_name?(cur_me) followers_parallelly(pre_me).to_a - followers_parallelly(cur_me).to_a elsif pre_me.respond_to?(:followers) && cur_me.respond_to?(:followers) pre_me.followers.to_a - cur_me.followers.to_a else raise end end
removing(pre_me, cur_me)
click to toggle source
# File lib/ex_twitter/new_api.rb, line 93 def removing(pre_me, cur_me) if uid_or_screen_name?(pre_me) && uid_or_screen_name?(cur_me) friends_parallelly(pre_me).to_a - friends_parallelly(cur_me).to_a elsif pre_me.respond_to?(:friends) && cur_me.respond_to?(:friends) pre_me.friends.to_a - cur_me.friends.to_a else raise end end
replied(*args)
click to toggle source
users which specified user is replied when user is login you had better to call mentions_timeline
# File lib/ex_twitter/new_api.rb, line 160 def replied(*args) options = args.extract_options! result = if args.empty? || (uid_or_screen_name?(args[0]) && authenticating_user?(args[0])) mentions_timeline.map { |m| m.user } else searched_result = search('@' + user(args[0]).screen_name, options) uids = _extract_uids(searched_result) _extract_users(searched_result, uids) end if options.has_key?(:uniq) && !options[:uniq] result else result.uniq { |r| r.id } end end
replying(*args)
click to toggle source
users which specified user is replying in_reply_to_user_id and in_reply_to_status_id is not used because of distinguishing mentions from replies
# File lib/ex_twitter/new_api.rb, line 121 def replying(*args) options = args.extract_options! tweets = if args.empty? user_timeline(options) elsif uid_or_screen_name?(args[0]) user_timeline(args[0], options) elsif args[0].kind_of?(Array) && args[0].all? { |t| t.respond_to?(:text) } args[0] else raise end screen_names = _extract_screen_names(tweets) result = users(screen_names, {super_operation: __method__}.merge(options)) if options.has_key?(:uniq) && !options[:uniq] screen_names.map { |sn| result.find { |r| r.screen_name == sn } }.compact else result.uniq { |r| r.id } end rescue Twitter::Error::NotFound => e e.message == 'No user matches for specified terms.' ? [] : (raise e) rescue => e logger.warn "#{__method__} #{args.inspect} #{e.class} #{e.message}" raise e end