def check_user_exists(self): """ Check that the username exists on the site. @see: U{https://www.mediawiki.org/wiki/API:Users} @raises pywikibot.exceptions.NoUsernameError: Username doesn't exist in user list. """ # convert any Special:BotPassword usernames to main account equivalent main_username = self.username if '@' in self.username: warn('When using BotPasswords it is recommended that you store ' 'your login credentials in a password_file instead. See ' '{}/BotPasswords for instructions and more information.'. format(__url__)) main_username = self.username.partition('@')[0] try: data = self.site.allusers(start=main_username, total=1) user = next(iter(data)) except APIError as e: if e.code == 'readapidenied': pywikibot.warning( "Could not check user '{}' exists on {}".format( main_username, self.site)) return raise if user['name'] != main_username: # Report the same error as server error code NotExists raise NoUsernameError("Username '{}' does not exist on {}".format( main_username, self.site))
def login(self, retry=False, autocreate=False) -> bool: """ Attempt to log into the server. @see: U{https://www.mediawiki.org/wiki/API:Login} @param retry: infinitely retry if the API returns an unknown error @type retry: bool @param autocreate: if true, allow auto-creation of the account using unified login @type autocreate: bool @raises pywikibot.exceptions.NoUsernameError: Username is not recognised by the site. """ if not self.password: # First check that the username exists, # to avoid asking for a password that will not work. if not autocreate: self.check_user_exists() # As we don't want the password to appear on the screen, we set # password = True self.password = pywikibot.input( 'Password for user {name} on {site} (no characters will be ' 'shown):'.format(name=self.login_name, site=self.site), password=True) pywikibot.output('Logging in to {site} as {name}'.format( name=self.login_name, site=self.site)) try: self.login_to_site() except APIError as e: error_code = e.code pywikibot.error('Login failed ({}).'.format(error_code)) if error_code in self._api_error: error_msg = 'Username "{}" {} on {}'.format( self.login_name, self._api_error[error_code], self.site) if error_code in ('Failed', 'FAIL'): error_msg += '\n.{}'.format(e.info) raise NoUsernameError(error_msg) # TODO: investigate other unhandled API codes (bug T75539) if retry: self.password = None return self.login(retry=False) else: self.storecookiedata() pywikibot.log('Should be logged in now') return True return False
def __init__(self, password: Optional[str] = None, site=None, user: Optional[str] = None): """ Initializer. All parameters default to defaults in user-config. @param site: Site object to log into @type site: BaseSite @param user: username to use. If user is None, the username is loaded from config.usernames. @param password: password to use @raises pywikibot.exceptions.NoUsernameError: No username is configured for the requested site. """ site = self.site = site or pywikibot.Site() if not user: config_names = config.usernames code_to_usr = config_names[site.family.name] or config_names['*'] try: user = code_to_usr.get(site.code) or code_to_usr['*'] except KeyError: raise NoUsernameError( 'ERROR: ' 'username for {site.family.name}:{site.code} is undefined.' '\nIf you have a username for that site, ' 'please add a line to user-config.py as follows:\n' "usernames['{site.family.name}']['{site.code}'] = " "'myUsername'".format(site=site)) self.password = password self.login_name = self.username = user if getattr(config, 'password_file', ''): self.readPassword()