Browse Source

earwigbot.wiki.exceptions -> earwigbot.exceptions; cleanup

tags/v0.1^2
Ben Kurtovic 12 years ago
parent
commit
25f31124db
9 changed files with 82 additions and 69 deletions
  1. +9
    -1
      earwigbot/__init__.py
  2. +30
    -25
      earwigbot/exceptions.py
  3. +0
    -1
      earwigbot/wiki/__init__.py
  4. +2
    -1
      earwigbot/wiki/constants.py
  5. +1
    -1
      earwigbot/wiki/copyright.py
  6. +21
    -21
      earwigbot/wiki/page.py
  7. +14
    -14
      earwigbot/wiki/site.py
  8. +1
    -1
      earwigbot/wiki/sitesdb.py
  9. +4
    -4
      earwigbot/wiki/user.py

+ 9
- 1
earwigbot/__init__.py View File

@@ -49,4 +49,12 @@ if not __release__:
finally: finally:
del _add_git_commit_id_to_version_string 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

WikiToolsetError → earwigbot/exceptions.py View File

@@ -21,34 +21,38 @@
# SOFTWARE. # SOFTWARE.


""" """
EarwigBot's Wiki Toolset: Exceptions

This module contains all exceptions used by the wiki package. There are a lot:

-- SiteNotFoundError
-- SiteAPIError
-- LoginError
-- NamespaceNotFoundError
-- PageNotFoundError
-- InvalidPageError
-- RedirectError
-- UserNotFoundError
-- EditError
-- PermissionsError
-- EditConflictError
-- NoContentError
-- ContentTooBigError
-- SpamDetectedError
-- FilteredError
-- SQLError
-- CopyvioCheckError
-- UnknownSearchEngineError
-- UnsupportedSearchEngineError
-- SearchQueryError
EarwigBot Exceptions

This module contains all exceptions used by EarwigBot::

EarwigBotError
+-- WikiToolsetError
+-- SiteNotFoundError
+-- SiteAPIError
+-- LoginError
+-- NamespaceNotFoundError
+-- PageNotFoundError
+-- InvalidPageError
+-- RedirectError
+-- UserNotFoundError
+-- EditError
| +-- PermissionsError
| +-- EditConflictError
| +-- NoContentError
| +-- ContentTooBigError
| +-- SpamDetectedError
| +-- FilteredError
+-- SQLError
+-- CopyvioCheckError
+-- UnknownSearchEngineError
+-- UnsupportedSearchEngineError
+-- SearchQueryError
""" """


class WikiToolsetError(Exception):
class EarwigBotErorr(Exception):
"""Base exception class for errors in EarwigBot."""

class WikiToolsetError(EarwigBotErorr):
"""Base exception class for errors in the Wiki Toolset.""" """Base exception class for errors in the Wiki Toolset."""


class SiteNotFoundError(WikiToolsetError): class SiteNotFoundError(WikiToolsetError):

+ 0
- 1
earwigbot/wiki/__init__.py View File

@@ -37,7 +37,6 @@ Category, and User) needs.


from earwigbot.wiki.category import * from earwigbot.wiki.category import *
from earwigbot.wiki.constants import * from earwigbot.wiki.constants import *
from earwigbot.wiki.exceptions import *
from earwigbot.wiki.page import * from earwigbot.wiki.page import *
from earwigbot.wiki.site import * from earwigbot.wiki.site import *
from earwigbot.wiki.sitesdb import * from earwigbot.wiki.sitesdb import *


+ 2
- 1
earwigbot/wiki/constants.py View File

@@ -35,7 +35,8 @@ earwigbot.wiki (e.g. `earwigbot.wiki.USER_AGENT`).
# Default User Agent when making API queries: # Default User Agent when making API queries:
from earwigbot import __version__ as _v from earwigbot import __version__ as _v
from platform import python_version as _p 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 del _v, _p


# Default namespace IDs: # Default namespace IDs:


+ 1
- 1
earwigbot/wiki/copyright.py View File

@@ -35,7 +35,7 @@ try:
except ImportError: except ImportError:
oauth = None oauth = None


from earwigbot.wiki.exceptions import *
from earwigbot.exceptions import *


