aboutsummaryrefslogtreecommitdiffstats
path: root/app/models/account.rb
blob: d4486b94bc61fa4a1a42585bd0654bcc85ecbbff (plain)
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
class Account < ActiveRecord::Base
  enum status: { active: 0, inactive: 1, revoked: 2 }

  belongs_to :user
  scope :for_node, ->(block_number) { active.where("id % ? = ?", Settings.collector.nodes_count, block_number) }

  # Returns whether tweet notification is enabled for this user.
  def notification_enabled?; notification_enabled end

  # Changes the `status` value to :inactive.
  def deactivate!; self.inactive! end

  class << self
    # Registers a new account or updates an existing account.
    # @param [Hash] hash data
    # @return [Account] The target account object.
    def register(hash)
      account = where(user_id: hash[:user_id]).first_or_initialize
      account.oauth_token = hash[:oauth_token]
      account.oauth_token_secret = hash[:oauth_token_secret]
      account.status = :active
      account.save! if account.changed?
      account
    end

    # Returns a random active account.
    # @return [Account] A random active account.
    def random
      active.order("RAND()").first
    end
  end

  # Verifies the OAuth token pair with calling /1.1/account/verify_credentials.json.
  # If the token was revoked, changes the `status` to :revoked.
  def verify_token!
    client.user
  rescue
    self.revoked!
  end

  # Returns Twitter Gem's Client instance.
  # @return [Twitter::REST::Client] An instance of Twitter::REST::Client.
  def client
    @_client ||= Twitter::REST::Client.new(consumer_key: Settings.consumer.key,
                                           consumer_secret: Settings.consumer.secret,
                                           access_token: oauth_token,
                                           access_token_secret: oauth_token_secret)
  end

  # Returns whether following the target user or not.
  # @param [User, Integer] target_id Target user.
  # @return [Boolean] whether following the target or not.
  def following?(target_id)
    target_id = target_id.id if target_id.is_a?(User)
    friends.member? target_id
  end

  # Returns the array of friends.
  # @return [Array<Integer>]
  def friends
    @_friends ||=
    Rails.cache.fetch("accounts/#{self.id}/friends", expires_in: Settings.cache.friends) do
      Set.new client.friend_ids
    end
  end

  # Returns the worker id collecting tweets for this account.
  # @return [Integer]
  def worker_number
    id % Settings.collector.nodes_count
  end
end