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
|
require "ostruct"
class User < ActiveRecord::Base
has_many :tweets
has_many :favorites
has_many :retweets
has_one :account
scope :suggest_screen_name, ->(str) { where("screen_name LIKE ?", "#{str.gsub(/(_|%)/) {|x| "\\" + x }}%").order(screen_name: :asc) }
class << self
def find(*args)
hash = args.first
return super(*args) unless hash.is_a?(Hash)
key, value = hash.delete_if {|k, v| v.nil? }.first
key && where(key => value).order(updated_at: :desc).first || raise(ActiveRecord::RecordNotFound, "Couldn't find User with #{key}=#{value}")
end
def transform_from_json_into_hash(json)
{
id: json[:id],
screen_name: json[:screen_name],
name: json[:name],
profile_image_url: json[:profile_image_url_https] || json[:profile_image_url],
protected: json[:protected]
}
end
def build_from_json(json)
self.new(transform_from_json_into_hash(json))
end
def create_or_update_from_json(json)
import([build_from_json(json)], on_duplicate_key_update: [:screen_name, :name, :profile_image_url, :protected])
end
def create_or_update_bulk_from_json(array)
return if array.empty?
objects = array.map {|json| transform_from_json_into_hash(json) }
keys = objects.first.keys
self.import(keys, objects.map(&:values),
on_duplicate_key_update: [:screen_name, :name, :profile_image_url, :protected],
validate: false)
end
end
def require_registered!
registered? || raise(Aclog::Exceptions::UserNotRegistered, self)
end
def twitter_url
"https://twitter.com/#{self.screen_name}"
end
def profile_image_url(size = nil)
if size == :original
suffix = ""
else
suffix = "_#{size || :normal}"
end
attributes["profile_image_url"].sub(/_normal((?:\.(?:png|jpeg|gif))?)/, "#{suffix}\\1")
end
def protected?
protected
end
def registered?
!!account && account.active?
end
def permitted_to_see?(user)
!user.protected? || user.id == self.id || (self.registered? && account.following?(user))
end
def stats
Rails.cache.fetch("users/#{self.id}/stats", expires_in: Settings.cache.stats) do
plucked = self.tweets.select("COUNT(*) AS count, SUM(reactions_count) AS sum").first.attributes
ret = OpenStruct.new
ret.updated_at = Time.now
ret.tweets_count = plucked["count"]
ret.reactions_count = plucked["sum"]
ret.registered = self.registered?
if self.registered?
ret.since_join = (DateTime.now.utc - self.account.created_at.to_datetime).to_i
end
ret
end
end
def count_discovered_by
[Favorite, Retweet].map { |klass|
klass
.joins("INNER JOIN (#{self.tweets.reacted.order_by_id.limit(500).to_sql}) tweets ON tweets.id = #{klass.table_name}.tweet_id")
.group("`#{klass.table_name}`.`user_id`")
.count("`#{klass.table_name}`.`user_id`")
}.inject { |m, s|
m.merge(s) { |key, first, second| first.to_i + second.to_i }
}.sort_by { |user_id, count| -count }
end
def count_discovered_users
[Favorite, Retweet].map { |klass|
Tweet
.joins("INNER JOIN (#{self.__send__(klass.table_name.to_sym).order(id: :desc).limit(500).to_sql}) m ON m.tweet_id = tweets.id")
.group("tweets.user_id")
.count("tweets.user_id")
}.inject { |m, s|
m.merge(s) { |key, first, second| first.to_i + second.to_i }
}.sort_by { |user_id, count| -count }
end
end
|