api.py 22.4 KB
Newer Older
1
# Tweepy
2
3
# Copyright 2009-2010 Joshua Roesslein
# See LICENSE for details.
4

5
6
7
import os
import mimetypes

Josh Roesslein's avatar
Josh Roesslein committed
8
9
from tweepy.binder import bind_api
from tweepy.error import TweepError
10
from tweepy.parsers import ModelParser
11
from tweepy.utils import list_to_csv
12

Josh Roesslein's avatar
Josh Roesslein committed
13

14
class API(object):
Josh Roesslein's avatar
Josh Roesslein committed
15
16
    """Twitter API"""

17
18
    def __init__(self, auth_handler=None,
            host='api.twitter.com', search_host='search.twitter.com',
19
             cache=None, secure=True, api_root='/1.1', search_root='',
20
            retry_count=0, retry_delay=0, retry_errors=None, timeout=60,
Mike's avatar
Mike committed
21
            parser=None, compression=False):
Josh Roesslein's avatar
Josh Roesslein committed
22
        self.auth = auth_handler
Josh Roesslein's avatar
Josh Roesslein committed
23
        self.host = host
24
        self.search_host = search_host
Josh Roesslein's avatar
Josh Roesslein committed
25
        self.api_root = api_root
26
        self.search_root = search_root
Josh Roesslein's avatar
Josh Roesslein committed
27
28
        self.cache = cache
        self.secure = secure
Mike's avatar
Mike committed
29
        self.compression = compression
30
31
        self.retry_count = retry_count
        self.retry_delay = retry_delay
32
        self.retry_errors = retry_errors
33
        self.timeout = timeout
34
        self.parser = parser or ModelParser()
Josh Roesslein's avatar
Josh Roesslein committed
35

Ferenc Szalai's avatar
Ferenc Szalai committed
36
    """ statuses/home_timeline """
Josh Roesslein's avatar
Josh Roesslein committed
37
38
    home_timeline = bind_api(
        path = '/statuses/home_timeline.json',
39
        payload_type = 'status', payload_list = True,
Josh Roesslein's avatar
Josh Roesslein committed
40
41
42
43
        allowed_param = ['since_id', 'max_id', 'count', 'page'],
        require_auth = True
    )

44
    """ statuses/user_timeline """
Josh Roesslein's avatar
Josh Roesslein committed
45
46
    user_timeline = bind_api(
        path = '/statuses/user_timeline.json',
47
        payload_type = 'status', payload_list = True,
Josh Roesslein's avatar
Josh Roesslein committed
48
        allowed_param = ['id', 'user_id', 'screen_name', 'since_id',
49
                          'max_id', 'count', 'page', 'include_rts']
Josh Roesslein's avatar
Josh Roesslein committed
50
51
    )

52
    """ statuses/mentions """
53
54
    mentions_timeline = bind_api(
        path = '/statuses/mentions_timeline.json',
55
        payload_type = 'status', payload_list = True,
56
        allowed_param = ['since_id', 'max_id', 'count'],
Josh Roesslein's avatar
Josh Roesslein committed
57
58
59
        require_auth = True
    )

60
61
62
63
64
65
66
    """/statuses/:id/retweeted_by.format"""
    retweeted_by = bind_api(
        path = '/statuses/{id}/retweeted_by.json',
        payload_type = 'status', payload_list = True,
        allowed_param = ['id', 'count', 'page'],
        require_auth = True
    )
67

Aaron Swartz's avatar
Aaron Swartz committed
68
69
70
71
72
73
    """/related_results/show/:id.format"""
    related_results = bind_api(
        path = '/related_results/show/{id}.json',
        payload_type = 'relation', payload_list = True,
        allowed_param = ['id'],
        require_auth = False
74
    )
75
76
77
78
79
80
81
82
83

    """/statuses/:id/retweeted_by/ids.format"""
    retweeted_by_ids = bind_api(
        path = '/statuses/{id}/retweeted_by/ids.json',
        payload_type = 'ids',
        allowed_param = ['id', 'count', 'page'],
        require_auth = True
    )

84
    """ statuses/retweets_of_me """
Josh Roesslein's avatar
Josh Roesslein committed
85
86
    retweets_of_me = bind_api(
        path = '/statuses/retweets_of_me.json',
87
        payload_type = 'status', payload_list = True,
Josh Roesslein's avatar
Josh Roesslein committed
88
89
90
91
        allowed_param = ['since_id', 'max_id', 'count', 'page'],
        require_auth = True
    )

