Module: Twterm::RESTClient

Includes:
Publisher
Included in:
Client
Defined in:
lib/twterm/rest_client.rb

Constant Summary collapse

CONSUMER_KEY =
'vLNSVFgXclBJQJRZ7VLMxL9lA'.freeze
CONSUMER_SECRET =
'OFLKzrepRG2p1hq0nUB9j2S9ndFQoNTPheTpmOY0GYw55jGgS5'.freeze

Instance Method Summary collapse

Methods included from Publisher

#publish

Methods included from Utils

check_type

Instance Method Details

#block(*user_ids) ⇒ Object



13
14
15
16
17
18
19
20
21
# File 'lib/twterm/rest_client.rb', line 13

def block(*user_ids)
  send_request do
    rest_client.block(*user_ids)
  end.then do |users|
    users.each do |user|
      Friendship.block(self.user_id, user.id)
    end
  end
end

#create_direct_message(recipient, text) ⇒ Object



23
24
25
26
27
28
29
30
31
32
# File 'lib/twterm/rest_client.rb', line 23

def create_direct_message(recipient, text)
  send_request do
    rest_client.create_direct_message(recipient.id, text)
  end.then do |message|
    msg = DirectMessage.new(message)
    direct_message_manager.add(msg.recipient, msg)
    publish(Event::DirectMessage::Fetched.new)
    publish(Event::Notification.new(:message, 'Your message to @%s has been sent' % msg.recipient.screen_name))
  end
end

#destroy_status(status) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/twterm/rest_client.rb', line 50

def destroy_status(status)
  send_request_without_catch do
    rest_client.destroy_status(status.id)
    publish(Event::Status::Delete.new(status.id))
    publish(Event::Notification.new(:message, 'Your tweet has been deleted'))
  end.catch do |reason|
    case reason
    when Twitter::Error::NotFound, Twitter::Error::Forbidden
      publish(Event::Notification.new(:error, 'You cannot destroy that status'))
    else
      raise reason
    end
  end.catch(&show_error)
end

#direct_message_conversationsObject



34
35
36
# File 'lib/twterm/rest_client.rb', line 34

def direct_message_conversations
  direct_message_manager.conversations
end

#direct_messages_receivedObject



38
39
40
41
42
# File 'lib/twterm/rest_client.rb', line 38

def direct_messages_received
  send_request do
    rest_client.direct_messages(count: 200).map(&DirectMessage.method(:new))
  end
end

#direct_messages_sentObject



44
45
46
47
48
# File 'lib/twterm/rest_client.rb', line 44

def direct_messages_sent
  send_request do
    rest_client.direct_messages_sent(count: 200).map(&DirectMessage.method(:new))
  end
end

#favorite(status) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/twterm/rest_client.rb', line 65

def favorite(status)
  return false unless status.is_a? Status

  send_request do
    rest_client.favorite(status.id)
  end.then do
    status.favorite!
    publish(Event::Notification.new(:message, 'Successfully liked: @%s "%s"' % [
      status.user.screen_name, status.text
    ]))
  end
end

#favorites(user_id = nil) ⇒ Object



78
79
80
81
82
83
84
85
86
# File 'lib/twterm/rest_client.rb', line 78

def favorites(user_id = nil)
  user_id ||= self.user_id

  send_request do
    rest_client.favorites(user_id, count: 200)
  end.then do |tweets|
    tweets.map(&Status.method(:new))
  end
end

#fetch_muted_usersObject



88
89
90
91
92
# File 'lib/twterm/rest_client.rb', line 88

def fetch_muted_users
  send_request do
    @muted_user_ids = rest_client.muted_ids.to_a
  end
end

#follow(*user_ids) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/twterm/rest_client.rb', line 94

def follow(*user_ids)
  send_request do
    rest_client.follow(*user_ids)
  end.then do |users|
    users.each do |user|
      if user.protected?
        Friendship.following_requested(self.user_id, user.id)
      else
        Friendship.follow(self.user_id, user.id)
      end
    end
  end
end

#followers(user_id = nil) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/twterm/rest_client.rb', line 108

def followers(user_id = nil)
  user_id ||= self.user_id

  m = Mutex.new

  send_request do
    rest_client.follower_ids(user_id).each_slice(100) do |user_ids|
      m.synchronize do
        users = rest_client.users(*user_ids).map(& -> u { User.new(u) })
        users.each do |user|
          Friendship.follow(user.id, self.user_id)
        end if user_id == self.user_id
        yield users
      end
    end
  end
