aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mastodon')
-rw-r--r--mastodon/Mastodon.py106
1 files changed, 63 insertions, 43 deletions
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py
index 12a054a..ae560c5 100644
--- a/mastodon/Mastodon.py
+++ b/mastodon/Mastodon.py
@@ -605,8 +605,7 @@ class Mastodon:
605 params['scope'] = " ".join(scopes) 605 params['scope'] = " ".join(scopes)
606 606
607 try: 607 try:
608 response = self.__api_request( 608 response = self.__api_request('POST', '/oauth/token', params, do_ratelimiting=False)
609 'POST', '/oauth/token', params, do_ratelimiting=False)
610 self.access_token = response['access_token'] 609 self.access_token = response['access_token']
611 self.__set_refresh_token(response.get('refresh_token')) 610 self.__set_refresh_token(response.get('refresh_token'))
612 self.__set_token_expired(int(response.get('expires_in', 0))) 611 self.__set_token_expired(int(response.get('expires_in', 0)))
@@ -658,8 +657,8 @@ class Mastodon:
658 self.access_token = None 657 self.access_token = None
659 self.__logged_in_id = None 658 self.__logged_in_id = None
660 659
661 @api_version("2.7.0", "2.7.0", "2.7.0") 660 @api_version("2.7.0", "2.7.0", "3.4.0")
662 def create_account(self, username, password, email, agreement=False, reason=None, locale="en", scopes=__DEFAULT_SCOPES, to_file=None): 661 def create_account(self, username, password, email, agreement=False, reason=None, locale="en", scopes=__DEFAULT_SCOPES, to_file=None, return_detailed_error=False):
663 """ 662 """
664 Creates a new user account with the given username, password and email. "agreement" 663 Creates a new user account with the given username, password and email. "agreement"
665 must be set to true (after showing the user the instance's user agreement and having 664 must be set to true (after showing the user the instance's user agreement and having
@@ -674,6 +673,26 @@ class Mastodon:
674 Returns an access token (just like log_in), which it can also persist to to_file, 673 Returns an access token (just like log_in), which it can also persist to to_file,
675 and sets it internally so that the user is now logged in. Note that this token 674 and sets it internally so that the user is now logged in. Note that this token
676 can only be used after the user has confirmed their email. 675 can only be used after the user has confirmed their email.
676
677 By default, the function will throw if the account could not be created. Alternately,
678 when `return_detailed_error` is passed, Mastodon.py will return the detailed error
679 response that the API provides (Starting from version 3.4.0 - not checked here) as an dict with
680 error details as the second return value and the token returned as `None` in case of error.
681 The dict will contain a text `error` values as well as a `details` value which is a dict with
682 one optional key for each potential field (`username`, `password`, `email` and `agreement`),
683 each if present containing a dict with an `error` category and free text `description`.
684 Valid error categories are:
685
686 * ERR_BLOCKED - When e-mail provider is not allowed
687 * ERR_UNREACHABLE - When e-mail address does not resolve to any IP via DNS (MX, A, AAAA)
688 * ERR_TAKEN - When username or e-mail are already taken
689 * ERR_RESERVED - When a username is reserved, e.g. "webmaster" or "admin"
690 * ERR_ACCEPTED - When agreement has not been accepted
691 * ERR_BLANK - When a required attribute is blank
692 * ERR_INVALID - When an attribute is malformed, e.g. wrong characters or invalid e-mail address
693 * ERR_TOO_LONG - When an attribute is over the character limit
694 * ERR_TOO_SHORT - When an attribute is under the character requirement
695 * ERR_INCLUSION - When an attribute is not one of the allowed values, e.g. unsupported locale
677 """ 696 """
678 params = self.__generate_params(locals(), ['to_file', 'scopes']) 697 params = self.__generate_params(locals(), ['to_file', 'scopes'])
679 params['client_id'] = self.client_id 698 params['client_id'] = self.client_id
@@ -690,8 +709,7 @@ class Mastodon:
690 oauth_params['client_secret'] = self.client_secret 709 oauth_params['client_secret'] = self.client_secret
691 oauth_params['grant_type'] = 'client_credentials' 710 oauth_params['grant_type'] = 'client_credentials'
692 711
693 response = self.__api_request( 712 response = self.__api_request('POST', '/oauth/token', oauth_params, do_ratelimiting=False)
694 'POST', '/oauth/token', oauth_params, do_ratelimiting=False)
695 temp_access_token = response['access_token'] 713 temp_access_token = response['access_token']
696 except Exception as e: 714 except Exception as e:
697 raise MastodonIllegalArgumentError( 715 raise MastodonIllegalArgumentError(
@@ -699,13 +717,16 @@ class Mastodon:
699 717
700 # Step 2: Use that to create a user 718 # Step 2: Use that to create a user
701 try: 719 try:
702 response = self.__api_request('POST', '/api/v1/accounts', params, do_ratelimiting=False, 720 response = self.__api_request('POST', '/api/v1/accounts', params, do_ratelimiting=False, access_token_override=temp_access_token, skip_error_check=True)
703 access_token_override=temp_access_token) 721 if "error" in response:
722 if return_detailed_error:
723 return None, response
724 raise MastodonIllegalArgumentError('Invalid request: %s' % e)
704 self.access_token = response['access_token'] 725 self.access_token = response['access_token']
705 self.__set_refresh_token(response.get('refresh_token')) 726 self.__set_refresh_token(response.get('refresh_token'))
706 self.__set_token_expired(int(response.get('expires_in', 0))) 727 self.__set_token_expired(int(response.get('expires_in', 0)))
707 except Exception as e: 728 except Exception as e:
708 raise MastodonIllegalArgumentError('Invalid request: %s' % e) 729 raise MastodonIllegalArgumentError('Invalid request')
709 730
710 # Step 3: Check scopes, persist, et cetera 731 # Step 3: Check scopes, persist, et cetera
711 received_scopes = response["scope"].split(" ") 732 received_scopes = response["scope"].split(" ")
@@ -714,8 +735,7 @@ class Mastodon:
714 received_scopes += self.__SCOPE_SETS[scope_set] 735 received_scopes += self.__SCOPE_SETS[scope_set]
715 736
716 if not set(scopes) <= set(received_scopes): 737 if not set(scopes) <= set(received_scopes):
717 raise MastodonAPIError( 738 raise MastodonAPIError('Granted scopes "' + " ".join(received_scopes) + '" do not contain all of the requested scopes "' + " ".join(scopes) + '".')
718 'Granted scopes "' + " ".join(received_scopes) + '" do not contain all of the requested scopes "' + " ".join(scopes) + '".')
719 739
720 if to_file is not None: 740 if to_file is not None:
721 with open(to_file, 'w') as token_file: 741 with open(to_file, 'w') as token_file:
@@ -724,7 +744,10 @@ class Mastodon:
724 744
725 self.__logged_in_id = None 745 self.__logged_in_id = None
726 746
727 return response['access_token'] 747 if return_detailed_error:
748 return response['access_token'], {}
749 else:
750 return response['access_token']
728 751
729 @api_version("3.4.0", "3.4.0", "3.4.0") 752 @api_version("3.4.0", "3.4.0", "3.4.0")
730 def email_resend_confirmation(self): 753 def email_resend_confirmation(self):
@@ -2775,7 +2798,7 @@ class Mastodon:
2775 """ 2798 """
2776 if not policy in ['all', 'none', 'follower', 'followed']: 2799 if not policy in ['all', 'none', 'follower', 'followed']:
2777 raise MastodonIllegalArgumentError("Valid values for policy are 'all', 'none', 'follower' or 'followed'.") 2800 raise MastodonIllegalArgumentError("Valid values for policy are 'all', 'none', 'follower' or 'followed'.")
2778 2801
2779 endpoint = Mastodon.__protocolize(endpoint) 2802 endpoint = Mastodon.__protocolize(endpoint)
2780 2803
2781 push_pubkey_b64 = base64.b64encode(encrypt_params['pubkey']) 2804 push_pubkey_b64 = base64.b64encode(encrypt_params['pubkey'])
@@ -3506,7 +3529,7 @@ class Mastodon:
3506 isotime = isotime[:-2] + ":" + isotime[-2:] 3529 isotime = isotime[:-2] + ":" + isotime[-2:]
3507 return isotime 3530 return isotime
3508 3531
3509 def __api_request(self, method, endpoint, params={}, files={}, headers={}, access_token_override=None, base_url_override=None, do_ratelimiting=True, use_json=False, parse=True, return_response_object=False): 3532 def __api_request(self, method, endpoint, params={}, files={}, headers={}, access_token_override=None, base_url_override=None, do_ratelimiting=True, use_json=False, parse=True, return_response_object=False, skip_error_check=False):
3510 """ 3533 """
3511 Internal API request helper. 3534 Internal API request helper.
3512 """ 3535 """
@@ -3657,35 +3680,32 @@ class Mastodon:
3657 time.sleep(to_next) 3680 time.sleep(to_next)
3658 request_complete = False 3681 request_complete = False
3659 continue 3682 continue
3683
3684 if skip_error_check == False:
3685 if response_object.status_code == 404:
3686 ex_type = MastodonNotFoundError
3687 if not error_msg:
3688 error_msg = 'Endpoint not found.'
3689 # this is for compatibility with older versions
3690 # which raised MastodonAPIError('Endpoint not found.')
3691 # on any 404
3692 elif response_object.status_code == 401:
3693 ex_type = MastodonUnauthorizedError
3694 elif response_object.status_code == 500:
3695 ex_type = MastodonInternalServerError
3696 elif response_object.status_code == 502:
3697 ex_type = MastodonBadGatewayError
3698 elif response_object.status_code == 503:
3699 ex_type = MastodonServiceUnavailableError
3700 elif response_object.status_code == 504:
3701 ex_type = MastodonGatewayTimeoutError
3702 elif response_object.status_code >= 500 and \
3703 response_object.status_code <= 511:
3704 ex_type = MastodonServerError
3705 else:
3706 ex_type = MastodonAPIError
3660 3707
3661 if response_object.status_code == 404: 3708 raise ex_type('Mastodon API returned error', response_object.status_code, response_object.reason, error_msg)
3662 ex_type = MastodonNotFoundError
3663 if not error_msg:
3664 error_msg = 'Endpoint not found.'
3665 # this is for compatibility with older versions
3666 # which raised MastodonAPIError('Endpoint not found.')
3667 # on any 404
3668 elif response_object.status_code == 401:
3669 ex_type = MastodonUnauthorizedError
3670 elif response_object.status_code == 500:
3671 ex_type = MastodonInternalServerError
3672 elif response_object.status_code == 502:
3673 ex_type = MastodonBadGatewayError
3674 elif response_object.status_code == 503:
3675 ex_type = MastodonServiceUnavailableError
3676 elif response_object.status_code == 504:
3677 ex_type = MastodonGatewayTimeoutError
3678 elif response_object.status_code >= 500 and \
3679 response_object.status_code <= 511:
3680 ex_type = MastodonServerError
3681 else:
3682 ex_type = MastodonAPIError
3683
3684 raise ex_type(
3685 'Mastodon API returned error',
3686 response_object.status_code,
3687 response_object.reason,
3688 error_msg)
3689 3709
3690 if return_response_object: 3710 if return_response_object:
3691 return response_object 3711 return response_object
Powered by cgit v1.2.3 (git 2.41.0)