92
    """ statuses/show """
Josh Roesslein's avatar
Josh Roesslein committed
93
94
    get_status = bind_api(
        path = '/statuses/show.json',
95
        payload_type = 'status',
Josh Roesslein's avatar
Josh Roesslein committed
96
97
98
        allowed_param = ['id']
    )

Ferenc Szalai's avatar
Ferenc Szalai committed
99
    """ statuses/update """
Josh Roesslein's avatar
Josh Roesslein committed
100
101
102
    update_status = bind_api(
        path = '/statuses/update.json',
        method = 'POST',
103
        payload_type = 'status',
104
        allowed_param = ['status', 'in_reply_to_status_id', 'lat', 'long', 'source', 'place_id'],
Josh Roesslein's avatar
Josh Roesslein committed
105
106
107
        require_auth = True
    )

108
    """ statuses/destroy """
Josh Roesslein's avatar
Josh Roesslein committed
109
    destroy_status = bind_api(
Joshua Roesslein's avatar
Joshua Roesslein committed
110
111
        path = '/statuses/destroy/{id}.json',
        method = 'POST',
112
        payload_type = 'status',
Josh Roesslein's avatar
Josh Roesslein committed
113
114
115
116
        allowed_param = ['id'],
        require_auth = True
    )

Ferenc Szalai's avatar
Ferenc Szalai committed
117
    """ statuses/retweet """
