1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
require "ostruct"
class User < ActiveRecord::Base
has_many :tweets, dependent: :delete_all
has_many :favorites, dependent: :delete_all
has_many :retweets, dependent: :delete_all
def twitter_url
"https://twitter.com/#{self.screen_name}"
end
def self.get(id, screen_name)
if id
find(id) rescue raise Aclog::Exceptions::UserNotFound
elsif screen_name
where(screen_name: screen_name).order(updated_at: :desc).first or raise Aclog::Exceptions::UserNotFound
else
Aclog::Exceptions::UserNotFound
end
end
def self.from_receiver(msg)
user = where(id: msg["id"]).first_or_initialize
att = user.attributes.dup
user.screen_name = msg["screen_name"]
user.name = msg["name"]
user.profile_image_url = msg["profile_image_url"]
user.protected = msg["protected"]
if att["screen_name"] == user.screen_name &&
att["name"] == user.name &&
att["profile_image_url"][-44..-1] == user.profile_image_url[-44..-1] &&
att["protected"] == user.protected?
logger.debug("User not changed: #{user.id}")
else
user.save!
logger.debug("User saved: #{user.id}")
end
return user
rescue
logger.error("Unknown error while inserting user: #{$!}/#{$@}")
end
def self.from_user_object(user_object)
from_receiver("id" => user_object.id,
"screen_name" => user_object.screen_name,
"name" => user_object.name,
"profile_image_url" => user_object.profile_image_url_https,
"protected" => user_object.protected)
end
def protected?
protected
end
def registered?
!!account
end
def account
Account.where(user_id: id).first
end
def profile_image_url_original
profile_image_url.sub(/_normal((?:\.(?:png|jpeg|gif))?)/, "\\1")
end
def stats
raise Aclog::Exceptions::UserNotRegistered.new(self) unless registered? && account.active?
Rails.cache.fetch("stats/#{self.id}", expires_in: 3.hours) do
reactions_count = tweets.sum(:reactions_count)
ret = OpenStruct.new
ret.updated_at = Time.now
ret.since_join = (DateTime.now.utc - self.account.created_at.to_datetime).to_i
ret.favorites_count = self.favorites.count
ret.retweets_count = self.retweets.count
ret.tweets_count = self.tweets.count
ret.reactions_count = reactions_count
ret.average_reactions_count = reactions_count.to_f / ret.tweets_count
ret
end
end
def count_discovered_by
tws = Tweet.arel_table
f = -> model do
klas = model.arel_table
m = tws.project(tws[:id]).where(tws[:user_id].eq(self.id)).order(tws[:id].desc).take(100).as("m")
query = klas.project(klas[:user_id], klas[:user_id].count).join(m).on(klas[:tweet_id].eq(m[:id])).group(klas[:user_id])
ActiveRecord::Base.connection.exec_query(query.to_sql).rows
end
merge_count_user(f.call(Favorite), f.call(Retweet))
end
def count_discovered_users
tws = Tweet.arel_table
f = -> model do
klas = model.arel_table
m = klas.project(klas[:tweet_id]).where(klas[:user_id].eq(self.id)).order(klas[:id].desc).take(500).as("m")
query = tws.project(tws[:user_id], tws[:user_id].count).join(m).on(tws[:id].eq(m[:tweet_id])).group(tws[:user_id])
ActiveRecord::Base.connection.exec_query(query.to_sql).rows
end
merge_count_user(f.call(Favorite), f.call(Retweet))
end
private
def merge_count_user(*args)
ret = {}
args.each_with_index do |o, i|
o.each do |user_id, count|
ret[user_id] ||= Array.new(args.size, 0)
ret[user_id][i] = count
end
end
ret.map(&:flatten).sort_by {|user_id, favorites_count, retweets_count| -(favorites_count + retweets_count) }
end
end
|