diff options
Diffstat (limited to 'mastodon')
-rw-r--r-- | mastodon/Mastodon.py | 169 |
1 files changed, 94 insertions, 75 deletions
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py index f15ee23..f6551f0 100644 --- a/mastodon/Mastodon.py +++ b/mastodon/Mastodon.py | |||
@@ -38,19 +38,24 @@ def parse_version_string(version_string): | |||
38 | ] | 38 | ] |
39 | return version_parts | 39 | return version_parts |
40 | 40 | ||
41 | def api_version(version): | 41 | def api_version(created_ver, last_changed_ver): |
42 | """Version check decorator. Currently only checks Bigger Than.""" | 42 | """Version check decorator. Currently only checks Bigger Than.""" |
43 | def api_min_version_decorator(function): | 43 | def api_min_version_decorator(function): |
44 | def wrapper(function, self, *args, **kwargs): | 44 | def wrapper(function, self, *args, **kwargs): |
45 | if not self.version_check_mode == "none": | ||
46 | if self.version_check_mode == "created": | ||
47 | version = created_version | ||
48 | else: | ||
49 | version = last_changed_ver | ||
45 | major, minor, patch = parse_version_string(version) | 50 | major, minor, patch = parse_version_string(version) |
46 | if major > self.mastodon_major: | 51 | if major > self.mastodon_major: |
47 | raise MastodonVersionError("Specified version does not support this API endpoint (Available from " + version + ")") | 52 | raise MastodonVersionError("Version check failed (Need version " + version + ")") |
48 | elif major == self.mastodon_major and minor > self.mastodon_minor: | 53 | elif major == self.mastodon_major and minor > self.mastodon_minor: |
49 | raise MastodonVersionError("Specified version does not support this API endpoint (Available from " + version + ")") | 54 | raise MastodonVersionError("Version check failed (Need version " + version + ")") |
50 | elif major == self.mastodon_major and minor == self.mastodon_minor and patch > self.mastodon_patch: | 55 | elif major == self.mastodon_major and minor == self.mastodon_minor and patch > self.mastodon_patch: |
51 | raise MastodonVersionError("Specified version does not support this API endpoint (Available from " + version + ")") | 56 | raise MastodonVersionError("Version check failed (Need version " + version + ")") |
52 | return function(self, *args, **kwargs) | 57 | return function(self, *args, **kwargs) |
53 | function.__doc__ = function.__doc__ + "\n\n *Minumum Mastodon version: " + version + "*" | 58 | function.__doc__ = function.__doc__ + "\n\n *Added: Mastodon v" + created_ver + ", last changed: Mastodon v" + last_changed_ver + "*" |
54 | return decorate(function, wrapper) | 59 | return decorate(function, wrapper) |
55 | return api_min_version_decorator | 60 | return api_min_version_decorator |
56 | 61 | ||
@@ -116,7 +121,8 @@ class Mastodon: | |||
116 | def __init__(self, client_id, client_secret=None, access_token=None, | 121 | def __init__(self, client_id, client_secret=None, access_token=None, |
117 | api_base_url=__DEFAULT_BASE_URL, debug_requests=False, | 122 | api_base_url=__DEFAULT_BASE_URL, debug_requests=False, |
118 | ratelimit_method="wait", ratelimit_pacefactor=1.1, | 123 | ratelimit_method="wait", ratelimit_pacefactor=1.1, |
119 | request_timeout=__DEFAULT_TIMEOUT, mastodon_version=None): | 124 | request_timeout=__DEFAULT_TIMEOUT, mastodon_version=None, |
125 | version_check_mode = "changed"): | ||
120 | """ | 126 | """ |
121 | Create a new API wrapper instance based on the given `client_secret` and `client_id`. If you | 127 | Create a new API wrapper instance based on the given `client_secret` and `client_id`. If you |
122 | give a `client_id` and it is not a file, you must also give a secret. | 128 | give a `client_id` and it is not a file, you must also give a secret. |
@@ -142,6 +148,12 @@ class Mastodon: | |||
142 | expect to be installed on the server. The function will throw an error if an unparseable | 148 | expect to be installed on the server. The function will throw an error if an unparseable |
143 | Version is specified. If no version is specified, Mastodon.py will set `mastodon_version` to the | 149 | Version is specified. If no version is specified, Mastodon.py will set `mastodon_version` to the |
144 | detected version. | 150 | detected version. |
151 | |||
152 | The version check mode can be set to "created", "changed" (the default behaviour) or "none". If set to | ||
153 | "created", Mastodon.py will throw an error if the version of Mastodon it is connected to is too old | ||
154 | to have an endpoint. If it is set to "changed", it will throw an error if the endpoints behaviour has | ||
155 | changed after the version of Mastodon that is connected has been released. If it is set to "none", | ||
156 | version checking is disabled. | ||
145 | """ | 157 | """ |
146 | self.api_base_url = Mastodon.__protocolize(api_base_url) | 158 | self.api_base_url = Mastodon.__protocolize(api_base_url) |
147 | self.client_id = client_id | 159 | self.client_id = client_id |
@@ -169,6 +181,10 @@ class Mastodon: | |||
169 | except: | 181 | except: |
170 | raise MastodonVersionError("Bad version specified") | 182 | raise MastodonVersionError("Bad version specified") |
171 | 183 | ||
184 | if not version_check_mode in ["created", "changed", "none"]: | ||
185 | raise MastodonIllegalArgumentError("Invalid version check method.") | ||
186 | self.version_check_mode = version_check_mode | ||
187 | |||
172 | # Ratelimiting parameter check | 188 | # Ratelimiting parameter check |
173 | if ratelimit_method not in ["throw", "wait", "pace"]: | 189 | if ratelimit_method not in ["throw", "wait", "pace"]: |
174 | raise MastodonIllegalArgumentError("Invalid ratelimit method.") | 190 | raise MastodonIllegalArgumentError("Invalid ratelimit method.") |
@@ -301,7 +317,7 @@ class Mastodon: | |||
301 | ### | 317 | ### |
302 | # Reading data: Instances | 318 | # Reading data: Instances |
303 | ### | 319 | ### |
304 | @api_version("1.1.0") | 320 | @api_version("1.1.0", "1.4.2") |
305 | def instance(self): | 321 | def instance(self): |
306 | """ | 322 | """ |
307 | Retrieve basic information about the instance, including the URI and administrative contact email. | 323 | Retrieve basic information about the instance, including the URI and administrative contact email. |
@@ -321,7 +337,7 @@ class Mastodon: | |||
321 | ### | 337 | ### |
322 | # Reading data: Timelines | 338 | # Reading data: Timelines |
323 | ## | 339 | ## |
324 | @api_version("1.0.0") | 340 | @api_version("1.0.0", "2.0.0") |
325 | def timeline(self, timeline="home", max_id=None, since_id=None, limit=None): | 341 | def timeline(self, timeline="home", max_id=None, since_id=None, limit=None): |
326 | """ | 342 | """ |
327 | Fetch statuses, most recent ones first. `timeline` can be 'home', 'local', 'public', | 343 | Fetch statuses, most recent ones first. `timeline` can be 'home', 'local', 'public', |
@@ -348,7 +364,7 @@ class Mastodon: | |||
348 | url = '/api/v1/timelines/{0}'.format(timeline) | 364 | url = '/api/v1/timelines/{0}'.format(timeline) |
349 | return self.__api_request('GET', url, params) | 365 | return self.__api_request('GET', url, params) |
350 | 366 | ||
351 | @api_version("1.0.0") | 367 | @api_version("1.0.0", "2.0.0") |
352 | def timeline_home(self, max_id=None, since_id=None, limit=None): | 368 | def timeline_home(self, max_id=None, since_id=None, limit=None): |
353 | """ | 369 | """ |
354 | Fetch the logged-in users home timeline (i.e. followed users and self). | 370 | Fetch the logged-in users home timeline (i.e. followed users and self). |
@@ -358,7 +374,7 @@ class Mastodon: | |||
358 | return self.timeline('home', max_id=max_id, since_id=since_id, | 374 | return self.timeline('home', max_id=max_id, since_id=since_id, |
359 | limit=limit) | 375 | limit=limit) |
360 | 376 | ||
361 | @api_version("1.0.0") | 377 | @api_version("1.0.0", "2.0.0") |
362 | def timeline_local(self, max_id=None, since_id=None, limit=None): | 378 | def timeline_local(self, max_id=None, since_id=None, limit=None): |
363 | """ | 379 | """ |
364 | Fetches the local / instance-wide timeline, not including replies. | 380 | Fetches the local / instance-wide timeline, not including replies. |
@@ -368,7 +384,7 @@ class Mastodon: | |||
368 | return self.timeline('local', max_id=max_id, since_id=since_id, | 384 | return self.timeline('local', max_id=max_id, since_id=since_id, |
369 | limit=limit) | 385 | limit=limit) |
370 | 386 | ||
371 | @api_version("1.0.0") | 387 | @api_version("1.0.0", "2.0.0") |
372 | def timeline_public(self, max_id=None, since_id=None, limit=None): | 388 | def timeline_public(self, max_id=None, since_id=None, limit=None): |
373 | """ | 389 | """ |
374 | Fetches the public / visible-network timeline, not including replies. | 390 | Fetches the public / visible-network timeline, not including replies. |
@@ -378,7 +394,7 @@ class Mastodon: | |||
378 | return self.timeline('public', max_id=max_id, since_id=since_id, | 394 | return self.timeline('public', max_id=max_id, since_id=since_id, |
379 | limit=limit) | 395 | limit=limit) |
380 | 396 | ||
381 | @api_version("1.0.0") | 397 | @api_version("1.0.0", "2.0.0") |
382 | def timeline_hashtag(self, hashtag, local=False, max_id=None, since_id=None, limit=None): | 398 | def timeline_hashtag(self, hashtag, local=False, max_id=None, since_id=None, limit=None): |
383 | """ | 399 | """ |
384 | Fetch a timeline of toots with a given hashtag. The hashtag parameter | 400 | Fetch a timeline of toots with a given hashtag. The hashtag parameter |
@@ -407,7 +423,7 @@ class Mastodon: | |||
407 | 423 | ||
408 | return self.__api_request('GET', url, params) | 424 | return self.__api_request('GET', url, params) |
409 | 425 | ||
410 | @api_version("2.1.0") | 426 | @api_version("2.1.0", "2.1.0") |
411 | def timeline_list(self, id, max_id=None, since_id=None, limit=None): | 427 | def timeline_list(self, id, max_id=None, since_id=None, limit=None): |
412 | """ | 428 | """ |
413 | Fetches a timeline containing all the toots by users in a given list. | 429 | Fetches a timeline containing all the toots by users in a given list. |
@@ -421,7 +437,7 @@ class Mastodon: | |||
421 | ### | 437 | ### |
422 | # Reading data: Statuses | 438 | # Reading data: Statuses |
423 | ### | 439 | ### |
424 | @api_version("1.0.0") | 440 | @api_version("1.0.0", "2.0.0") |
425 | def status(self, id): | 441 | def status(self, id): |
426 | """ | 442 | """ |
427 | Fetch information about a single toot. | 443 | Fetch information about a single toot. |
@@ -434,7 +450,7 @@ class Mastodon: | |||
434 | url = '/api/v1/statuses/{0}'.format(str(id)) | 450 | url = '/api/v1/statuses/{0}'.format(str(id)) |
435 | return self.__api_request('GET', url) | 451 | return self.__api_request('GET', url) |
436 | 452 | ||
437 | @api_version("1.0.0") | 453 | @api_version("1.0.0", "1.0.0") |
438 | def status_card(self, id): | 454 | def status_card(self, id): |
439 | """ | 455 | """ |
440 | Fetch a card associated with a status. A card describes an object (such as an | 456 | Fetch a card associated with a status. A card describes an object (such as an |
@@ -448,7 +464,7 @@ class Mastodon: | |||
448 | url = '/api/v1/statuses/{0}/card'.format(str(id)) | 464 | url = '/api/v1/statuses/{0}/card'.format(str(id)) |
449 | return self.__api_request('GET', url) | 465 | return self.__api_request('GET', url) |
450 | 466 | ||
451 | @api_version("1.0.0") | 467 | @api_version("1.0.0", "1.0.0") |
452 | def status_context(self, id): | 468 | def status_context(self, id): |
453 | """ | 469 | """ |
454 | Fetch information about ancestors and descendants of a toot. | 470 | Fetch information about ancestors and descendants of a toot. |
@@ -461,7 +477,7 @@ class Mastodon: | |||
461 | url = '/api/v1/statuses/{0}/context'.format(str(id)) | 477 | url = '/api/v1/statuses/{0}/context'.format(str(id)) |
462 | return self.__api_request('GET', url) | 478 | return self.__api_request('GET', url) |
463 | 479 | ||
464 | @api_version("1.0.0") | 480 | @api_version("1.0.0", "1.0.0") |
465 | def status_reblogged_by(self, id): | 481 | def status_reblogged_by(self, id): |
466 | """ | 482 | """ |
467 | Fetch a list of users that have reblogged a status. | 483 | Fetch a list of users that have reblogged a status. |
@@ -474,7 +490,7 @@ class Mastodon: | |||
474 | url = '/api/v1/statuses/{0}/reblogged_by'.format(str(id)) | 490 | url = '/api/v1/statuses/{0}/reblogged_by'.format(str(id)) |
475 | return self.__api_request('GET', url) | 491 | return self.__api_request('GET', url) |
476 | 492 | ||
477 | @api_version("1.0.0") | 493 | @api_version("1.0.0", "1.0.0") |
478 | def status_favourited_by(self, id): | 494 | def status_favourited_by(self, id): |
479 | """ | 495 | """ |
480 | Fetch a list of users that have favourited a status. | 496 | Fetch a list of users that have favourited a status. |
@@ -490,7 +506,7 @@ class Mastodon: | |||
490 | ### | 506 | ### |
491 | # Reading data: Notifications | 507 | # Reading data: Notifications |
492 | ### | 508 | ### |
493 | @api_version("1.0.0") | 509 | @api_version("1.0.0", "1.0.0") |
494 | def notifications(self, id=None, max_id=None, since_id=None, limit=None): | 510 | def notifications(self, id=None, max_id=None, since_id=None, limit=None): |
495 | """ | 511 | """ |
496 | Fetch notifications (mentions, favourites, reblogs, follows) for the logged-in | 512 | Fetch notifications (mentions, favourites, reblogs, follows) for the logged-in |
@@ -517,7 +533,7 @@ class Mastodon: | |||
517 | ### | 533 | ### |
518 | # Reading data: Accounts | 534 | # Reading data: Accounts |
519 | ### | 535 | ### |
520 | @api_version("1.0.0") | 536 | @api_version("1.0.0", "1.0.0") |
521 | def account(self, id): | 537 | def account(self, id): |
522 | """ | 538 | """ |
523 | Fetch account information by user `id`. | 539 | Fetch account information by user `id`. |
@@ -528,7 +544,7 @@ class Mastodon: | |||
528 | url = '/api/v1/accounts/{0}'.format(str(id)) | 544 | url = '/api/v1/accounts/{0}'.format(str(id)) |
529 | return self.__api_request('GET', url) | 545 | return self.__api_request('GET', url) |
530 | 546 | ||
531 | @api_version("1.0.0") | 547 | @api_version("1.0.0", "1.5.0") |
532 | def account_verify_credentials(self): | 548 | def account_verify_credentials(self): |
533 | """ | 549 | """ |
534 | Fetch logged-in user's account information. | 550 | Fetch logged-in user's account information. |
@@ -537,14 +553,18 @@ class Mastodon: | |||
537 | """ | 553 | """ |
538 | return self.__api_request('GET', '/api/v1/accounts/verify_credentials') | 554 | return self.__api_request('GET', '/api/v1/accounts/verify_credentials') |
539 | 555 | ||
540 | @api_version("1.0.0") | 556 | @api_version("1.0.0", "2.0.0") |
541 | def account_statuses(self, id, max_id=None, since_id=None, limit=None): | 557 | def account_statuses(self, id, only_media=False, pinned=False, exclude_replies=False, max_id=None, since_id=None, limit=None): |
542 | """ | 558 | """ |
543 | Fetch statuses by user `id`. Same options as `timeline()`_ are permitted. | 559 | Fetch statuses by user `id`. Same options as `timeline()`_ are permitted. |
544 | Returned toots are from the perspective of the logged-in user, i.e. | 560 | Returned toots are from the perspective of the logged-in user, i.e. |
545 | all statuses visible to the logged-in user (including DMs) are | 561 | all statuses visible to the logged-in user (including DMs) are |
546 | included. | 562 | included. |
547 | 563 | ||
564 | If `only_media` is set, return only statuses with media attachments. | ||
565 | If `pinned` is set, return only statuses that have been pinned. | ||
566 | If `exclude_replies` is set, filter out all statuses that are replies. | ||
567 | |||
548 | Returns a list of `toot dicts`_. | 568 | Returns a list of `toot dicts`_. |
549 | """ | 569 | """ |
550 | id = self.__unpack_id(id) | 570 | id = self.__unpack_id(id) |
@@ -558,7 +578,7 @@ class Mastodon: | |||
558 | url = '/api/v1/accounts/{0}/statuses'.format(str(id)) | 578 | url = '/api/v1/accounts/{0}/statuses'.format(str(id)) |
559 | return self.__api_request('GET', url, params) | 579 | return self.__api_request('GET', url, params) |
560 | 580 | ||
561 | @api_version("1.0.0") | 581 | @api_version("1.0.0", "1.0.0") |
562 | def account_following(self, id, max_id=None, since_id=None, limit=None): | 582 | def account_following(self, id, max_id=None, since_id=None, limit=None): |
563 | """ | 583 | """ |
564 | Fetch users the given user is following. | 584 | Fetch users the given user is following. |
@@ -576,7 +596,7 @@ class Mastodon: | |||
576 | url = '/api/v1/accounts/{0}/following'.format(str(id)) | 596 | url = '/api/v1/accounts/{0}/following'.format(str(id)) |
577 | return self.__api_request('GET', url, params) | 597 | return self.__api_request('GET', url, params) |
578 | 598 | ||
579 | @api_version("1.0.0") | 599 | @api_version("1.0.0", "1.0.0") |
580 | def account_followers(self, id, max_id=None, since_id=None, limit=None): | 600 | def account_followers(self, id, max_id=None, since_id=None, limit=None): |
581 | """ | 601 | """ |
582 | Fetch users the given user is followed by. | 602 | Fetch users the given user is followed by. |
@@ -594,7 +614,7 @@ class Mastodon: | |||
594 | url = '/api/v1/accounts/{0}/followers'.format(str(id)) | 614 | url = '/api/v1/accounts/{0}/followers'.format(str(id)) |
595 | return self.__api_request('GET', url, params) | 615 | return self.__api_request('GET', url, params) |
596 | 616 | ||
597 | @api_version("1.0.0") | 617 | @api_version("1.0.0", "1.4.0") |
598 | def account_relationships(self, id): | 618 | def account_relationships(self, id): |
599 | """ | 619 | """ |
600 | Fetch relationship (following, followed_by, blocking, follow requested) of | 620 | Fetch relationship (following, followed_by, blocking, follow requested) of |
@@ -607,7 +627,7 @@ class Mastodon: | |||
607 | return self.__api_request('GET', '/api/v1/accounts/relationships', | 627 | return self.__api_request('GET', '/api/v1/accounts/relationships', |
608 | params) | 628 | params) |
609 | 629 | ||
610 | @api_version("1.0.0") | 630 | @api_version("1.0.0", "1.0.0") |
611 | def account_search(self, q, limit=None): | 631 | def account_search(self, q, limit=None): |
612 | """ | 632 | """ |
613 | Fetch matching accounts. Will lookup an account remotely if the search term is | 633 | Fetch matching accounts. Will lookup an account remotely if the search term is |
@@ -618,7 +638,7 @@ class Mastodon: | |||
618 | params = self.__generate_params(locals()) | 638 | params = self.__generate_params(locals()) |
619 | return self.__api_request('GET', '/api/v1/accounts/search', params) | 639 | return self.__api_request('GET', '/api/v1/accounts/search', params) |
620 | 640 | ||
621 | @api_version("2.1.0") | 641 | @api_version("2.1.0", "2.1.0") |
622 | def account_lists(self, id): | 642 | def account_lists(self, id): |
623 | """ | 643 | """ |
624 | Get all of the logged in users lists which the specified user is | 644 | Get all of the logged in users lists which the specified user is |
@@ -633,7 +653,7 @@ class Mastodon: | |||
633 | ### | 653 | ### |
634 | # Reading data: Searching | 654 | # Reading data: Searching |
635 | ### | 655 | ### |
636 | @api_version("1.1.0") | 656 | @api_version("1.1.0", "2.1.0") |
637 | def search(self, q, resolve=False): | 657 | def search(self, q, resolve=False): |
638 | """ | 658 | """ |
639 | Fetch matching hashtags, accounts and statuses. Will search federated | 659 | Fetch matching hashtags, accounts and statuses. Will search federated |
@@ -647,7 +667,7 @@ class Mastodon: | |||
647 | ### | 667 | ### |
648 | # Reading data: Lists | 668 | # Reading data: Lists |
649 | ### | 669 | ### |
650 | @api_version("2.1.0") | 670 | @api_version("2.1.0", "2.1.0") |
651 | def lists(self): | 671 | def lists(self): |
652 | """ | 672 | """ |
653 | Fetch a list of all the Lists by the logged-in user. | 673 | Fetch a list of all the Lists by the logged-in user. |
@@ -656,7 +676,7 @@ class Mastodon: | |||
656 | """ | 676 | """ |
657 | return self.__api_request('GET', '/api/v1/lists') | 677 | return self.__api_request('GET', '/api/v1/lists') |
658 | 678 | ||
659 | @api_version("2.1.0") | 679 | @api_version("2.1.0", "2.1.0") |
660 | def list(self, id): | 680 | def list(self, id): |
661 | """ | 681 | """ |
662 | Fetch info about a specific list. | 682 | Fetch info about a specific list. |
@@ -666,7 +686,7 @@ class Mastodon: | |||
666 | id = self.__unpack_id(id) | 686 | id = self.__unpack_id(id) |
667 | return self.__api_request('GET', '/api/v1/lists/{0}'.format(id)) | 687 | return self.__api_request('GET', '/api/v1/lists/{0}'.format(id)) |
668 | 688 | ||
669 | @api_version("2.1.0") | 689 | @api_version("2.1.0", "2.1.0") |
670 | def list_accounts(self, id, max_id=None, since_id=None, limit=None): | 690 | def list_accounts(self, id, max_id=None, since_id=None, limit=None): |
671 | """ | 691 | """ |
672 | Get the accounts that are on the given list. A `limit` of 0 can | 692 | Get the accounts that are on the given list. A `limit` of 0 can |
@@ -688,7 +708,7 @@ class Mastodon: | |||
688 | ### | 708 | ### |
689 | # Reading data: Mutes and Blocks | 709 | # Reading data: Mutes and Blocks |
690 | ### | 710 | ### |
691 | @api_version("1.1.0") | 711 | @api_version("1.1.0", "1.1.0") |
692 | def mutes(self, max_id=None, since_id=None, limit=None): | 712 | def mutes(self, max_id=None, since_id=None, limit=None): |
693 | """ | 713 | """ |
694 | Fetch a list of users muted by the logged-in user. | 714 | Fetch a list of users muted by the logged-in user. |
@@ -704,7 +724,7 @@ class Mastodon: | |||
704 | params = self.__generate_params(locals()) | 724 | params = self.__generate_params(locals()) |
705 | return self.__api_request('GET', '/api/v1/mutes', params) | 725 | return self.__api_request('GET', '/api/v1/mutes', params) |
706 | 726 | ||
707 | @api_version("1.0.0") | 727 | @api_version("1.0.0", "1.0.0") |
708 | def blocks(self, max_id=None, since_id=None, limit=None): | 728 | def blocks(self, max_id=None, since_id=None, limit=None): |
709 | """ | 729 | """ |
710 | Fetch a list of users blocked by the logged-in user. | 730 | Fetch a list of users blocked by the logged-in user. |
@@ -723,7 +743,7 @@ class Mastodon: | |||
723 | ### | 743 | ### |
724 | # Reading data: Reports | 744 | # Reading data: Reports |
725 | ### | 745 | ### |
726 | @api_version("1.1.0") | 746 | @api_version("1.1.0", "1.1.0") |
727 | def reports(self): | 747 | def reports(self): |
728 | """ | 748 | """ |
729 | Fetch a list of reports made by the logged-in user. | 749 | Fetch a list of reports made by the logged-in user. |
@@ -738,7 +758,7 @@ class Mastodon: | |||
738 | ### | 758 | ### |
739 | # Reading data: Favourites | 759 | # Reading data: Favourites |
740 | ### | 760 | ### |
741 | @api_version("1.0.0") | 761 | @api_version("1.0.0", "2.0.0") |
742 | def favourites(self, max_id=None, since_id=None, limit=None): | 762 | def favourites(self, max_id=None, since_id=None, limit=None): |
743 | """ | 763 | """ |
744 | Fetch the logged-in user's favourited statuses. | 764 | Fetch the logged-in user's favourited statuses. |
@@ -757,7 +777,7 @@ class Mastodon: | |||
757 | ### | 777 | ### |
758 | # Reading data: Follow requests | 778 | # Reading data: Follow requests |
759 | ### | 779 | ### |
760 | @api_version("1.0.0") | 780 | @api_version("1.0.0", "1.0.0") |
761 | def follow_requests(self, max_id=None, since_id=None, limit=None): | 781 | def follow_requests(self, max_id=None, since_id=None, limit=None): |
762 | """ | 782 | """ |
763 | Fetch the logged-in user's incoming follow requests. | 783 | Fetch the logged-in user's incoming follow requests. |
@@ -776,7 +796,7 @@ class Mastodon: | |||
776 | ### | 796 | ### |
777 | # Reading data: Domain blocks | 797 | # Reading data: Domain blocks |
778 | ### | 798 | ### |
779 | @api_version("1.4.0") | 799 | @api_version("1.4.0", "1.4.0") |
780 | def domain_blocks(self, max_id=None, since_id=None, limit=None): | 800 | def domain_blocks(self, max_id=None, since_id=None, limit=None): |
781 | """ | 801 | """ |
782 | Fetch the logged-in user's blocked domains. | 802 | Fetch the logged-in user's blocked domains. |
@@ -795,7 +815,7 @@ class Mastodon: | |||
795 | ### | 815 | ### |
796 | # Reading data: Emoji | 816 | # Reading data: Emoji |
797 | ### | 817 | ### |
798 | @api_version("2.1.0") | 818 | @api_version("2.1.0", "2.1.0") |
799 | def custom_emojis(self): | 819 | def custom_emojis(self): |
800 | """ | 820 | """ |
801 | Fetch the list of custom emoji the instance has installed. | 821 | Fetch the list of custom emoji the instance has installed. |
@@ -810,7 +830,7 @@ class Mastodon: | |||
810 | ### | 830 | ### |
811 | # Writing data: Statuses | 831 | # Writing data: Statuses |
812 | ### | 832 | ### |
813 | @api_version("1.0.0") | 833 | @api_version("1.0.0", "2.0.0") |
814 | def status_post(self, status, in_reply_to_id=None, media_ids=None, | 834 | def status_post(self, status, in_reply_to_id=None, media_ids=None, |
815 | sensitive=False, visibility='', spoiler_text=None): | 835 | sensitive=False, visibility='', spoiler_text=None): |
816 | """ | 836 | """ |
@@ -872,7 +892,7 @@ class Mastodon: | |||
872 | params = self.__generate_params(params_initial) | 892 | params = self.__generate_params(params_initial) |
873 | return self.__api_request('POST', '/api/v1/statuses', params) | 893 | return self.__api_request('POST', '/api/v1/statuses', params) |
874 | 894 | ||
875 | @api_version("1.0.0") | 895 | @api_version("1.0.0", "2.0.0") |
876 | def toot(self, status): | 896 | def toot(self, status): |
877 | """ | 897 | """ |
878 | Synonym for `status_post()`_ that only takes the status text as input. | 898 | Synonym for `status_post()`_ that only takes the status text as input. |
@@ -883,7 +903,7 @@ class Mastodon: | |||
883 | """ | 903 | """ |
884 | return self.status_post(status) | 904 | return self.status_post(status) |
885 | 905 | ||
886 | @api_version("1.0.0") | 906 | @api_version("1.0.0", "1.0.0") |
887 | def status_delete(self, id): | 907 | def status_delete(self, id): |
888 | """ | 908 | """ |
889 | Delete a status | 909 | Delete a status |
@@ -892,7 +912,7 @@ class Mastodon: | |||
892 | url = '/api/v1/statuses/{0}'.format(str(id)) | 912 | url = '/api/v1/statuses/{0}'.format(str(id)) |
893 | self.__api_request('DELETE', url) | 913 | self.__api_request('DELETE', url) |
894 | 914 | ||
895 | @api_version("1.0.0") | 915 | @api_version("1.0.0", "2.0.0") |
896 | def status_reblog(self, id): | 916 | def status_reblog(self, id): |
897 | """ | 917 | """ |
898 | Reblog a status. | 918 | Reblog a status. |
@@ -903,7 +923,7 @@ class Mastodon: | |||
903 | url = '/api/v1/statuses/{0}/reblog'.format(str(id)) | 923 | url = '/api/v1/statuses/{0}/reblog'.format(str(id)) |
904 | return self.__api_request('POST', url) | 924 | return self.__api_request('POST', url) |
905 | 925 | ||
906 | @api_version("1.0.0") | 926 | @api_version("1.0.0", "2.0.0") |
907 | def status_unreblog(self, id): | 927 | def status_unreblog(self, id): |
908 | """ | 928 | """ |
909 | Un-reblog a status. | 929 | Un-reblog a status. |
@@ -914,7 +934,7 @@ class Mastodon: | |||
914 | url = '/api/v1/statuses/{0}/unreblog'.format(str(id)) | 934 | url = '/api/v1/statuses/{0}/unreblog'.format(str(id)) |
915 | return self.__api_request('POST', url) | 935 | return self.__api_request('POST', url) |
916 | 936 | ||
917 | @api_version("1.0.0") | 937 | @api_version("1.0.0", "2.0.0") |
918 | def status_favourite(self, id): | 938 | def status_favourite(self, id): |
919 | """ | 939 | """ |
920 | Favourite a status. | 940 | Favourite a status. |
@@ -925,7 +945,7 @@ class Mastodon: | |||
925 | url = '/api/v1/statuses/{0}/favourite'.format(str(id)) | 945 | url = '/api/v1/statuses/{0}/favourite'.format(str(id)) |
926 | return self.__api_request('POST', url) | 946 | return self.__api_request('POST', url) |
927 | 947 | ||
928 | @api_version("1.0.0") | 948 | @api_version("1.0.0", "2.0.0") |
929 | def status_unfavourite(self, id): | 949 | def status_unfavourite(self, id): |
930 | """ | 950 | """ |
931 | Un-favourite a status. | 951 | Un-favourite a status. |
@@ -936,7 +956,7 @@ class Mastodon: | |||
936 | url = '/api/v1/statuses/{0}/unfavourite'.format(str(id)) | 956 | url = '/api/v1/statuses/{0}/unfavourite'.format(str(id)) |
937 | return self.__api_request('POST', url) | 957 | return self.__api_request('POST', url) |
938 | 958 | ||
939 | @api_version("1.4.0") | 959 | @api_version("1.4.0", "2.0.0") |
940 | def status_mute(self, id): | 960 | def status_mute(self, id): |
941 | """ | 961 | """ |
942 | Mute notifications for a status. | 962 | Mute notifications for a status. |
@@ -947,7 +967,7 @@ class Mastodon: | |||
947 | url = '/api/v1/statuses/{0}/mute'.format(str(id)) | 967 | url = '/api/v1/statuses/{0}/mute'.format(str(id)) |
948 | return self.__api_request('POST', url) | 968 | return self.__api_request('POST', url) |
949 | 969 | ||
950 | @api_version("1.4.0") | 970 | @api_version("1.4.0", "2.0.0") |
951 | def status_unmute(self, id): | 971 | def status_unmute(self, id): |
952 | """ | 972 | """ |
953 | Unmute notifications for a status. | 973 | Unmute notifications for a status. |
@@ -961,7 +981,7 @@ class Mastodon: | |||
961 | ### | 981 | ### |
962 | # Writing data: Notifications | 982 | # Writing data: Notifications |
963 | ### | 983 | ### |
964 | @api_version("1.0.0") | 984 | @api_version("1.0.0", "1.0.0") |
965 | def notifications_clear(self): | 985 | def notifications_clear(self): |
966 | """ | 986 | """ |
967 | Clear out a users notifications | 987 | Clear out a users notifications |
@@ -969,7 +989,7 @@ class Mastodon: | |||
969 | self.__api_request('POST', '/api/v1/notifications/clear') | 989 | self.__api_request('POST', '/api/v1/notifications/clear') |
970 | 990 | ||
971 | 991 | ||
972 | @api_version("1.3.0") | 992 | @api_version("1.3.0", "1.3.0") |
973 | def notifications_dismiss(self, id): | 993 | def notifications_dismiss(self, id): |
974 | """ | 994 | """ |
975 | Deletes a single notification | 995 | Deletes a single notification |
@@ -981,7 +1001,7 @@ class Mastodon: | |||
981 | ### | 1001 | ### |
982 | # Writing data: Accounts | 1002 | # Writing data: Accounts |
983 | ### | 1003 | ### |
984 | @api_version("1.0.0") | 1004 | @api_version("1.0.0", "1.4.0") |
985 | def account_follow(self, id): | 1005 | def account_follow(self, id): |
986 | """ | 1006 | """ |
987 | Follow a user. | 1007 | Follow a user. |
@@ -992,7 +1012,7 @@ class Mastodon: | |||
992 | url = '/api/v1/accounts/{0}/follow'.format(str(id)) | 1012 | url = '/api/v1/accounts/{0}/follow'.format(str(id)) |
993 | return self.__api_request('POST', url) | 1013 | return self.__api_request('POST', url) |
994 | 1014 | ||
995 | @api_version("1.0.0") | 1015 | @api_version("1.0.0", "1.0.0") |
996 | def follows(self, uri): | 1016 | def follows(self, uri): |
997 | """ | 1017 | """ |
998 | Follow a remote user by uri (username@domain). | 1018 | Follow a remote user by uri (username@domain). |
@@ -1002,7 +1022,7 @@ class Mastodon: | |||
1002 | params = self.__generate_params(locals()) | 1022 | params = self.__generate_params(locals()) |
1003 | return self.__api_request('POST', '/api/v1/follows', params) | 1023 | return self.__api_request('POST', '/api/v1/follows', params) |
1004 | 1024 | ||
1005 | @api_version("1.0.0") | 1025 | @api_version("1.0.0", "1.4.0") |
1006 | def account_unfollow(self, id): | 1026 | def account_unfollow(self, id): |
1007 | """ | 1027 | """ |
1008 | Unfollow a user. | 1028 | Unfollow a user. |
@@ -1013,7 +1033,7 @@ class Mastodon: | |||
1013 | url = '/api/v1/accounts/{0}/unfollow'.format(str(id)) | 1033 | url = '/api/v1/accounts/{0}/unfollow'.format(str(id)) |
1014 | return self.__api_request('POST', url) | 1034 | return self.__api_request('POST', url) |
1015 | 1035 | ||
1016 | @api_version("1.0.0") | 1036 | @api_version("1.0.0", "1.4.0") |
1017 | def account_block(self, id): | 1037 | def account_block(self, id): |
1018 | """ | 1038 | """ |
1019 | Block a user. | 1039 | Block a user. |
@@ -1024,7 +1044,7 @@ class Mastodon: | |||
1024 | url = '/api/v1/accounts/{0}/block'.format(str(id)) | 1044 | url = '/api/v1/accounts/{0}/block'.format(str(id)) |
1025 | return self.__api_request('POST', url) | 1045 | return self.__api_request('POST', url) |
1026 | 1046 | ||
1027 | @api_version("1.0.0") | 1047 | @api_version("1.0.0", "1.4.0") |
1028 | def account_unblock(self, id): | 1048 | def account_unblock(self, id): |
1029 | """ | 1049 | """ |
1030 | Unblock a user. | 1050 | Unblock a user. |
@@ -1035,7 +1055,7 @@ class Mastodon: | |||
1035 | url = '/api/v1/accounts/{0}/unblock'.format(str(id)) | 1055 | url = '/api/v1/accounts/{0}/unblock'.format(str(id)) |
1036 | return self.__api_request('POST', url) | 1056 | return self.__api_request('POST', url) |
1037 | 1057 | ||
1038 | @api_version("1.1.0") | 1058 | @api_version("1.1.0", "1.4.0") |
1039 | def account_mute(self, id): | 1059 | def account_mute(self, id): |
1040 | """ | 1060 | """ |
1041 | Mute a user. | 1061 | Mute a user. |
@@ -1046,7 +1066,7 @@ class Mastodon: | |||
1046 | url = '/api/v1/accounts/{0}/mute'.format(str(id)) | 1066 | url = '/api/v1/accounts/{0}/mute'.format(str(id)) |
1047 | return self.__api_request('POST', url) | 1067 | return self.__api_request('POST', url) |
1048 | 1068 | ||
1049 | @api_version("1.1.0") | 1069 | @api_version("1.1.0", "1.4.0") |
1050 | def account_unmute(self, id): | 1070 | def account_unmute(self, id): |
1051 | """ | 1071 | """ |
1052 | Unmute a user. | 1072 | Unmute a user. |
@@ -1057,7 +1077,7 @@ class Mastodon: | |||
1057 | url = '/api/v1/accounts/{0}/unmute'.format(str(id)) | 1077 | url = '/api/v1/accounts/{0}/unmute'.format(str(id)) |
1058 | return self.__api_request('POST', url) | 1078 | return self.__api_request('POST', url) |
1059 | 1079 | ||
1060 | @api_version("1.1.1") | 1080 | @api_version("1.1.1", "1.6.0") |
1061 | def account_update_credentials(self, display_name=None, note=None, | 1081 | def account_update_credentials(self, display_name=None, note=None, |
1062 | avatar=None, header=None): | 1082 | avatar=None, header=None): |
1063 | """ | 1083 | """ |
@@ -1076,7 +1096,7 @@ class Mastodon: | |||
1076 | ### | 1096 | ### |
1077 | # Writing data: Lists | 1097 | # Writing data: Lists |
1078 | ### | 1098 | ### |
1079 | @api_version("2.1.0") | 1099 | @api_version("2.1.0", "2.1.0") |
1080 | def list_create(self, title): | 1100 | def list_create(self, title): |
1081 | """ | 1101 | """ |
1082 | Create a new list with the given `title`. | 1102 | Create a new list with the given `title`. |
@@ -1086,7 +1106,7 @@ class Mastodon: | |||
1086 | params = self.__generate_params(locals()) | 1106 | params = self.__generate_params(locals()) |
1087 | return self.__api_request('POST', '/api/v1/lists', params) | 1107 | return self.__api_request('POST', '/api/v1/lists', params) |
1088 | 1108 | ||
1089 | @api_version("2.1.0") | 1109 | @api_version("2.1.0", "2.1.0") |
1090 | def list_update(self, id, title): | 1110 | def list_update(self, id, title): |
1091 | """ | 1111 | """ |
1092 | Update info about a list, where "info" is really the lists `title`. | 1112 | Update info about a list, where "info" is really the lists `title`. |
@@ -1097,7 +1117,7 @@ class Mastodon: | |||
1097 | params = self.__generate_params(locals(), ['id']) | 1117 | params = self.__generate_params(locals(), ['id']) |
1098 | return self.__api_request('PUT', '/api/v1/lists/{0}'.format(id), params) | 1118 | return self.__api_request('PUT', '/api/v1/lists/{0}'.format(id), params) |
1099 | 1119 | ||
1100 | @api_version("2.1.0") | 1120 | @api_version("2.1.0", "2.1.0") |
1101 | def list_delete(self, id): | 1121 | def list_delete(self, id): |
1102 | """ | 1122 | """ |
1103 | Delete a list. | 1123 | Delete a list. |
@@ -1105,7 +1125,7 @@ class Mastodon: | |||
1105 | id = self.__unpack_id(id) | 1125 | id = self.__unpack_id(id) |
1106 | self.__api_request('DELETE', '/api/v1/lists/{0}'.format(id)) | 1126 | self.__api_request('DELETE', '/api/v1/lists/{0}'.format(id)) |
1107 | 1127 | ||
1108 | @api_version("2.1.0") | 1128 | @api_version("2.1.0", "2.1.0") |
1109 | def list_accounts_add(self, id, account_ids): | 1129 | def list_accounts_add(self, id, account_ids): |
1110 | """ | 1130 | """ |
1111 | Add the account(s) given in `account_ids` to the list. | 1131 | Add the account(s) given in `account_ids` to the list. |
@@ -1119,7 +1139,7 @@ class Mastodon: | |||
1119 | params = self.__generate_params(locals(), ['id']) | 1139 | params = self.__generate_params(locals(), ['id']) |
1120 | self.__api_request('POST', '/api/v1/lists/{0}/accounts'.format(id), params) | 1140 | self.__api_request('POST', '/api/v1/lists/{0}/accounts'.format(id), params) |
1121 | 1141 | ||
1122 | @api_version("2.1.0") | 1142 | @api_version("2.1.0", "2.1.0") |
1123 | def list_accounts_delete(self, id, account_ids): | 1143 | def list_accounts_delete(self, id, account_ids): |
1124 | """ | 1144 | """ |
1125 | Remove the account(s) given in `account_ids` from the list. | 1145 | Remove the account(s) given in `account_ids` from the list. |
@@ -1136,7 +1156,7 @@ class Mastodon: | |||
1136 | ### | 1156 | ### |
1137 | # Writing data: Reports | 1157 | # Writing data: Reports |
1138 | ### | 1158 | ### |
1139 | @api_version("1.1.0") | 1159 | @api_version("1.1.0", "1.1.0") |
1140 | def report(self, account_id, status_ids, comment): | 1160 | def report(self, account_id, status_ids, comment): |
1141 | """ | 1161 | """ |
1142 | Report statuses to the instances administrators. | 1162 | Report statuses to the instances administrators. |
@@ -1157,7 +1177,7 @@ class Mastodon: | |||
1157 | ### | 1177 | ### |
1158 | # Writing data: Follow requests | 1178 | # Writing data: Follow requests |
1159 | ### | 1179 | ### |
1160 | @api_version("1.0.0") | 1180 | @api_version("1.0.0", "1.0.0") |
1161 | def follow_request_authorize(self, id): | 1181 | def follow_request_authorize(self, id): |
1162 | """ | 1182 | """ |
1163 | Accept an incoming follow request. | 1183 | Accept an incoming follow request. |
@@ -1166,7 +1186,7 @@ class Mastodon: | |||
1166 | url = '/api/v1/follow_requests/{0}/authorize'.format(str(id)) | 1186 | url = '/api/v1/follow_requests/{0}/authorize'.format(str(id)) |
1167 | self.__api_request('POST', url) | 1187 | self.__api_request('POST', url) |
1168 | 1188 | ||
1169 | @api_version("1.0.0") | 1189 | @api_version("1.0.0", "1.0.0") |
1170 | def follow_request_reject(self, id): | 1190 | def follow_request_reject(self, id): |
1171 | """ | 1191 | """ |
1172 | Reject an incoming follow request. | 1192 | Reject an incoming follow request. |
@@ -1178,7 +1198,7 @@ class Mastodon: | |||
1178 | ### | 1198 | ### |
1179 | # Writing data: Media | 1199 | # Writing data: Media |
1180 | ### | 1200 | ### |
1181 | @api_version("1.0.0") | 1201 | @api_version("1.0.0", "2.0.0") |
1182 | def media_post(self, media_file, mime_type=None, description=None): | 1202 | def media_post(self, media_file, mime_type=None, description=None): |
1183 | """ | 1203 | """ |
1184 | Post an image. `media_file` can either be image data or | 1204 | Post an image. `media_file` can either be image data or |
@@ -1213,7 +1233,7 @@ class Mastodon: | |||
1213 | ### | 1233 | ### |
1214 | # Writing data: Domain blocks | 1234 | # Writing data: Domain blocks |
1215 | ### | 1235 | ### |
1216 | @api_version("1.4.0") | 1236 | @api_version("1.4.0", "1.4.0") |
1217 | def domain_block(self, domain=None): | 1237 | def domain_block(self, domain=None): |
1218 | """ | 1238 | """ |
1219 | Add a block for all statuses originating from the specified domain for the logged-in user. | 1239 | Add a block for all statuses originating from the specified domain for the logged-in user. |
@@ -1221,7 +1241,7 @@ class Mastodon: | |||
1221 | params = self.__generate_params(locals()) | 1241 | params = self.__generate_params(locals()) |
1222 | self.__api_request('POST', '/api/v1/domain_blocks', params) | 1242 | self.__api_request('POST', '/api/v1/domain_blocks', params) |
1223 | 1243 | ||
1224 | @api_version("1.4.0") | 1244 | @api_version("1.4.0", "1.4.0") |
1225 | def domain_unblock(self, domain=None): | 1245 | def domain_unblock(self, domain=None): |
1226 | """ | 1246 | """ |
1227 | Remove a domain block for the logged-in user. | 1247 | Remove a domain block for the logged-in user. |
@@ -1302,7 +1322,7 @@ class Mastodon: | |||
1302 | ### | 1322 | ### |
1303 | # Streaming | 1323 | # Streaming |
1304 | ### | 1324 | ### |
1305 | @api_version("1.1.0") | 1325 | @api_version("1.1.0", "1.4.2") |
1306 | def stream_user(self, listener, async=False): | 1326 | def stream_user(self, listener, async=False): |
1307 | """ | 1327 | """ |
1308 | Streams events that are relevant to the authorized user, i.e. home | 1328 | Streams events that are relevant to the authorized user, i.e. home |
@@ -1310,21 +1330,21 @@ class Mastodon: | |||
1310 | """ | 1330 | """ |
1311 | return self.__stream('/api/v1/streaming/user', listener, async=async) | 1331 | return self.__stream('/api/v1/streaming/user', listener, async=async) |
1312 | 1332 | ||
1313 | @api_version("1.1.0") | 1333 | @api_version("1.1.0", "1.4.2") |
1314 | def stream_public(self, listener, async=False): | 1334 | def stream_public(self, listener, async=False): |
1315 | """ | 1335 | """ |
1316 | Streams public events. | 1336 | Streams public events. |
1317 | """ | 1337 | """ |
1318 | return self.__stream('/api/v1/streaming/public', listener, async=async) | 1338 | return self.__stream('/api/v1/streaming/public', listener, async=async) |
1319 | 1339 | ||
1320 | @api_version("1.1.0") | 1340 | @api_version("1.1.0", "1.4.2") |
1321 | def stream_local(self, listener, async=False): | 1341 | def stream_local(self, listener, async=False): |
1322 | """ | 1342 | """ |
1323 | Streams local public events. | 1343 | Streams local public events. |
1324 | """ | 1344 | """ |
1325 | return self.__stream('/api/v1/streaming/public/local', listener, async=async) | 1345 | return self.__stream('/api/v1/streaming/public/local', listener, async=async) |
1326 | 1346 | ||
1327 | @api_version("1.1.0") | 1347 | @api_version("1.1.0", "1.4.2") |
1328 | def stream_hashtag(self, tag, listener, async=False): | 1348 | def stream_hashtag(self, tag, listener, async=False): |
1329 | """ | 1349 | """ |
1330 | Stream for all public statuses for the hashtag 'tag' seen by the connected | 1350 | Stream for all public statuses for the hashtag 'tag' seen by the connected |
@@ -1334,7 +1354,7 @@ class Mastodon: | |||
1334 | raise MastodonIllegalArgumentError("Tag parameter should omit leading #") | 1354 | raise MastodonIllegalArgumentError("Tag parameter should omit leading #") |
1335 | return self.__stream("/api/v1/streaming/hashtag?tag={}".format(tag), listener) | 1355 | return self.__stream("/api/v1/streaming/hashtag?tag={}".format(tag), listener) |
1336 | 1356 | ||
1337 | @api_version("2.1.0") | 1357 | @api_version("2.1.0", "2.1.0") |
1338 | def stream_list(self, id, listener, async=False): | 1358 | def stream_list(self, id, listener, async=False): |
1339 | """ | 1359 | """ |
1340 | Stream events for the current user, restricted to accounts on the given | 1360 | Stream events for the current user, restricted to accounts on the given |
@@ -1706,7 +1726,6 @@ class Mastodon: | |||
1706 | class MastodonError(Exception): | 1726 | class MastodonError(Exception): |
1707 | """Base class for Mastodon.py exceptions""" | 1727 | """Base class for Mastodon.py exceptions""" |
1708 | 1728 | ||
1709 | |||
1710 | class MastodonVersionError(MastodonError): | 1729 | class MastodonVersionError(MastodonError): |
1711 | """Raised when a function is called that the version of Mastodon for which | 1730 | """Raised when a function is called that the version of Mastodon for which |
1712 | Mastodon.py was instantiated does not support""" | 1731 | Mastodon.py was instantiated does not support""" |