api.py 21.6 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,
21
            parser=None):
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
29
30
        self.retry_count = retry_count
        self.retry_delay = retry_delay
31
        self.retry_errors = retry_errors
32
        self.parser = parser or ModelParser()
Josh Roesslein's avatar
Josh Roesslein committed
33

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

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

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

58
59
60
61
62
63
64
    """/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
    )
65

Aaron Swartz's avatar
Aaron Swartz committed
66
67
68
69
70
71
    """/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
72
    )
73
74
75
76
77
78
79
80
81

    """/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
    )

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

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

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

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

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

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

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

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

146
147
148
149
150
151
152
153
154
155
    """ 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'],
    )

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

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

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
    """ 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
    )

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

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

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

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

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

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

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

252
    """ friendships/exists """
Josh Roesslein's avatar
Josh Roesslein committed
253
254
    exists_friendship = bind_api(
        path = '/friendships/exists.json',
255
        payload_type = 'json',
Josh Roesslein's avatar
Josh Roesslein committed
256
257
258
        allowed_param = ['user_a', 'user_b']
    )

259
    """ friendships/show """
Josh Roesslein's avatar
Josh Roesslein committed
260
261
    show_friendship = bind_api(
        path = '/friendships/show.json',
262
        payload_type = 'friendship',
Josh Roesslein's avatar
Josh Roesslein committed
263
264
265
266
        allowed_param = ['source_id', 'source_screen_name',
                          'target_id', 'target_screen_name']
    )

267
268
269
270
271
272
273
274
275
276
277
278
279

    """ Perform bulk look up of friendships from user ID or screenname """
    def lookup_friendships(self, user_ids=None, screen_names=None):
	    return self._lookup_friendships(list_to_csv(user_ids), list_to_csv(screen_names))

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


280
    """ friends/ids """
Josh Roesslein's avatar
Josh Roesslein committed
281
282
    friends_ids = bind_api(
        path = '/friends/ids.json',
283
        payload_type = 'ids',
284
        allowed_param = ['id', 'user_id', 'screen_name', 'cursor']
Josh Roesslein's avatar
Josh Roesslein committed
285
286
    )

287
288
289
290
291
292
293
294
295
296
297
298
299
300
    """ 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']
    )

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

308
    """ account/verify_credentials """
309
    def verify_credentials(self, **kargs):
Josh Roesslein's avatar
Josh Roesslein committed
310
311
312
        try:
            return bind_api(
                path = '/account/verify_credentials.json',
313
                payload_type = 'user',
314
315
316
                require_auth = True,
                allowed_param = ['include_entities', 'skip_status'],
            )(self, **kargs)
317
318
319
320
        except TweepError, e:
            if e.response and e.response.status == 401:
                return False
            raise
Josh Roesslein's avatar
Josh Roesslein committed
321

322
    """ account/rate_limit_status """
Josh Roesslein's avatar
Josh Roesslein committed
323
    rate_limit_status = bind_api(
324
        path = '/application/rate_limit_status.json',
325
        payload_type = 'json',
326
        allowed_param = ['resources'],
327
        use_cache = False
Josh Roesslein's avatar
Josh Roesslein committed
328
329
    )

330
    """ account/update_delivery_device """
Josh Roesslein's avatar
Josh Roesslein committed
331
332
333
334
    set_delivery_device = bind_api(
        path = '/account/update_delivery_device.json',
        method = 'POST',
        allowed_param = ['device'],
335
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
336
337
338
        require_auth = True
    )

339
    """ account/update_profile_colors """
Josh Roesslein's avatar
Josh Roesslein committed
340
341
342
    update_profile_colors = bind_api(
        path = '/account/update_profile_colors.json',
        method = 'POST',
343
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
344
345
346
347
348
349
        allowed_param = ['profile_background_color', 'profile_text_color',
                          'profile_link_color', 'profile_sidebar_fill_color',
                          'profile_sidebar_border_color'],
        require_auth = True
    )

350
    """ account/update_profile_image """
Josh Roesslein's avatar
Josh Roesslein committed
351
    def update_profile_image(self, filename):
Josh Roesslein's avatar
Josh Roesslein committed
352
        headers, post_data = API._pack_image(filename, 700)
Josh Roesslein's avatar
Josh Roesslein committed
353
        return bind_api(
Josh Roesslein's avatar
Josh Roesslein committed
354
355
            path = '/account/update_profile_image.json',
            method = 'POST',
356
            payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
357
358
359
            require_auth = True
        )(self, post_data=post_data, headers=headers)

360
    """ account/update_profile_background_image """
Josh Roesslein's avatar
Josh Roesslein committed
361
    def update_profile_background_image(self, filename, *args, **kargs):
Josh Roesslein's avatar
Josh Roesslein committed
362
        headers, post_data = API._pack_image(filename, 800)
Josh Roesslein's avatar
Josh Roesslein committed
363
364
365
        bind_api(
            path = '/account/update_profile_background_image.json',
            method = 'POST',
366
            payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
367
368
369
370
            allowed_param = ['tile'],
            require_auth = True
        )(self, post_data=post_data, headers=headers)

371
    """ account/update_profile """