end

#friends(user_id = nil) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/twterm/rest_client.rb', line 126

def friends(user_id = nil)
  user_id ||= self.user_id

  m = Mutex.new

  send_request do
    rest_client.friend_ids(user_id).each_slice(100) do |user_ids|
      m.synchronize do
        yield rest_client.users(*user_ids).map(& -> u { User.new(u) })
      end
    end
  end
end

#home_timelineObject



140
141
142
143
144
145
146
147
148
# File 'lib/twterm/rest_client.rb', line 140

def home_timeline
  send_request do
    rest_client.home_timeline(count: 200)
  end.then do |statuses|
    statuses
    .select(&@mute_filter)
    .map(&Status.method(:new))
  end
end

#list(list_id) ⇒ Object



150
151
152
153
154
155
156
# File 'lib/twterm/rest_client.rb', line 150

def list(list_id)
  send_request do
    rest_client.list(list_id)
  end.then do |list|
    List.new(list)
  end
end

#list_timeline(list) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
# File 'lib/twterm/rest_client.rb', line 158

def list_timeline(list)
  fail ArgumentError,
    'argument must be an instance of List class' unless list.is_a? List
  send_request do
    rest_client.list_timeline(list.id, count: 200)
  end.then do |statuses|
    statuses
    .select(&@mute_filter)
    .map(&Status.method(:new))
  end
end

#listsObject



170
171
172
173
174
175
176
# File 'lib/twterm/rest_client.rb', line 170

def lists
  send_request do
    rest_client.lists
  end.then do |lists|
    lists.map { |list| List.new(list) }
  end
end

#lookup_friendshipsObject



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/twterm/rest_client.rb', line 178

def lookup_friendships
  user_ids = User.ids.reject { |id| Friendship.already_looked_up?(id) }
  send_request_without_catch do
    user_ids.each_slice(100) do |chunked_user_ids|
      friendships = rest_client.friendships(*chunked_user_ids)
      friendships.each do |friendship|
        id = friendship.id
        client_id = user_id

        conn = friendship.connections
        conn.include?('blocking') ? Friendship.block(client_id, id) : Friendship.unblock(client_id, id)
        conn.include?('following') ? Friendship.follow(client_id, id) : Friendship.unfollow(client_id, id)
        conn.include?('following_requested') ? Friendship.following_requested(client_id, id) : Friendship.following_not_requested(client_id, id)
        conn.include?('followed_by') ? Friendship.follow(id, client_id) : Friendship.unfollow(id, client_id)
        conn.include?('muting') ? Friendship.mute(client_id, id) : Friendship.unmute(client_id, id)
      end
    end
  end.catch do |e|
    case e
    when Twitter::Error::TooManyRequests
      # do nothing
    else
      raise e
    end
  end.catch(&show_error)
end

#mentionsObject



205
206
207
208
209
210
211
212
213
# File 'lib/twterm/rest_client.rb', line 205

def mentions
  send_request do
    rest_client.mentions(count: 200)
  end.then do |statuses|
    statuses
    .select(&@mute_filter)
    .map(&Status.method(:new))
  end
end

#mute(user_ids) ⇒ Object



215
216
217
218
219
220
221
222
223
# File 'lib/twterm/rest_client.rb', line 215

def mute(user_ids)
  send_request do
    rest_client.mute(*user_ids)
  end.then do |users|
    users.each do |user|
      Friendship.mute(self.user_id, user.id)
    end
  end
end

#post(text, in_reply_to = nil) ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
# File 'lib/twterm/rest_client.rb', line 225

def post(text, in_reply_to = nil)
  send_request do
    if in_reply_to.is_a? Status
      text = "@#{in_reply_to.user.screen_name} #{text}"
      rest_client.update(text, in_reply_to_status_id: in_reply_to.id)
    else
      rest_client.update(text)
    end
    publish(Event::Notification.new(:message, 'Your tweet has been posted'))
  end
end

#rest_clientObject



361
362
363
364
365
366
367
368
# File 'lib/twterm/rest_client.rb', line 361

def rest_client
  @rest_client ||= Twitter::REST::Client.new do |config|
    config.consumer_key        = CONSUMER_KEY
    config.consumer_secret     = CONSUMER_SECRET
    config.access_token        = @access_token
    config.access_token_secret = @access_token_secret
  end
end

#retweet(status) ⇒ Object



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/twterm/rest_client.rb', line 237