class _CopyvioCheckResult(object): class _CopyvioCheckResult(object):
def __init__(self, violation, confidence, url, queries, article, chains): def __init__(self, violation, confidence, url, queries, article, chains):


+ 21
- 21
earwigbot/wiki/page.py View File

@@ -25,8 +25,8 @@ import re
from time import gmtime, strftime from time import gmtime, strftime
from urllib import quote from urllib import quote


from earwigbot import exceptions
from earwigbot.wiki.copyright import CopyrightMixin from earwigbot.wiki.copyright import CopyrightMixin
from earwigbot.wiki.exceptions import *


__all__ = ["Page"] __all__ = ["Page"]


@@ -132,7 +132,7 @@ class Page(CopyrightMixin):
""" """
if self._exists == 1: if self._exists == 1:
e = "Page '{0}' is invalid.".format(self._title) e = "Page '{0}' is invalid.".format(self._title)
raise InvalidPageError(e)
raise exceptions.InvalidPageError(e)


def _force_existence(self): def _force_existence(self):
"""Used to ensure that our page exists. """Used to ensure that our page exists.
@@ -144,7 +144,7 @@ class Page(CopyrightMixin):
self._force_validity() self._force_validity()
if self._exists == 2: if self._exists == 2:
e = "Page '{0}' does not exist.".format(self._title) e = "Page '{0}' does not exist.".format(self._title)
raise PageNotFoundError(e)
raise exceptions.PageNotFoundError(e)


def _load_wrapper(self): def _load_wrapper(self):
"""Calls _load_attributes() and follows redirects if we're supposed to. """Calls _load_attributes() and follows redirects if we're supposed to.
@@ -278,8 +278,8 @@ class Page(CopyrightMixin):
self._load_attributes() self._load_attributes()
if not self._token: if not self._token:
e = "You don't have permission to edit this page." 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: # Weed out invalid pages before we get too far:
self._force_validity() self._force_validity()


@@ -310,7 +310,7 @@ class Page(CopyrightMixin):
try: try:
assertion = result["edit"]["assert"] assertion = result["edit"]["assert"]
except KeyError: except KeyError:
raise EditError(result["edit"])
raise exceptions.EditError(result["edit"])
self._handle_assert_edit(assertion, params, tries) self._handle_assert_edit(assertion, params, tries)


def _build_edit_params(self, text, summary, minor, bot, force, section, 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", if error.code in ["noedit", "cantcreate", "protectedtitle",
"noimageredirect"]: "noimageredirect"]:
raise PermissionsError(error.info)
raise exceptions.PermissionsError(error.info)


elif error.code in ["noedit-anon", "cantcreate-anon", elif error.code in ["noedit-anon", "cantcreate-anon",
"noimageredirect-anon"]: "noimageredirect-anon"]:
if not all(self._site._login_info): if not all(self._site._login_info):
# Insufficient login info: # Insufficient login info:
raise PermissionsError(error.info)
raise exceptions.PermissionsError(error.info)
if tries == 0: if tries == 0:
# We have login info; try to login: # We have login info; try to login:
self._site._login(self._site._login_info) self._site._login(self._site._login_info)
@@ -368,28 +368,28 @@ class Page(CopyrightMixin):
else: else:
# We already tried to log in and failed! # 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." 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"]: elif error.code in ["editconflict", "pagedeleted", "articleexists"]:
# These attributes are now invalidated: # These attributes are now invalidated:
self._content = None self._content = None
self._basetimestamp = None self._basetimestamp = None
self._exists = 0 self._exists = 0
raise EditConflictError(error.info)
raise exceptions.EditConflictError(error.info)


elif error.code in ["emptypage", "emptynewsection"]: elif error.code in ["emptypage", "emptynewsection"]:
raise NoContentError(error.info)
raise exceptions.NoContentError(error.info)


elif error.code == "contenttoobig": elif error.code == "contenttoobig":
raise ContentTooBigError(error.info)
raise exceptions.ContentTooBigError(error.info)


elif error.code == "spamdetected": elif error.code == "spamdetected":
raise SpamDetectedError(error.info)
raise exceptions.SpamDetectedError(error.info)


