diff --git a/docs/api/earwigbot.rst b/docs/api/earwigbot.rst index f74e44f..07c8499 100644 --- a/docs/api/earwigbot.rst +++ b/docs/api/earwigbot.rst @@ -9,14 +9,6 @@ earwigbot Package :undoc-members: :show-inheritance: -:mod:`blowfish` Module ----------------------- - -.. automodule:: earwigbot.blowfish - :members: - :undoc-members: - :show-inheritance: - :mod:`bot` Module ----------------- @@ -33,6 +25,14 @@ earwigbot Package :undoc-members: :show-inheritance: +:mod:`exceptions` Module +------------------------ + +.. automodule:: earwigbot.exceptions + :members: + :undoc-members: + :show-inheritance: + :mod:`managers` Module ---------------------- diff --git a/docs/api/earwigbot.wiki.rst b/docs/api/earwigbot.wiki.rst index 9938da8..9e7a5ad 100644 --- a/docs/api/earwigbot.wiki.rst +++ b/docs/api/earwigbot.wiki.rst @@ -33,14 +33,6 @@ wiki Package :undoc-members: :show-inheritance: -:mod:`exceptions` Module ------------------------- - -.. automodule:: earwigbot.wiki.exceptions - :members: - :undoc-members: - :show-inheritance: - :mod:`page` Module ------------------ diff --git a/earwigbot/__init__.py b/earwigbot/__init__.py index fa766e0..236104c 100644 --- a/earwigbot/__init__.py +++ b/earwigbot/__init__.py @@ -49,4 +49,12 @@ if not __release__: finally: del _add_git_commit_id_to_version_string -from earwigbot import bot, commands, config, irc, managers, tasks, util, wiki +from earwigbot import bot +from earwigbot import commands +from earwigbot import config +from earwigbot import exceptions +from earwigbot import irc +from earwigbot import managers +from earwigbot import tasks +from earwigbot import util +from earwigbot import wiki diff --git a/earwigbot/commands/threads.py b/earwigbot/commands/threads.py index f9a6219..8dd7b10 100644 --- a/earwigbot/commands/threads.py +++ b/earwigbot/commands/threads.py @@ -24,7 +24,7 @@ import threading import re from earwigbot.commands import BaseCommand -from earwigbot.irc import KwargParseException +from earwigbot.exceptions import KwargParseError class Command(BaseCommand): """Manage wiki tasks from IRC, and check on thread status.""" @@ -135,7 +135,7 @@ class Command(BaseCommand): try: data.parse_kwargs() - except KwargParseException, arg: + except KwargParseError, arg: msg = "error parsing argument: \x0303{0}\x0301.".format(arg) self.reply(data, msg) return diff --git a/earwigbot/exceptions.py b/earwigbot/exceptions.py new file mode 100644 index 0000000..c11d74f --- /dev/null +++ b/earwigbot/exceptions.py @@ -0,0 +1,244 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2009-2012 by Ben Kurtovic +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +""" +EarwigBot Exceptions + +This module contains all exceptions used by EarwigBot:: + + EarwigBotError + +-- IRCError + | +-- BrokenSocketError + | +-- KwargParseError + +-- WikiToolsetError + +-- SiteNotFoundError + +-- SiteAPIError + +-- LoginError + +-- NamespaceNotFoundError + +-- PageNotFoundError + +-- InvalidPageError + +-- RedirectError + +-- UserNotFoundError + +-- EditError + | +-- PermissionsError + | +-- EditConflictError + | +-- NoContentError + | +-- ContentTooBigError + | +-- SpamDetectedError + | +-- FilteredError + +-- SQLError + +-- CopyvioCheckError + +-- UnknownSearchEngineError + +-- UnsupportedSearchEngineError + +-- SearchQueryError +""" + +class EarwigBotError(Exception): + """Base exception class for errors in EarwigBot.""" + +class IRCError(EarwigBotError): + """Base exception class for errors in IRC-relation sections of the bot.""" + +class BrokenSocketError(IRCError): + """A socket has broken, because it is not sending data. + + Raised by :py:meth:`IRCConnection._get + `. + """ + +class KwargParseError(IRCError): + """Couldn't parse a certain keyword argument in an IRC message. + + This is usually caused by it being given incorrectly: e.g., no value (abc), + just a value (=xyz), just an equal sign (=), instead of the correct form + (abc=xyz). + + Raised by :py:meth:`Data.parse_kwargs + `. + """ + +class WikiToolsetError(EarwigBotError): + """Base exception class for errors in the Wiki Toolset.""" + +class SiteNotFoundError(WikiToolsetError): + """A particular site could not be found in the sites database. + + Raised by :py:class:`~earwigbot.wiki.sitesdb.SitesDB`. + """ + +class SiteAPIError(WikiToolsetError): + """Couldn't connect to a site's API. + + Perhaps the server doesn't exist, our URL is wrong or incomplete, or + there are temporary problems on their end. + + Raised by :py:meth:`Site.api_query `. + """ + +class LoginError(WikiToolsetError): + """An error occured while trying to login. + + Perhaps the username/password is incorrect. + + Raised by :py:meth:`Site._login `. + """ + +class NamespaceNotFoundError(WikiToolsetError): + """A requested namespace name or namespace ID does not exist. + + Raised by :py:meth:`Site.namespace_id_to_name + ` and + :py:meth:`Site.namespace_name_to_id + `. + """ + +class PageNotFoundError(WikiToolsetError): + """Attempted to get information about a page that does not exist. + + Raised by :py:class:`~earwigbot.wiki.page.Page`. + """ + +class InvalidPageError(WikiToolsetError): + """Attempted to get information about a page whose title is invalid. + + Raised by :py:class:`~earwigbot.wiki.page.Page`. + """ + +class RedirectError(WikiToolsetError): + """A redirect-only method was called on a malformed or non-redirect page. + + Raised by :py:meth:`Page.get_redirect_target + `. + """ + +class UserNotFoundError(WikiToolsetError): + """Attempted to get certain information about a user that does not exist. + + Raised by :py:class:`~earwigbot.wiki.user.User`. + """ + +class EditError(WikiToolsetError): + """An error occured while editing. + + This is used as a base class for all editing errors; this one specifically + is used only when a generic error occurs that we don't know about. + + Raised by :py:meth:`Page.edit ` and + :py:meth:`Page.add_section `. + """ + +class PermissionsError(EditError): + """A permissions error ocurred while editing. + + We tried to do something we don't have permission to, like trying to delete + a page as a non-admin, or trying to edit a page without login information + and AssertEdit enabled. + + Raised by :py:meth:`Page.edit ` and + :py:meth:`Page.add_section `. + """ + +class EditConflictError(EditError): + """We gotten an edit conflict or a (rarer) delete/recreate conflict. + + Raised by :py:meth:`Page.edit ` and + :py:meth:`Page.add_section `. + """ + +class NoContentError(EditError): + """We tried to create a page or new section with no content. + + Raised by :py:meth:`Page.edit ` and + :py:meth:`Page.add_section `. + """ + +class ContentTooBigError(EditError): + """The edit we tried to push exceeded the article size limit. + + Raised by :py:meth:`Page.edit ` and + :py:meth:`Page.add_section `. + """ + +class SpamDetectedError(EditError): + """The spam filter refused our edit. + + Raised by :py:meth:`Page.edit ` and + :py:meth:`Page.add_section `. + """ + +class FilteredError(EditError): + """The edit filter refused our edit. + + Raised by :py:meth:`Page.edit ` and + :py:meth:`Page.add_section `. + """ + +class SQLError(WikiToolsetError): + """Some error involving SQL querying occurred. + + Raised by :py:meth:`Site.sql_query `. + """ + +class CopyvioCheckError(WikiToolsetError): + """An error occured when checking a page for copyright violations. + + This is a base class for multiple exceptions; usually one of those will be + raised instead of this. + + Raised by :py:meth:`Page.copyvio_check + ` and + :py:meth:`Page.copyvio_compare + `. + """ + +class UnknownSearchEngineError(CopyvioCheckError): + """Attempted to do a copyvio check with an unknown search engine. + + Search engines are specified in :file:`config.yml` as + :py:attr:`config.wiki["search"]["engine"]`. + + Raised by :py:meth:`Page.copyvio_check + ` and + :py:meth:`Page.copyvio_compare + `. + """ + +class UnsupportedSearchEngineError(CopyvioCheckError): + """Attmpted to do a copyvio check using an unavailable engine. + + This might occur if, for example, an engine requires oauth2 but the package + couldn't be imported. + + Raised by :py:meth:`Page.copyvio_check + ` and + :py:meth:`Page.copyvio_compare + `. + """ + +class SearchQueryError(CopyvioCheckError): + """Some error ocurred while doing a search query. + + Raised by :py:meth:`Page.copyvio_check + ` and + :py:meth:`Page.copyvio_compare + `. + """ diff --git a/earwigbot/irc/connection.py b/earwigbot/irc/connection.py index f819534..b8c864a 100644 --- a/earwigbot/irc/connection.py +++ b/earwigbot/irc/connection.py @@ -24,14 +24,9 @@ import socket from threading import Lock from time import sleep -__all__ = ["BrokenSocketException", "IRCConnection"] +from earwigbot.exceptions import BrokenSocketError -class BrokenSocketException(Exception): - """A socket has broken, because it is not sending data. - - Raised by IRCConnection()._get(). - """ - pass +__all__ = ["IRCConnection"] class IRCConnection(object): """A class to interface with IRC.""" @@ -72,7 +67,7 @@ class IRCConnection(object): data = self._sock.recv(size) if not data: # Socket isn't giving us any data, so it is dead or broken: - raise BrokenSocketException() + raise BrokenSocketError() return data def _send(self, msg): @@ -137,7 +132,7 @@ class IRCConnection(object): while 1: try: read_buffer += self._get() - except BrokenSocketException: + except BrokenSocketError: self._is_running = False break diff --git a/earwigbot/irc/data.py b/earwigbot/irc/data.py index b83bcf6..83b8166 100644 --- a/earwigbot/irc/data.py +++ b/earwigbot/irc/data.py @@ -22,13 +22,9 @@ import re -__all__ = ["KwargParseException", "Data"] +from earwigbot.exceptions import KwargParseError -class KwargParseException(Exception): - """Couldn't parse a certain keyword argument in self.args, probably because - it was given incorrectly: e.g., no value (abc), just a value (=xyz), just - an equal sign (=), instead of the correct (abc=xyz).""" - pass +__all__ = ["Data"] class Data(object): """Store data from an individual line received on IRC.""" @@ -81,8 +77,8 @@ class Data(object): try: key, value = re.findall("^(.*?)\=(.*?)$", arg)[0] except IndexError: - raise KwargParseException(arg) + raise KwargParseError(arg) if key and value: self.kwargs[key] = value else: - raise KwargParseException(arg) + raise KwargParseError(arg) diff --git a/earwigbot/wiki/__init__.py b/earwigbot/wiki/__init__.py index 3c11724..9765239 100644 --- a/earwigbot/wiki/__init__.py +++ b/earwigbot/wiki/__init__.py @@ -37,7 +37,6 @@ Category, and User) needs. from earwigbot.wiki.category import * from earwigbot.wiki.constants import * -from earwigbot.wiki.exceptions import * from earwigbot.wiki.page import * from earwigbot.wiki.site import * from earwigbot.wiki.sitesdb import * diff --git a/earwigbot/wiki/constants.py b/earwigbot/wiki/constants.py index 8e818a6..7ccb136 100644 --- a/earwigbot/wiki/constants.py +++ b/earwigbot/wiki/constants.py @@ -35,7 +35,8 @@ earwigbot.wiki (e.g. `earwigbot.wiki.USER_AGENT`). # Default User Agent when making API queries: from earwigbot import __version__ as _v from platform import python_version as _p -USER_AGENT = "EarwigBot/{0} (Python/{1}; https://github.com/earwig/earwigbot)".format(_v, _p()) +USER_AGENT = "EarwigBot/{0} (Python/{1}; https://github.com/earwig/earwigbot)" +USER_AGENT = USER_AGENT.format(_v, _p()) del _v, _p # Default namespace IDs: diff --git a/earwigbot/wiki/copyright.py b/earwigbot/wiki/copyright.py index c003ebb..397c5c1 100644 --- a/earwigbot/wiki/copyright.py +++ b/earwigbot/wiki/copyright.py @@ -35,7 +35,7 @@ try: except ImportError: oauth = None -from earwigbot.wiki.exceptions import * +from earwigbot.exceptions import * class _CopyvioCheckResult(object): def __init__(self, violation, confidence, url, queries, article, chains): diff --git a/earwigbot/wiki/exceptions.py b/earwigbot/wiki/exceptions.py deleted file mode 100644 index 41266df..0000000 --- a/earwigbot/wiki/exceptions.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2009-2012 by Ben Kurtovic -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -""" -EarwigBot's Wiki Toolset: Exceptions - -This module contains all exceptions used by the wiki package. There are a lot: - --- WikiToolsetError - -- SiteNotFoundError - -- SiteAPIError - -- LoginError - -- NamespaceNotFoundError - -- PageNotFoundError - -- InvalidPageError - -- RedirectError - -- UserNotFoundError - -- EditError - -- PermissionsError - -- EditConflictError - -- NoContentError - -- ContentTooBigError - -- SpamDetectedError - -- FilteredError - -- SQLError - -- CopyvioCheckError - -- UnknownSearchEngineError - -- UnsupportedSearchEngineError - -- SearchQueryError -""" - -class WikiToolsetError(Exception): - """Base exception class for errors in the Wiki Toolset.""" - -class SiteNotFoundError(WikiToolsetError): - """A site matching the args given to get_site() could not be found in the - config file.""" - -class SiteAPIError(WikiToolsetError): - """We couldn't connect to a site's API, perhaps because the server doesn't - exist, our URL is wrong or incomplete, or they're having temporary - problems.""" - -class LoginError(WikiToolsetError): - """An error occured while trying to login. Perhaps the username/password is - incorrect.""" - -class NamespaceNotFoundError(WikiToolsetError): - """A requested namespace name or namespace ID does not exist.""" - -class PageNotFoundError(WikiToolsetError): - """Attempting to get certain information about a page that does not - exist.""" - -class InvalidPageError(WikiToolsetError): - """Attempting to get certain information about a page whose title is - invalid.""" - -class RedirectError(WikiToolsetError): - """Page's get_redirect_target() method failed because the page is either - not a redirect, or it is malformed.""" - -class UserNotFoundError(WikiToolsetError): - """Attempting to get certain information about a user that does not - exist.""" - -class EditError(WikiToolsetError): - """We got some error while editing. Sometimes, a subclass of this exception - will be used, like PermissionsError or EditConflictError.""" - -class PermissionsError(EditError): - """We tried to do something we don't have permission to, like a non-admin - trying to delete a page, or trying to edit a page when no login information - was provided.""" - -class EditConflictError(EditError): - """We've gotten an edit conflict or a (rarer) delete/recreate conflict.""" - -class NoContentError(EditError): - """We tried to create a page or new section with no content.""" - -class ContentTooBigError(EditError): - """The edit we tried to push exceeded the article size limit.""" - -class SpamDetectedError(EditError): - """The spam filter refused our edit.""" - -class FilteredError(EditError): - """The edit filter refused our edit.""" - -class SQLError(WikiToolsetError): - """Some error involving SQL querying occurred.""" - -class CopyvioCheckError(WikiToolsetError): - """An error occured when checking a page for copyright violations.""" - -class UnknownSearchEngineError(CopyvioCheckError): - """CopyrightMixin().copyvio_check() called with an unknown engine.""" - -class UnsupportedSearchEngineError(CopyvioCheckError): - """The engine requested is not available, e.g., because a required package - is missing.""" - -class SearchQueryError(CopyvioCheckError): - """Some error ocurred while doing a search query.""" diff --git a/earwigbot/wiki/page.py b/earwigbot/wiki/page.py index e6e9a4f..1c7ab0f 100644 --- a/earwigbot/wiki/page.py +++ b/earwigbot/wiki/page.py @@ -25,8 +25,8 @@ import re from time import gmtime, strftime from urllib import quote +from earwigbot import exceptions from earwigbot.wiki.copyright import CopyrightMixin -from earwigbot.wiki.exceptions import * __all__ = ["Page"] @@ -132,7 +132,7 @@ class Page(CopyrightMixin): """ if self._exists == 1: e = "Page '{0}' is invalid.".format(self._title) - raise InvalidPageError(e) + raise exceptions.InvalidPageError(e) def _force_existence(self): """Used to ensure that our page exists. @@ -144,7 +144,7 @@ class Page(CopyrightMixin): self._force_validity() if self._exists == 2: e = "Page '{0}' does not exist.".format(self._title) - raise PageNotFoundError(e) + raise exceptions.PageNotFoundError(e) def _load_wrapper(self): """Calls _load_attributes() and follows redirects if we're supposed to. @@ -278,8 +278,8 @@ class Page(CopyrightMixin): self._load_attributes() if not self._token: e = "You don't have permission to edit this page." - raise PermissionsError(e) - + raise exceptions.PermissionsError(e) + # Weed out invalid pages before we get too far: self._force_validity() @@ -310,7 +310,7 @@ class Page(CopyrightMixin): try: assertion = result["edit"]["assert"] except KeyError: - raise EditError(result["edit"]) + raise exceptions.EditError(result["edit"]) self._handle_assert_edit(assertion, params, tries) def _build_edit_params(self, text, summary, minor, bot, force, section, @@ -353,13 +353,13 @@ class Page(CopyrightMixin): """ if error.code in ["noedit", "cantcreate", "protectedtitle", "noimageredirect"]: - raise PermissionsError(error.info) + raise exceptions.PermissionsError(error.info) elif error.code in ["noedit-anon", "cantcreate-anon", "noimageredirect-anon"]: if not all(self._site._login_info): # Insufficient login info: - raise PermissionsError(error.info) + raise exceptions.PermissionsError(error.info) if tries == 0: # We have login info; try to login: self._site._login(self._site._login_info) @@ -368,28 +368,28 @@ class Page(CopyrightMixin): else: # We already tried to log in and failed! e = "Although we should be logged in, we are not. This may be a cookie problem or an odd bug." - raise LoginError(e) + raise exceptions.LoginError(e) elif error.code in ["editconflict", "pagedeleted", "articleexists"]: # These attributes are now invalidated: self._content = None self._basetimestamp = None self._exists = 0 - raise EditConflictError(error.info) + raise exceptions.EditConflictError(error.info) elif error.code in ["emptypage", "emptynewsection"]: - raise NoContentError(error.info) + raise exceptions.NoContentError(error.info) elif error.code == "contenttoobig": - raise ContentTooBigError(error.info) + raise exceptions.ContentTooBigError(error.info) elif error.code == "spamdetected": - raise SpamDetectedError(error.info) + raise exceptions.SpamDetectedError(error.info) elif error.code == "filtered": - raise FilteredError(error.info) + raise exceptions.FilteredError(error.info) - raise EditError(": ".join((error.code, error.info))) + raise exceptions.EditError(": ".join((error.code, error.info))) def _handle_assert_edit(self, assertion, params, tries): """If we can't edit due to a failed AssertEdit assertion, handle that. @@ -401,7 +401,7 @@ class Page(CopyrightMixin): if not all(self._site._login_info): # Insufficient login info: e = "AssertEdit: user assertion failed, and no login info was provided." - raise PermissionsError(e) + raise exceptions.PermissionsError(e) if tries == 0: # We have login info; try to login: self._site._login(self._site._login_info) @@ -410,15 +410,15 @@ class Page(CopyrightMixin): else: # We already tried to log in and failed! e = "Although we should be logged in, we are not. This may be a cookie problem or an odd bug." - raise LoginError(e) + raise exceptions.LoginError(e) elif assertion == "bot": e = "AssertEdit: bot assertion failed; we don't have a bot flag!" - raise PermissionsError(e) + raise exceptions.PermissionsError(e) # Unknown assertion, maybe "true", "false", or "exists": e = "AssertEdit: assertion '{0}' failed.".format(assertion) - raise PermissionsError(e) + raise exceptions.PermissionsError(e) def title(self, force=False): """Returns the Page's title, or pagename. @@ -570,7 +570,7 @@ class Page(CopyrightMixin): if self._namespace < 0: ns = self._site.namespace_id_to_name(self._namespace) e = "Pages in the {0} namespace can't have talk pages.".format(ns) - raise InvalidPageError(e) + raise exceptions.InvalidPageError(e) if self._is_talkpage: new_ns = self._namespace - 1 @@ -650,7 +650,7 @@ class Page(CopyrightMixin): return re.findall(self.re_redirect, content, flags=re.I)[0] except IndexError: e = "The page does not appear to have a redirect target." - raise RedirectError(e) + raise exceptions.RedirectError(e) def edit(self, text, summary, minor=False, bot=True, force=False): """Replaces the page's content or creates a new page. diff --git a/earwigbot/wiki/site.py b/earwigbot/wiki/site.py index 6505965..f90a2cc 100644 --- a/earwigbot/wiki/site.py +++ b/earwigbot/wiki/site.py @@ -38,9 +38,9 @@ try: except ImportError: oursql = None +from earwigbot import exceptions +from earwigbot.wiki import constants from earwigbot.wiki.category import Category -from earwigbot.wiki.constants import * -from earwigbot.wiki.exceptions import * from earwigbot.wiki.page import Page from earwigbot.wiki.user import User @@ -128,7 +128,7 @@ class Site(object): else: self._cookiejar = CookieJar() if not user_agent: - user_agent = USER_AGENT # Set default UA from wiki.constants + user_agent = constants.USER_AGENT # Set default UA self._opener = build_opener(HTTPCookieProcessor(self._cookiejar)) self._opener.addheaders = [("User-Agent", user_agent), ("Accept-Encoding", "gzip")] @@ -232,7 +232,7 @@ class Site(object): e = e.format(error.code) else: e = "API query failed." - raise SiteAPIError(e) + raise exceptions.SiteAPIError(e) result = response.read() if response.headers.get("Content-Encoding") == "gzip": @@ -246,7 +246,7 @@ class Site(object): """Given API query params, return the URL to query and POST data.""" if not self._base_url or self._script_path is None: e = "Tried to do an API query, but no API URL is known." - raise SiteAPIError(e) + raise exceptions.SiteAPIError(e) base_url = self._base_url if base_url.startswith("//"): # Protocol-relative URLs from 1.18 @@ -271,7 +271,7 @@ class Site(object): res = loads(result) # Try to parse as a JSON object except ValueError: e = "API query failed: JSON could not be decoded." - raise SiteAPIError(e) + raise exceptions.SiteAPIError(e) try: code = res["error"]["code"] @@ -282,7 +282,7 @@ class Site(object): if code == "maxlag": # We've been throttled by the server if tries >= self._max_retries: e = "Maximum number of retries reached ({0})." - raise SiteAPIError(e.format(self._max_retries)) + raise exceptions.SiteAPIError(e.format(self._max_retries)) tries += 1 msg = 'Server says "{0}"; retrying in {1} seconds ({2}/{3})' self._logger.info(msg.format(info, wait, tries, self._max_retries)) @@ -290,7 +290,7 @@ class Site(object): return self._api_query(params, tries=tries, wait=wait*3) else: # Some unknown error occurred e = 'API query failed: got error "{0}"; server says: "{1}".' - error = SiteAPIError(e.format(code, info)) + error = earwigbot.SiteAPIError(e.format(code, info)) error.code, error.info = code, info raise error @@ -491,7 +491,7 @@ class Site(object): e = "The given password is incorrect." else: e = "Couldn't login; server says '{0}'.".format(res) - raise LoginError(e) + raise exceptions.LoginError(e) def _logout(self): """Safely logout through the API. @@ -518,7 +518,7 @@ class Site(object): """ if not oursql: e = "Module 'oursql' is required for SQL queries." - raise SQLError(e) + raise exceptions.SQLError(e) args = self._sql_data for key, value in kwargs.iteritems(): @@ -638,7 +638,7 @@ class Site(object): return self._namespaces[ns_id][0] except KeyError: e = "There is no namespace with id {0}.".format(ns_id) - raise NamespaceNotFoundError(e) + raise exceptions.NamespaceNotFoundError(e) def namespace_name_to_id(self, name): """Given a namespace name, returns the associated ID. @@ -655,7 +655,7 @@ class Site(object): return ns_id e = "There is no namespace with name '{0}'.".format(name) - raise NamespaceNotFoundError(e) + raise exceptions.NamespaceNotFoundError(e) def get_page(self, title, follow_redirects=False): """Returns a Page object for the given title (pagename). @@ -667,7 +667,7 @@ class Site(object): Note that this doesn't do any direct checks for existence or redirect-following - Page's methods provide that. """ - prefixes = self.namespace_id_to_name(NS_CATEGORY, all=True) + prefixes = self.namespace_id_to_name(constants.NS_CATEGORY, all=True) prefix = title.split(":", 1)[0] if prefix != title: # Avoid a page that is simply "Category" if prefix in prefixes: @@ -680,7 +680,7 @@ class Site(object): `catname` should be given *without* a namespace prefix. This method is really just shorthand for get_page("Category:" + catname). """ - prefix = self.namespace_id_to_name(NS_CATEGORY) + prefix = self.namespace_id_to_name(constants.NS_CATEGORY) pagename = ':'.join((prefix, catname)) return Category(self, pagename, follow_redirects) diff --git a/earwigbot/wiki/sitesdb.py b/earwigbot/wiki/sitesdb.py index 2a3cba5..c60fa13 100644 --- a/earwigbot/wiki/sitesdb.py +++ b/earwigbot/wiki/sitesdb.py @@ -28,7 +28,7 @@ import stat import sqlite3 as sqlite from earwigbot import __version__ -from earwigbot.wiki.exceptions import SiteNotFoundError +from earwigbot.exceptions import SiteNotFoundError from earwigbot.wiki.site import Site __all__ = ["SitesDB"] diff --git a/earwigbot/wiki/user.py b/earwigbot/wiki/user.py index 6c51051..67c9567 100644 --- a/earwigbot/wiki/user.py +++ b/earwigbot/wiki/user.py @@ -22,8 +22,8 @@ from time import gmtime, strptime -from earwigbot.wiki.constants import * -from earwigbot.wiki.exceptions import UserNotFoundError +from earwigbot.exceptions import UserNotFoundError +from earwigbot.wiki import constants from earwigbot.wiki.page import Page __all__ = ["User"] @@ -252,7 +252,7 @@ class User(object): No checks are made to see if it exists or not. Proper site namespace conventions are followed. """ - prefix = self._site.namespace_id_to_name(NS_USER) + prefix = self._site.namespace_id_to_name(constants.NS_USER) pagename = ':'.join((prefix, self._name)) return Page(self._site, pagename) @@ -262,6 +262,6 @@ class User(object): No checks are made to see if it exists or not. Proper site namespace conventions are followed. """ - prefix = self._site.namespace_id_to_name(NS_USER_TALK) + prefix = self._site.namespace_id_to_name(constants.NS_USER_TALK) pagename = ':'.join((prefix, self._name)) return Page(self._site, pagename)