118
119
120
    retweet = bind_api(
        path = '/statuses/retweet/{id}.json',
        method = 'POST',
121
        payload_type = 'status',
122
123
124
        allowed_param = ['id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
125

Ferenc Szalai's avatar
Ferenc Szalai committed
126
    """ statuses/retweets """
127
128
    retweets = bind_api(
        path = '/statuses/retweets/{id}.json',
129
        payload_type = 'status', payload_list = True,
130
131
132
        allowed_param = ['id', 'count'],
        require_auth = True
    )
133

134
    """ users/show """
Josh Roesslein's avatar
Josh Roesslein committed
135
136
    get_user = bind_api(
        path = '/users/show.json',
137
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
138
139
140
        allowed_param = ['id', 'user_id', 'screen_name']
    )

Miriam Sexton's avatar
Miriam Sexton committed
141
142
    ''' statuses/oembed '''
    get_oembed = bind_api(
Miriam Sexton's avatar
Miriam Sexton committed
143
        path = '/statuses/oembed.json',
Miriam Sexton's avatar
Miriam Sexton committed
144
145
146
147
        payload_type = 'json',
        allowed_param = ['id', 'url', 'maxwidth', 'hide_media', 'omit_script', 'align', 'related', 'lang']
    )

148
149
150
151
152
153
154
155
156
157
    """ Perform bulk look up of users from user ID or screenname """
    def lookup_users(self, user_ids=None, screen_names=None):
        return self._lookup_users(list_to_csv(user_ids), list_to_csv(screen_names))

    _lookup_users = bind_api(
        path = '/users/lookup.json',
        payload_type = 'user', payload_list = True,
        allowed_param = ['user_id', 'screen_name'],
    )

158
    """ Get the authenticated user """
Josh Roesslein's avatar
Josh Roesslein committed
159
    def me(self):
Josh Roesslein's avatar
Josh Roesslein committed
160
        return self.get_user(screen_name=self.auth.get_username())
Josh Roesslein's avatar
Josh Roesslein committed
161

162
163
164
    """ users/search """
    search_users = bind_api(
        path = '/users/search.json',
165
        payload_type = 'user', payload_list = True,
166
167
168
169
        require_auth = True,
        allowed_param = ['q', 'per_page', 'page']
    )

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    """ users/suggestions/:slug """
    suggested_users = bind_api(
        path = '/users/suggestions/{slug}.json',
        payload_type = 'user', payload_list = True,
        require_auth = True,
        allowed_param = ['slug', 'lang']
    )

    """ users/suggestions """
    suggested_categories = bind_api(
        path = '/users/suggestions.json',
        payload_type = 'category', payload_list = True,
        allowed_param = ['lang'],
        require_auth = True
    )

    """ users/suggestions/:slug/members """
    suggested_users_tweets = bind_api(
        path = '/users/suggestions/{slug}/members.json',
        payload_type = 'status', payload_list = True,
        allowed_param = ['slug'],
        require_auth = True
    )

194
    """ direct_messages """
Josh Roesslein's avatar
Josh Roesslein committed
195
196
    direct_messages = bind_api(
        path = '/direct_messages.json',
197
        payload_type = 'direct_message', payload_list = True,
Josh Roesslein's avatar
Josh Roesslein committed
198
199
200
201
        allowed_param = ['since_id', 'max_id', 'count', 'page'],
        require_auth = True
    )

202
203
204
205
206
207
208
209
    """ direct_messages/show """
    get_direct_message = bind_api(
        path = '/direct_messages/show/{id}.json',
        payload_type = 'direct_message',
        allowed_param = ['id'],
        require_auth = True
    )

210
    """ direct_messages/sent """
Josh Roesslein's avatar
Josh Roesslein committed
211
212
    sent_direct_messages = bind_api(
        path = '/direct_messages/sent.json',
213
        payload_type = 'direct_message', payload_list = True,
Josh Roesslein's avatar
Josh Roesslein committed
214
215
216
        allowed_param = ['since_id', 'max_id', 'count', 'page'],
        require_auth = True
    )
217

218
    """ direct_messages/new """
Josh Roesslein's avatar
Josh Roesslein committed
219
220
    send_direct_message = bind_api(
        path = '/direct_messages/new.json',
221
        method = 'POST',
222
        payload_type = 'direct_message',
223
        allowed_param = ['user', 'screen_name', 'user_id', 'text'],
224
        require_auth = True
Josh Roesslein's avatar
Josh Roesslein committed
225
    )
226

227
    """ direct_messages/destroy """
Josh Roesslein's avatar
Josh Roesslein committed
228
229
230
    destroy_direct_message = bind_api(
        path = '/direct_messages/destroy.json',
        method = 'DELETE',
231
        payload_type = 'direct_message',
Josh Roesslein's avatar
Josh Roesslein committed
232
233
234
235
        allowed_param = ['id'],
        require_auth = True
    )

236
    """ friendships/create """
Josh Roesslein's avatar
Josh Roesslein committed
237
238
    create_friendship = bind_api(
        path = '/friendships/create.json',
239
        method = 'POST',
240
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
241
        allowed_param = ['id', 'user_id', 'screen_name', 'follow'],
242
        require_auth = True
Josh Roesslein's avatar
Josh Roesslein committed
243
244
    )

245
    """ friendships/destroy """
Josh Roesslein's avatar
Josh Roesslein committed
246
247
248
    destroy_friendship = bind_api(
        path = '/friendships/destroy.json',
        method = 'DELETE',
249
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
250
251
252
253
        allowed_param = ['id', 'user_id', 'screen_name'],
        require_auth = True
    )

254
    """ friendships/show """
Josh Roesslein's avatar
Josh Roesslein committed
255
256
    show_friendship = bind_api(
        path = '/friendships/show.json',
257
        payload_type = 'friendship',
Josh Roesslein's avatar
Josh Roesslein committed
258
259
260
261
        allowed_param = ['source_id', 'source_screen_name',
                          'target_id', 'target_screen_name']
    )

262
263
    """ Perform bulk look up of friendships from user ID or screenname """
    def lookup_friendships(self, user_ids=None, screen_names=None):
Santosh Kumar's avatar
Santosh Kumar committed
264
        return self._lookup_friendships(list_to_csv(user_ids), list_to_csv(screen_names))
265
266
267
268
269
270
271
272
273

    _lookup_friendships = bind_api(
        path = '/friendships/lookup.json',
        payload_type = 'relationship', payload_list = True,
        allowed_param = ['user_id', 'screen_name'],
        require_auth = True
    )


274
    """ friends/ids """
Josh Roesslein's avatar
Josh Roesslein committed
275
276
    friends_ids = bind_api(
        path = '/friends/ids.json',
277
        payload_type = 'ids',
278
        allowed_param = ['id', 'user_id', 'screen_name', 'cursor']
Josh Roesslein's avatar
Josh Roesslein committed
279
280
    )

281
282
283
284
285
286
287
    """ friends/list """
    friends = bind_api(
        path = '/friends/list.json',
        payload_type = 'user', payload_list = True,
        allowed_param = ['id', 'user_id', 'screen_name', 'page', 'cursor']
    )

288
289
290
291
292
293
294
295
296
297
298
299
300
301
    """ friendships/incoming """
    friendships_incoming = bind_api(
        path = '/friendships/incoming.json',
        payload_type = 'ids',
        allowed_param = ['cursor']
    )

    """ friendships/outgoing"""
    friendships_outgoing = bind_api(
        path = '/friendships/outgoing.json',
        payload_type = 'ids',
        allowed_param = ['cursor']
    )

302
    """ followers/ids """
Josh Roesslein's avatar
Josh Roesslein committed
303
304
    followers_ids = bind_api(
        path = '/followers/ids.json',
305
        payload_type = 'ids',
306
        allowed_param = ['id', 'user_id', 'screen_name', 'cursor']
Josh Roesslein's avatar
Josh Roesslein committed
307
308
    )

309
310
311
312
313
314
315
    """ followers/list """
    followers = bind_api(
        path = '/followers/list.json',
        payload_type = 'user', payload_list = True,
        allowed_param = ['id', 'user_id', 'screen_name', 'page', 'cursor']
    )

316
    """ account/verify_credentials """
317
    def verify_credentials(self, **kargs):
Josh Roesslein's avatar
Josh Roesslein committed
318
319
320
        try:
            return bind_api(
                path = '/account/verify_credentials.json',
321
                payload_type = 'user',
322
323
324
                require_auth = True,
                allowed_param = ['include_entities', 'skip_status'],
            )(self, **kargs)
325
326
327
328
        except TweepError, e:
            if e.response and e.response.status == 401:
                return False
            raise
Josh Roesslein's avatar
Josh Roesslein committed
329

330
    """ account/rate_limit_status """
Josh Roesslein's avatar
Josh Roesslein committed
331
    rate_limit_status = bind_api(
332
        path = '/application/rate_limit_status.json',
333
        payload_type = 'json',
334
        allowed_param = ['resources'],
335
        use_cache = False
Josh Roesslein's avatar
Josh Roesslein committed
336
337
    )

338
    """ account/update_delivery_device """
Josh Roesslein's avatar
Josh Roesslein committed
339
340
341
342
    set_delivery_device = bind_api(
        path = '/account/update_delivery_device.json',
        method = 'POST',
        allowed_param = ['device'],
343
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
344
345
346
        require_auth = True
    )

347
    """ account/update_profile_colors """
Josh Roesslein's avatar
Josh Roesslein committed
348
349
350
    update_profile_colors = bind_api(
        path = '/account/update_profile_colors.json',
        method = 'POST',
351
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
352
353
354
355
356
357
        allowed_param = ['profile_background_color', 'profile_text_color',
                          'profile_link_color', 'profile_sidebar_fill_color',
                          'profile_sidebar_border_color'],
        require_auth = True
    )

358
    """ account/update_profile_image """
Josh Roesslein's avatar
Josh Roesslein committed
359
    def update_profile_image(self, filename):
Josh Roesslein's avatar
Josh Roesslein committed
360
        headers, post_data = API._pack_image(filename, 700)
Josh Roesslein's avatar
Josh Roesslein committed
361
        return bind_api(
Josh Roesslein's avatar
Josh Roesslein committed
362
363
            path = '/account/update_profile_image.json',
            method = 'POST',
364
            payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
365
366
367
            require_auth = True
        )(self, post_data=post_data, headers=headers)

368
    """ account/update_profile_background_image """
Josh Roesslein's avatar
Josh Roesslein committed
369
    def update_profile_background_image(self, filename, *args, **kargs):
Josh Roesslein's avatar
Josh Roesslein committed
370
        headers, post_data = API._pack_image(filename, 800)
Josh Roesslein's avatar
Josh Roesslein committed
371
372
373
        bind_api(
            path = '/account/update_profile_background_image.json',
            method = 'POST',
374
            payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
375
376
377
378
            allowed_param = ['tile'],
            require_auth = True
        )(self, post_data=post_data, headers=headers)

379
380
381
382
383
384
385
386
387
388
389
    """ account/update_profile_banner """
    def update_profile_banner(self, filename, *args, **kargs):
        headers, post_data = API._pack_image(filename, 700, form_field="banner")
        bind_api(
            path = '/account/update_profile_banner.json',
            method = 'POST',
            allowed_param = ['width', 'height', 'offset_left', 'offset_right'],
            require_auth = True
        )(self, post_data=post_data, headers=headers)


390
    """ account/update_profile """
Josh Roesslein's avatar
Josh Roesslein committed
391
392
393
    update_profile = bind_api(
        path = '/account/update_profile.json',
        method = 'POST',
394
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
395
        allowed_param = ['name', 'url', 'location', 'description'],
396
        require_auth = True
Josh Roesslein's avatar
Josh Roesslein committed
397
398
    )

399
    """ favorites """
Josh Roesslein's avatar
Josh Roesslein committed
400
    favorites = bind_api(
401
        path = '/favorites/list.json',
402
        payload_type = 'status', payload_list = True,
403
        allowed_param = ['screen_name', 'user_id', 'max_id', 'count', 'since_id', 'max_id']
Josh Roesslein's avatar
Josh Roesslein committed
404
405
    )

406
    """ favorites/create """
407
    create_favorite = bind_api(
408
        path = '/favorites/create.json',
409
        method = 'POST',
410
        payload_type = 'status',
411
412
413
        allowed_param = ['id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
414

415
    """ favorites/destroy """
416
    destroy_favorite = bind_api(
417
418
        path = '/favorites/destroy.json',
        method = 'POST',
419
        payload_type = 'status',
420
421
422
        allowed_param = ['id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
423

424
    """ blocks/create """
Josh Roesslein's avatar
Josh Roesslein committed
425
426
427
    create_block = bind_api(
        path = '/blocks/create.json',
        method = 'POST',
428
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
429
        allowed_param = ['id', 'user_id', 'screen_name'],
Josh Roesslein's avatar
Josh Roesslein committed
430
431
432
        require_auth = True
    )

433
    """ blocks/destroy """
Josh Roesslein's avatar
Josh Roesslein committed
434
435
436
    destroy_block = bind_api(
        path = '/blocks/destroy.json',
        method = 'DELETE',
437
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
438
        allowed_param = ['id', 'user_id', 'screen_name'],
Josh Roesslein's avatar
Josh Roesslein committed
439
440
441
        require_auth = True
    )

442
    """ blocks/blocking """
Josh Roesslein's avatar
Josh Roesslein committed
443
    blocks = bind_api(
Joshua Roesslein's avatar
Joshua Roesslein committed
444
        path = '/blocks/list.json',
445
        payload_type = 'user', payload_list = True,
Josh Roesslein's avatar
Josh Roesslein committed
446
447
448
449
        allowed_param = ['page'],
        require_auth = True
    )

450
    """ blocks/blocking/ids """
Josh Roesslein's avatar
Josh Roesslein committed
451
    blocks_ids = bind_api(
Joshua Roesslein's avatar
Joshua Roesslein committed
452
        path = '/blocks/ids.json',
453
        payload_type = 'json',
Josh Roesslein's avatar
Josh Roesslein committed
454
455
456
        require_auth = True
    )

457
    """ report_spam """
Josh Roesslein's avatar
Josh Roesslein committed
458
    report_spam = bind_api(
459
        path = '/users/report_spam.json',
Josh Roesslein's avatar
Josh Roesslein committed
460
        method = 'POST',
461
        payload_type = 'user',
462
        allowed_param = ['user_id', 'screen_name'],
Josh Roesslein's avatar
Josh Roesslein committed
463
464
465
        require_auth = True
    )

466
    """ saved_searches """
Josh Roesslein's avatar
Josh Roesslein committed
467
    saved_searches = bind_api(
468
        path = '/saved_searches/list.json',
469
        payload_type = 'saved_search', payload_list = True,
Josh Roesslein's avatar
Josh Roesslein committed
470
471
472
        require_auth = True
    )

473
    """ saved_searches/show """
474
475
    get_saved_search = bind_api(
        path = '/saved_searches/show/{id}.json',
476
        payload_type = 'saved_search',
477
478
479
        allowed_param = ['id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
480

481
    """ saved_searches/create """
Josh Roesslein's avatar
Josh Roesslein committed
482
483
484
    create_saved_search = bind_api(
        path = '/saved_searches/create.json',
        method = 'POST',
485
        payload_type = 'saved_search',
Josh Roesslein's avatar
Josh Roesslein committed
486
487
488
489
        allowed_param = ['query'],
        require_auth = True
    )

490
    """ saved_searches/destroy """
491
492
    destroy_saved_search = bind_api(
        path = '/saved_searches/destroy/{id}.json',
493
        method = 'POST',
494
        payload_type = 'saved_search',
495
496
497
        allowed_param = ['id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
498

499
    """ help/test """
Josh Roesslein's avatar
Josh Roesslein committed
500
    def test(self):
501
        try:
502
            bind_api(
503
504
505
506
                path = '/help/test.json',
            )(self)
        except TweepError:
            return False
507
        return True
508

509
510
511
512
513
514
515
    create_list = bind_api(
        path = '/lists/create.json',
        method = 'POST',
        payload_type = 'list',
        allowed_param = ['name', 'mode', 'description'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
516

517
518
519
520
521
522
523
    destroy_list = bind_api(
        path = '/lists/destroy.json',
        method = 'POST',
        payload_type = 'list',
        allowed_param = ['owner_screen_name', 'owner_id', 'list_id', 'slug'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
524

525
526
527
528
529
530
531
    update_list = bind_api(
        path = '/lists/update.json',
        method = 'POST',
        payload_type = 'list',
        allowed_param = ['list_id', 'slug', 'name', 'mode', 'description', 'owner_screen_name', 'owner_id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
532

533
534
    lists_all = bind_api(
        path = '/lists/list.json',
535
        payload_type = 'list', payload_list = True,
536
        allowed_param = ['screen_name', 'user_id'],
537
538
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
539

540
    lists_memberships = bind_api(
541
        path = '/lists/memberships.json',
542
        payload_type = 'list', payload_list = True,
543
        allowed_param = ['screen_name', 'user_id', 'filter_to_owned_lists', 'cursor'],
544
545
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
546

547
    lists_subscriptions = bind_api(
548
        path = '/lists/subscriptions.json',
549
        payload_type = 'list', payload_list = True,
550
        allowed_param = ['screen_name', 'user_id', 'cursor'],
551
552
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
553

554
    list_timeline = bind_api(
555
        path = '/lists/statuses.json',
556
        payload_type = 'status', payload_list = True,
557
        allowed_param = ['owner_screen_name', 'slug', 'owner_id', 'list_id', 'since_id', 'max_id', 'count']
558
    )
Josh Roesslein's avatar
Josh Roesslein committed
559

560
    get_list = bind_api(
561
        path = '/lists/show.json',
562
        payload_type = 'list',
563
        allowed_param = ['owner_screen_name', 'owner_id', 'slug', 'list_id']
564
    )
Josh Roesslein's avatar
Josh Roesslein committed
565

566
567
568
569
570
571
572
    add_list_member = bind_api(
        path = '/lists/members/create.json',
        method = 'POST',
        payload_type = 'list',
        allowed_param = ['screen_name', 'user_id', 'owner_screen_name', 'owner_id', 'slug', 'list_id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
573

574
575
576
577
578
579
580
    remove_list_member = bind_api(
        path = '/lists/members/destroy.json',
        method = 'POST',
        payload_type = 'list',
        allowed_param = ['screen_name', 'user_id', 'owner_screen_name', 'owner_id', 'slug', 'list_id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
581

582
    list_members = bind_api(
583
        path = '/lists/members.json',
584
        payload_type = 'user', payload_list = True,
585
        allowed_param = ['owner_screen_name', 'slug', 'list_id', 'owner_id', 'cursor']
586
    )
Josh Roesslein's avatar
Josh Roesslein committed
587

588
589
590
591
592
    show_list_member = bind_api(
        path = '/lists/members/show.json',
        payload_type = 'user',
        allowed_param = ['list_id', 'slug', 'user_id', 'screen_name', 'owner_screen_name', 'owner_id']
    )
Josh Roesslein's avatar
Josh Roesslein committed
593

594
    subscribe_list = bind_api(
595
        path = '/lists/subscribers/create.json',
596
        method = 'POST',
597
        payload_type = 'list',
598
        allowed_param = ['owner_screen_name', 'slug', 'owner_id', 'list_id'],
599
600
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
601

602
    unsubscribe_list = bind_api(
603
604
        path = '/lists/subscribers/destroy.json',
        method = 'POST',
605
        payload_type = 'list',
606
        allowed_param = ['owner_screen_name', 'slug', 'owner_id', 'list_id'],
607
608
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
609

610
    list_subscribers = bind_api(
611
        path = '/lists/subscribers.json',
612
        payload_type = 'user', payload_list = True,
613
        allowed_param = ['owner_screen_name', 'slug', 'owner_id', 'list_id', 'cursor']
614
    )
Josh Roesslein's avatar
Josh Roesslein committed
615

616
617
618
619
620
    show_list_subscriber = bind_api(
        path = '/lists/subscribers/show.json',
        payload_type = 'user',
        allowed_param = ['owner_screen_name', 'slug', 'screen_name', 'owner_id', 'list_id', 'user_id']
    )
Josh Roesslein's avatar
Josh Roesslein committed
621

622
    """ trends/available """
623
624
    trends_available = bind_api(
        path = '/trends/available.json',
625
626
627
628
629
        payload_type = 'json'
    )

    trends_place = bind_api(
        path = '/trends/place.json',
630
        payload_type = 'json',
631
        allowed_param = ['id', 'exclude']
632
633
    )

634
635
    trends_closest = bind_api(
        path = '/trends/closest.json',
636
        payload_type = 'json',
637
        allowed_param = ['lat', 'long']
638
    )
639

640
    """ search """
641
642
643
    search = bind_api(
        search_api = True,
        path = '/search.json',
644
        payload_type = 'search_result', payload_list = True,
645
        allowed_param = ['q', 'lang', 'locale', 'rpp', 'page', 'since_id', 'geocode', 'show_user', 'max_id', 'since', 'until', 'result_type']
646
    )
647
    search.pagination_mode = 'page'
Josh Roesslein's avatar
Josh Roesslein committed
648

649
    """ trends/daily """
650
651
    trends_daily = bind_api(
        path = '/trends/daily.json',
652
        payload_type = 'json',
653
654
        allowed_param = ['date', 'exclude']
    )
655

656
    """ trends/weekly """
657
658
    trends_weekly = bind_api(
        path = '/trends/weekly.json',
659
        payload_type = 'json',
660
661
        allowed_param = ['date', 'exclude']
    )
662

663
664
665
    """ geo/reverse_geocode """
    reverse_geocode = bind_api(
        path = '/geo/reverse_geocode.json',
666
        payload_type = 'place', payload_list = True,
667
668
669
670
671
672
        allowed_param = ['lat', 'long', 'accuracy', 'granularity', 'max_results']
    )

    """ geo/id """
    geo_id = bind_api(
        path = '/geo/id/{id}.json',
673
        payload_type = 'place',
674
675
676
        allowed_param = ['id']
    )

677
678
679
    """ geo/search """
    geo_search = bind_api(
        path = '/geo/search.json',
680
        payload_type = 'place', payload_list = True,
681
682
683
        allowed_param = ['lat', 'long', 'query', 'ip', 'granularity', 'accuracy', 'max_results', 'contained_within']
    )

684
685
686
687
688
689
690
    """ geo/similar_places """
    geo_similar_places = bind_api(
        path = '/geo/similar_places.json',
        payload_type = 'place', payload_list = True,
        allowed_param = ['lat', 'long', 'name', 'contained_within']
    )

691
    """ Internal use only """
Josh Roesslein's avatar
Josh Roesslein committed
692
    @staticmethod
Josh Roesslein's avatar
Josh Roesslein committed
693
694
695
696
697
698
    def _pack_image(filename, max_size):
        """Pack image from file into multipart-formdata post body"""
        # image must be less than 700kb in size
        try:
            if os.path.getsize(filename) > (max_size * 1024):
                raise TweepError('File is too big, must be less than 700kb.')
699
        except os.error:
Josh Roesslein's avatar
Josh Roesslein committed
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
            raise TweepError('Unable to access file')

        # image must be gif, jpeg, or png
        file_type = mimetypes.guess_type(filename)
        if file_type is None:
            raise TweepError('Could not determine file type')
        file_type = file_type[0]
        if file_type not in ['image/gif', 'image/jpeg', 'image/png']:
            raise TweepError('Invalid file type for image: %s' % file_type)

        # build the mulitpart-formdata body
        fp = open(filename, 'rb')
        BOUNDARY = 'Tw3ePy'
        body = []
        body.append('--' + BOUNDARY)
        body.append('Content-Disposition: form-data; name="image"; filename="%s"' % filename)
        body.append('Content-Type: %s' % file_type)
        body.append('')
        body.append(fp.read())
        body.append('--' + BOUNDARY + '--')
        body.append('')
        fp.close()
        body = '\r\n'.join(body)

        # build headers
        headers = {
            'Content-Type': 'multipart/form-data; boundary=Tw3ePy',
727
            'Content-Length': str(len(body))
Josh Roesslein's avatar
Josh Roesslein committed
728
729
730
        }

        return headers, body
731