elif error.code == "filtered": 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): def _handle_assert_edit(self, assertion, params, tries):
"""If we can't edit due to a failed AssertEdit assertion, handle that. """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): if not all(self._site._login_info):
# Insufficient login info: # Insufficient login info:
e = "AssertEdit: user assertion failed, and no login info was provided." e = "AssertEdit: user assertion failed, and no login info was provided."
raise PermissionsError(e)
raise exceptions.PermissionsError(e)
if tries == 0: if tries == 0:
# We have login info; try to login: # We have login info; try to login:
self._site._login(self._site._login_info) self._site._login(self._site._login_info)
@@ -410,15 +410,15 @@ class Page(CopyrightMixin):
else: else:
# We already tried to log in and failed! # 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." 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": elif assertion == "bot":
e = "AssertEdit: bot assertion failed; we don't have a bot flag!" 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": # Unknown assertion, maybe "true", "false", or "exists":
e = "AssertEdit: assertion '{0}' failed.".format(assertion) e = "AssertEdit: assertion '{0}' failed.".format(assertion)
raise PermissionsError(e)
raise exceptions.PermissionsError(e)


def title(self, force=False): def title(self, force=False):
"""Returns the Page's title, or pagename. """Returns the Page's title, or pagename.
@@ -570,7 +570,7 @@ class Page(CopyrightMixin):
if self._namespace < 0: if self._namespace < 0:
ns = self._site.namespace_id_to_name(self._namespace) ns = self._site.namespace_id_to_name(self._namespace)
e = "Pages in the {0} namespace can't have talk pages.".format(ns) e = "Pages in the {0} namespace can't have talk pages.".format(ns)
raise InvalidPageError(e)
raise exceptions.InvalidPageError(e)


if self._is_talkpage: if self._is_talkpage:
new_ns = self._namespace - 1 new_ns = self._namespace - 1
@@ -650,7 +650,7 @@ class Page(CopyrightMixin):
return re.findall(self.re_redirect, content, flags=re.I)[0] return re.findall(self.re_redirect, content, flags=re.I)[0]
except IndexError: except IndexError:
e = "The page does not appear to have a redirect target." 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): def edit(self, text, summary, minor=False, bot=True, force=False):
"""Replaces the page's content or creates a new page. """Replaces the page's content or creates a new page.


+ 14
- 14
earwigbot/wiki/site.py View File

@@ -38,9 +38,9 @@ try:
except ImportError: except ImportError:
oursql = None oursql = None


from earwigbot import exceptions
from earwigbot.wiki import constants
from earwigbot.wiki.category import Category 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.page import Page
from earwigbot.wiki.user import User from earwigbot.wiki.user import User


@@ -128,7 +128,7 @@ class Site(object):
else: else:
self._cookiejar = CookieJar() self._cookiejar = CookieJar()
if not user_agent: 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 = build_opener(HTTPCookieProcessor(self._cookiejar))
self._opener.addheaders = [("User-Agent", user_agent), self._opener.addheaders = [("User-Agent", user_agent),
("Accept-Encoding", "gzip")] ("Accept-Encoding", "gzip")]
@@ -232,7 +232,7 @@ class Site(object):
e = e.format(error.code) e = e.format(error.code)
else: else:
e = "API query failed." e = "API query failed."
raise SiteAPIError(e)
raise exceptions.SiteAPIError(e)