def retweet(status)
  fail ArgumentError,
    'argument must be an instance of Status class' unless status.is_a? Status

  send_request_without_catch do
    rest_client.retweet!(status.id)
  end.then do
    status.retweet!
    publish(Event::Notification.new(:message, 'Successfully retweeted: @%s "%s"' % [
      status.user.screen_name, status.text
    ]))
  end.catch do |reason|
    message =
      case reason
      when Twitter::Error::AlreadyRetweeted
        'The status is already retweeted'
      when Twitter::Error::NotFound
        'The status is not found'
      when Twitter::Error::Forbidden
        if status.user.id == user_id  # when the status is mine
          'You cannot retweet your own status'
        else  # when the status is not mine
          'The status is protected'
        end
      else
        raise e
      end
    publish(Event::Notification.new(:error, "Retweet attempt failed: #{message}"))
  end.catch(&show_error)
end

#saved_searchObject



268
269
270
271
272
# File 'lib/twterm/rest_client.rb', line 268

def saved_search
  send_request do
    rest_client.saved_searches
  end
end

#search(query) ⇒ Object



274
275
276
277
278
279
280
281
282
# File 'lib/twterm/rest_client.rb', line 274

def search(query)
  send_request do
    rest_client.search(query, count: 100).attrs[:statuses]
  end.then do |statuses|
    statuses
    .map(&Twitter::Tweet.method(:new))
    .map(&Status.method(:new))
  end
end

#send_request(&block) ⇒ Object



370
371
372
# File 'lib/twterm/rest_client.rb', line 370

def send_request(&block)
  send_request_without_catch(&block).catch(&show_error)
end

#send_request_without_catch(&block) ⇒ Object



374
375
376
377
378
379
380
381
382
# File 'lib/twterm/rest_client.rb', line 374

def send_request_without_catch(&block)
  Promise.new do |resolve, reject|
    begin
      resolve.(block.call)
    rescue Twitter::Error => reason
      reject.(reason)
    end
  end
end

#show_status(status_id) ⇒ Object



284
285
286
287
288
289
290
# File 'lib/twterm/rest_client.rb', line 284

def show_status(status_id)
  send_request do
    rest_client.status(status_id)
  end.then do |status|
    Status.new(status)
  end
end

#show_user(query) ⇒ Object



292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/twterm/rest_client.rb', line 292

def show_user(query)
  send_request_without_catch do
    rest_client.user(query)
  end.catch do |reason|
    case reason
    when Twitter::Error::NotFound
      nil
    else
      raise reason
    end
  end.catch(&show_error).then do |user|
    user.nil? ? nil : User.new(user)
  end
end

#unblock(*user_ids) ⇒ Object



307
308
309
310
311
312
313
314
315
# File 'lib/twterm/rest_client.rb', line 307

def unblock(*user_ids)
  send_request do
    rest_client.unblock(*user_ids)
  end.then do |users|
    users.each do |user|
      Friendship.unblock(self.user_id, user.id)
    end
  end
end

#unfavorite(status) ⇒ Object



317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/twterm/rest_client.rb', line 317

def unfavorite(status)
  fail ArgumentError,
    'argument must be an instance of Status class' unless status.is_a? Status

  send_request do
    rest_client.unfavorite(status.id)
  end.then do
    status.unfavorite!
    publish(Event::Notification.new(:message, 'Successfully unliked: @%s "%s"' % [
      status.user.screen_name, status.text
    ]))
  end
end

#unfollow(*user_ids) ⇒ Object



331
332
333
334
335
336
337
338
339
# File 'lib/twterm/rest_client.rb', line 331

def unfollow(*user_ids)
  send_request do
    rest_client.unfollow(*user_ids)
  end.then do |users|
    users.each do |user|
      Friendship.unfollow(self.user_id, user.id)
    end
  end
end

#unmute(user_ids) ⇒ Object



341
342
343
344
345
346
347
348
349
# File 'lib/twterm/rest_client.rb', line 341

def unmute(user_ids)
  send_request do
    rest_client.unmute(*user_ids)
  end.then do |users|
    users.each do |user|
      Friendship.unmute(self.user_id, user.id)
    end
  end
end

#user_timeline(user_id) ⇒ Object



351
352
353
354
355
356
357
358
359
# File 'lib/twterm/rest_client.rb', line 351

def user_timeline(user_id)
  send_request do
    rest_client.user_timeline(user_id, count: 200)
  end.then do |statuses|
    statuses
    .select(&@mute_filter)
    .map(&Status.method(:new))
  end
end