Josh Roesslein's avatar
Josh Roesslein committed
372
373
374
    update_profile = bind_api(
        path = '/account/update_profile.json',
        method = 'POST',
375
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
376
        allowed_param = ['name', 'url', 'location', 'description'],
377
        require_auth = True
Josh Roesslein's avatar
Josh Roesslein committed
378
379
    )

380
    """ favorites """
Josh Roesslein's avatar
Josh Roesslein committed
381
    favorites = bind_api(
382
        path = '/favorites/list.json',
383
        payload_type = 'status', payload_list = True,
384
        allowed_param = ['screen_name', 'user_id', 'max_id', 'count', 'since_id', 'max_id']
Josh Roesslein's avatar
Josh Roesslein committed
385
386
    )

387
    """ favorites/create """
388
    create_favorite = bind_api(
389
        path = '/favorites/create.json',
390
        method = 'POST',
391
        payload_type = 'status',
392
393
394
        allowed_param = ['id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
395

396
    """ favorites/destroy """
397
    destroy_favorite = bind_api(
398
399
        path = '/favorites/destroy.json',
        method = 'POST',
400
        payload_type = 'status',
401
402
403
        allowed_param = ['id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
404

405
    """ blocks/create """
Josh Roesslein's avatar
Josh Roesslein committed
406
407
408
    create_block = bind_api(
        path = '/blocks/create.json',
        method = 'POST',
409
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
410
        allowed_param = ['id', 'user_id', 'screen_name'],
Josh Roesslein's avatar
Josh Roesslein committed
411
412
413
        require_auth = True
    )

414
    """ blocks/destroy """
Josh Roesslein's avatar
Josh Roesslein committed
415
416
417
    destroy_block = bind_api(
        path = '/blocks/destroy.json',
        method = 'DELETE',
418
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
419
        allowed_param = ['id', 'user_id', 'screen_name'],
Josh Roesslein's avatar
Josh Roesslein committed
420
421
422
        require_auth = True
    )

423
    """ blocks/blocking """
Josh Roesslein's avatar
Josh Roesslein committed
424
    blocks = bind_api(
Joshua Roesslein's avatar
Joshua Roesslein committed
425
        path = '/blocks/list.json',
426
        payload_type = 'user', payload_list = True,
Josh Roesslein's avatar
Josh Roesslein committed
427
428
429
430
        allowed_param = ['page'],
        require_auth = True
    )

431
    """ blocks/blocking/ids """
Josh Roesslein's avatar
Josh Roesslein committed
432
    blocks_ids = bind_api(
Joshua Roesslein's avatar
Joshua Roesslein committed
433
        path = '/blocks/ids.json',
434
        payload_type = 'json',
Josh Roesslein's avatar
Josh Roesslein committed
435
436
437
        require_auth = True
    )

438
    """ report_spam """
Josh Roesslein's avatar
Josh Roesslein committed
439
440
441
    report_spam = bind_api(
        path = '/report_spam.json',
        method = 'POST',
442
        payload_type = 'user',
Josh Roesslein's avatar
Josh Roesslein committed
443
444
445
446
        allowed_param = ['id', 'user_id', 'screen_name'],
        require_auth = True
    )

447
    """ saved_searches """
Josh Roesslein's avatar
Josh Roesslein committed
448
    saved_searches = bind_api(
449
        path = '/saved_searches/list.json',
450
        payload_type = 'saved_search', payload_list = True,
Josh Roesslein's avatar
Josh Roesslein committed
451
452
453
        require_auth = True
    )

454
    """ saved_searches/show """
455
456
    get_saved_search = bind_api(
        path = '/saved_searches/show/{id}.json',
457
        payload_type = 'saved_search',
458
459
460
        allowed_param = ['id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
461

462
    """ saved_searches/create """
Josh Roesslein's avatar
Josh Roesslein committed
463
464
465
    create_saved_search = bind_api(
        path = '/saved_searches/create.json',
        method = 'POST',
466
        payload_type = 'saved_search',
Josh Roesslein's avatar
Josh Roesslein committed
467
468
469
470
        allowed_param = ['query'],
        require_auth = True
    )

471
    """ saved_searches/destroy """
472
473
    destroy_saved_search = bind_api(
        path = '/saved_searches/destroy/{id}.json',
474
        method = 'POST',
475
        payload_type = 'saved_search',
476
477
478
        allowed_param = ['id'],
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
479

480
    """ help/test """
Josh Roesslein's avatar
Josh Roesslein committed
481
    def test(self):
482
        try:
483
            bind_api(
484
485
486
487
                path = '/help/test.json',
            )(self)
        except TweepError:
            return False
488
        return True
489

490
491
492
493
494
495
496
    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
497

498
499
500
501
502
503
504
    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
505

506
507
508
509
510
511
512
    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
513

514
515
    lists_all = bind_api(
        path = '/lists/list.json',
516
        payload_type = 'list', payload_list = True,
517
        allowed_param = ['screen_name', 'user_id'],
518
519
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
520

521
    lists_memberships = bind_api(
522
        path = '/lists/memberships.json',
523
        payload_type = 'list', payload_list = True,
524
        allowed_param = ['screen_name', 'user_id', 'filter_to_owned_lists', 'cursor'],
525
526
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
527

528
    lists_subscriptions = bind_api(
529
        path = '/lists/subscriptions.json',
530
        payload_type = 'list', payload_list = True,
531
        allowed_param = ['screen_name', 'user_id', 'cursor'],
532
533
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
534

535
    list_timeline = bind_api(
536
        path = '/lists/statuses.json',
537
        payload_type = 'status', payload_list = True,
538
        allowed_param = ['owner_screen_name', 'slug', 'owner_id', 'list_id', 'since_id', 'max_id', 'count']
539
    )
Josh Roesslein's avatar
Josh Roesslein committed
540

541
    get_list = bind_api(
542
        path = '/lists/show.json',
543
        payload_type = 'list',
544
        allowed_param = ['owner_screen_name', 'owner_id', 'slug', 'list_id']
545
    )
Josh Roesslein's avatar
Josh Roesslein committed
546

547
548
549
550
551
552
553
    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
554

555
556
557
558
559
560
561
    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
562

563
    list_members = bind_api(
564
        path = '/lists/members.json',
565
        payload_type = 'user', payload_list = True,
566
        allowed_param = ['owner_screen_name', 'slug', 'list_id', 'owner_id', 'cursor']
567
    )
Josh Roesslein's avatar
Josh Roesslein committed
568

569
570
571
572
573
    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
574

575
    subscribe_list = bind_api(
576
        path = '/lists/subscribers/create.json',
577
        method = 'POST',
578
        payload_type = 'list',
579
        allowed_param = ['owner_screen_name', 'slug', 'owner_id', 'list_id'],
580
581
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
582

583
    unsubscribe_list = bind_api(
584
585
        path = '/lists/subscribers/destroy.json',
        method = 'POST',
586
        payload_type = 'list',
587
        allowed_param = ['owner_screen_name', 'slug', 'owner_id', 'list_id'],
588
589
        require_auth = True
    )
Josh Roesslein's avatar
Josh Roesslein committed
590

591
    list_subscribers = bind_api(
592
        path = '/lists/subscribers.json',
593
        payload_type = 'user', payload_list = True,
594
        allowed_param = ['owner_screen_name', 'slug', 'owner_id', 'list_id', 'cursor']
595
    )
Josh Roesslein's avatar
Josh Roesslein committed
596

597
598
599
600
601
    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
602

603
    """ trends/available """
604
605
    trends_available = bind_api(
        path = '/trends/available.json',
606
607
608
609
610
        payload_type = 'json'
    )

    trends_place = bind_api(
        path = '/trends/place.json',
611
        payload_type = 'json',
612
        allowed_param = ['id', 'exclude']
613
614
    )

615
616
    trends_closest = bind_api(
        path = '/trends/closest.json',
617
        payload_type = 'json',
618
        allowed_param = ['lat', 'long']
619
    )
620

621
    """ search """
622
623
624
    search = bind_api(
        search_api = True,
        path = '/search.json',
625
        payload_type = 'search_result', payload_list = True,
626
        allowed_param = ['q', 'lang', 'locale', 'rpp', 'page', 'since_id', 'geocode', 'show_user', 'max_id', 'since', 'until', 'result_type']
627
    )
628
    search.pagination_mode = 'page'
Josh Roesslein's avatar
Josh Roesslein committed
629

630
    """ trends/daily """
631
632
    trends_daily = bind_api(
        path = '/trends/daily.json',
633
        payload_type = 'json',
634
635
        allowed_param = ['date', 'exclude']
    )
636

637
    """ trends/weekly """
638
639
    trends_weekly = bind_api(
        path = '/trends/weekly.json',
640
        payload_type = 'json',
641
642
        allowed_param = ['date', 'exclude']
    )
643

644
645
646
    """ geo/reverse_geocode """
    reverse_geocode = bind_api(
        path = '/geo/reverse_geocode.json',
647
        payload_type = 'place', payload_list = True,
648
649
650
651
652
653
        allowed_param = ['lat', 'long', 'accuracy', 'granularity', 'max_results']
    )

    """ geo/id """
    geo_id = bind_api(
        path = '/geo/id/{id}.json',
654
        payload_type = 'place',
655
656
657
        allowed_param = ['id']
    )

658
659
660
    """ geo/search """
    geo_search = bind_api(
        path = '/geo/search.json',
661
        payload_type = 'place', payload_list = True,
662
663
664
        allowed_param = ['lat', 'long', 'query', 'ip', 'granularity', 'accuracy', 'max_results', 'contained_within']
    )

665
666
667
668
669
670
671
    """ 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']
    )

672
    """ Internal use only """
Josh Roesslein's avatar
Josh Roesslein committed
673
    @staticmethod
Josh Roesslein's avatar
Josh Roesslein committed
674
675
676
677
678
679
    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.')
680
        except os.error:
Josh Roesslein's avatar
Josh Roesslein committed
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
            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',
708
            'Content-Length': str(len(body))
Josh Roesslein's avatar
Josh Roesslein committed
709
710
711
        }

        return headers, body
712