result = response.read() result = response.read()
if response.headers.get("Content-Encoding") == "gzip": 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.""" """Given API query params, return the URL to query and POST data."""
if not self._base_url or self._script_path is None: if not self._base_url or self._script_path is None:
e = "Tried to do an API query, but no API URL is known." 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 base_url = self._base_url
if base_url.startswith("//"): # Protocol-relative URLs from 1.18 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 res = loads(result) # Try to parse as a JSON object
except ValueError: except ValueError:
e = "API query failed: JSON could not be decoded." e = "API query failed: JSON could not be decoded."
raise SiteAPIError(e)
raise exceptions.SiteAPIError(e)


try: try:
code = res["error"]["code"] code = res["error"]["code"]
@@ -282,7 +282,7 @@ class Site(object):
if code == "maxlag": # We've been throttled by the server if code == "maxlag": # We've been throttled by the server
if tries >= self._max_retries: if tries >= self._max_retries:
e = "Maximum number of retries reached ({0})." e = "Maximum number of retries reached ({0})."
raise SiteAPIError(e.format(self._max_retries))
raise exceptions.SiteAPIError(e.format(self._max_retries))
tries += 1 tries += 1
msg = 'Server says "{0}"; retrying in {1} seconds ({2}/{3})' msg = 'Server says "{0}"; retrying in {1} seconds ({2}/{3})'
self._logger.info(msg.format(info, wait, tries, self._max_retries)) 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) return self._api_query(params, tries=tries, wait=wait*3)
else: # Some unknown error occurred else: # Some unknown error occurred
e = 'API query failed: got error "{0}"; server says: "{1}".' 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 error.code, error.info = code, info
raise error raise error


@@ -491,7 +491,7 @@ class Site(object):
e = "The given password is incorrect." e = "The given password is incorrect."
else: else:
e = "Couldn't login; server says '{0}'.".format(res) e = "Couldn't login; server says '{0}'.".format(res)
raise LoginError(e)
raise exceptions.LoginError(e)


def _logout(self): def _logout(self):
"""Safely logout through the API. """Safely logout through the API.
@@ -518,7 +518,7 @@ class Site(object):
""" """
if not oursql: if not oursql:
e = "Module 'oursql' is required for SQL queries." e = "Module 'oursql' is required for SQL queries."
raise SQLError(e)
raise exceptions.SQLError(e)


args = self._sql_data args = self._sql_data
for key, value in kwargs.iteritems(): for key, value in kwargs.iteritems():
@@ -638,7 +638,7 @@ class Site(object):
return self._namespaces[ns_id][0] return self._namespaces[ns_id][0]
except KeyError: except KeyError:
e = "There is no namespace with id {0}.".format(ns_id) 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): def namespace_name_to_id(self, name):
"""Given a namespace name, returns the associated ID. """Given a namespace name, returns the associated ID.
@@ -655,7 +655,7 @@ class Site(object):
return ns_id return ns_id


e = "There is no namespace with name '{0}'.".format(name) 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): def get_page(self, title, follow_redirects=False):
"""Returns a Page object for the given title (pagename). """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 Note that this doesn't do any direct checks for existence or
redirect-following - Page's methods provide that. 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] prefix = title.split(":", 1)[0]
if prefix != title: # Avoid a page that is simply "Category" if prefix != title: # Avoid a page that is simply "Category"
if prefix in prefixes: if prefix in prefixes:
@@ -680,7 +680,7 @@ class Site(object):
`catname` should be given *without* a namespace prefix. This method is `catname` should be given *without* a namespace prefix. This method is
really just shorthand for get_page("Category:" + catname). 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)) pagename = ':'.join((prefix, catname))
return Category(self, pagename, follow_redirects) return Category(self, pagename, follow_redirects)




+ 1
- 1
earwigbot/wiki/sitesdb.py View File

@@ -28,7 +28,7 @@ import stat
import sqlite3 as sqlite import sqlite3 as sqlite


from earwigbot import __version__ from earwigbot import __version__
from earwigbot.wiki.exceptions import SiteNotFoundError
from earwigbot.exceptions import SiteNotFoundError
from earwigbot.wiki.site import Site from earwigbot.wiki.site import Site


__all__ = ["SitesDB"] __all__ = ["SitesDB"]


+ 4
- 4
earwigbot/wiki/user.py View File

@@ -22,8 +22,8 @@


from time import gmtime, strptime 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 from earwigbot.wiki.page import Page


__all__ = ["User"] __all__ = ["User"]
@@ -252,7 +252,7 @@ class User(object):
No checks are made to see if it exists or not. Proper site namespace No checks are made to see if it exists or not. Proper site namespace
conventions are followed. 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)) pagename = ':'.join((prefix, self._name))
return Page(self._site, pagename) 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 No checks are made to see if it exists or not. Proper site namespace
conventions are followed. 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)) pagename = ':'.join((prefix, self._name))
return Page(self._site, pagename) return Page(self._site, pagename)

Loading…
Cancel
Save