| @@ -57,7 +57,7 @@ class Bot(object): | |||||
| self.logger = logging.getLogger("earwigbot") | self.logger = logging.getLogger("earwigbot") | ||||
| self.commands = CommandManager(self) | self.commands = CommandManager(self) | ||||
| self.tasks = TaskManager(self) | self.tasks = TaskManager(self) | ||||
| self.wiki = SitesDB(self.config) | |||||
| self.wiki = SitesDB(self) | |||||
| self.frontend = None | self.frontend = None | ||||
| self.watcher = None | self.watcher = None | ||||
| @@ -35,10 +35,6 @@ add_site, and remove_site that should handle all of your Site (and thus, Page, | |||||
| Category, and User) needs. | Category, and User) needs. | ||||
| """ | """ | ||||
| import logging as _log | |||||
| logger = _log.getLogger("earwigbot.wiki") | |||||
| logger.addHandler(_log.NullHandler()) | |||||
| 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.exceptions import * | ||||
| @@ -23,6 +23,7 @@ | |||||
| from cookielib import CookieJar | from cookielib import CookieJar | ||||
| from gzip import GzipFile | from gzip import GzipFile | ||||
| from json import loads | from json import loads | ||||
| from logging import getLogger, NullHandler | |||||
| from os.path import expanduser | from os.path import expanduser | ||||
| from re import escape as re_escape, match as re_match | from re import escape as re_escape, match as re_match | ||||
| from StringIO import StringIO | from StringIO import StringIO | ||||
| @@ -36,7 +37,6 @@ try: | |||||
| except ImportError: | except ImportError: | ||||
| oursql = None | oursql = None | ||||
| from earwigbot.wiki import logger | |||||
| from earwigbot.wiki.category import Category | from earwigbot.wiki.category import Category | ||||
| from earwigbot.wiki.constants import * | from earwigbot.wiki.constants import * | ||||
| from earwigbot.wiki.exceptions import * | from earwigbot.wiki.exceptions import * | ||||
| @@ -74,7 +74,7 @@ class Site(object): | |||||
| article_path=None, script_path=None, sql=None, | article_path=None, script_path=None, sql=None, | ||||
| namespaces=None, login=(None, None), cookiejar=None, | namespaces=None, login=(None, None), cookiejar=None, | ||||
| user_agent=None, use_https=False, assert_edit=None, | user_agent=None, use_https=False, assert_edit=None, | ||||
| maxlag=None, wait_between_queries=5, | |||||
| maxlag=None, wait_between_queries=5, logger=None, | |||||
| search_config=(None, None)): | search_config=(None, None)): | ||||
| """Constructor for new Site instances. | """Constructor for new Site instances. | ||||
| @@ -132,6 +132,13 @@ class Site(object): | |||||
| # Get all of the above attributes that were not specified as arguments: | # Get all of the above attributes that were not specified as arguments: | ||||
| self._load_attributes() | self._load_attributes() | ||||
| # Set up our internal logger: | |||||
| if logger: | |||||
| self._logger = logger | |||||
| else: # Just set up a null logger to eat up our messages: | |||||
| self._logger = getLogger("earwigbot.wiki").getChild(self._name) | |||||
| self._logger.addHandler(NullHandler()) | |||||
| # If we have a name/pass and the API says we're not logged in, log in: | # If we have a name/pass and the API says we're not logged in, log in: | ||||
| self._login_info = name, password = login | self._login_info = name, password = login | ||||
| if name and password: | if name and password: | ||||
| @@ -193,12 +200,13 @@ class Site(object): | |||||
| since_last_query = time() - self._last_query_time # Throttling support | since_last_query = time() - self._last_query_time # Throttling support | ||||
| if since_last_query < self._wait_between_queries: | if since_last_query < self._wait_between_queries: | ||||
| wait_time = self._wait_between_queries - since_last_query | wait_time = self._wait_between_queries - since_last_query | ||||
| logger.debug("Throttled: waiting {0} seconds".format(wait_time)) | |||||
| log = "Throttled: waiting {0} seconds".format(wait_time) | |||||
| self._logger.debug(log) | |||||
| sleep(wait_time) | sleep(wait_time) | ||||
| self._last_query_time = time() | self._last_query_time = time() | ||||
| url, data = self._build_api_query(params) | url, data = self._build_api_query(params) | ||||
| logger.debug("{0} -> {1}".format(url, data)) | |||||
| self._logger.debug("{0} -> {1}".format(url, data)) | |||||
| try: | try: | ||||
| response = self._opener.open(url, data) | response = self._opener.open(url, data) | ||||
| @@ -263,7 +271,7 @@ class Site(object): | |||||
| raise SiteAPIError(e.format(self._max_retries)) | raise 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})' | ||||
| logger.info(msg.format(info, wait, tries, self._max_retries)) | |||||
| self._logger.info(msg.format(info, wait, tries, self._max_retries)) | |||||
| sleep(wait) | sleep(wait) | ||||
| 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 | ||||
| @@ -52,9 +52,10 @@ class SitesDB(object): | |||||
| by importing the manager class (`from earwigbot.wiki import SitesDB`). | by importing the manager class (`from earwigbot.wiki import SitesDB`). | ||||
| """ | """ | ||||
| def __init__(self, config): | |||||
| """Set up the manager with an attribute for the BotConfig object.""" | |||||
| self.config = config | |||||
| def __init__(self, bot): | |||||
| """Set up the manager with an attribute for the base Bot object.""" | |||||
| self.config = bot.config | |||||
| self._logger = bot.logger.getChild("wiki") | |||||
| self._sites = {} # Internal site cache | self._sites = {} # Internal site cache | ||||
| self._sitesdb = path.join(config.root_dir, "sites.db") | self._sitesdb = path.join(config.root_dir, "sites.db") | ||||
| self._cookie_file = path.join(config.root_dir, ".cookies") | self._cookie_file = path.join(config.root_dir, ".cookies") | ||||
| @@ -173,6 +174,7 @@ class SitesDB(object): | |||||
| assert_edit = config.wiki.get("assert") | assert_edit = config.wiki.get("assert") | ||||
| maxlag = config.wiki.get("maxlag") | maxlag = config.wiki.get("maxlag") | ||||
| wait_between_queries = config.wiki.get("waitTime", 5) | wait_between_queries = config.wiki.get("waitTime", 5) | ||||
| logger = self._logger.getChild(name) | |||||
| search_config = config.wiki.get("search") | search_config = config.wiki.get("search") | ||||
| if user_agent: | if user_agent: | ||||
| @@ -185,7 +187,7 @@ class SitesDB(object): | |||||
| cookiejar=cookiejar, user_agent=user_agent, | cookiejar=cookiejar, user_agent=user_agent, | ||||
| use_https=use_https, assert_edit=assert_edit, | use_https=use_https, assert_edit=assert_edit, | ||||
| maxlag=maxlag, wait_between_queries=wait_between_queries, | maxlag=maxlag, wait_between_queries=wait_between_queries, | ||||
| search_config=search_config) | |||||
| logger=logger, search_config=search_config) | |||||
| def _get_site_name_from_sitesdb(self, project, lang): | def _get_site_name_from_sitesdb(self, project, lang): | ||||
| """Return the name of the first site with the given project and lang. | """Return the name of the first site with the given project and lang. | ||||
| @@ -342,6 +344,7 @@ class SitesDB(object): | |||||
| assert_edit = config.wiki.get("assert") | assert_edit = config.wiki.get("assert") | ||||
| maxlag = config.wiki.get("maxlag") | maxlag = config.wiki.get("maxlag") | ||||
| wait_between_queries = config.wiki.get("waitTime", 5) | wait_between_queries = config.wiki.get("waitTime", 5) | ||||
| logger = self._logger.getChild(name) | |||||
| search_config = config.wiki.get("search") | search_config = config.wiki.get("search") | ||||
| # Create a Site object to log in and load the other attributes: | # Create a Site object to log in and load the other attributes: | ||||
| @@ -349,7 +352,7 @@ class SitesDB(object): | |||||
| login=login, cookiejar=cookiejar, user_agent=user_agent, | login=login, cookiejar=cookiejar, user_agent=user_agent, | ||||
| use_https=use_https, assert_edit=assert_edit, | use_https=use_https, assert_edit=assert_edit, | ||||
| maxlag=maxlag, wait_between_queries=wait_between_queries, | maxlag=maxlag, wait_between_queries=wait_between_queries, | ||||
| search_config=search_config) | |||||
| logger=logger, search_config=search_config) | |||||
| self._add_site_to_sitesdb(site) | self._add_site_to_sitesdb(site) | ||||
| self._sites[site.name()] = site | self._sites[site.name()] = site | ||||
| @@ -49,7 +49,7 @@ from earwigbot.commands import CommandManager | |||||
| from earwigbot.config import BotConfig | from earwigbot.config import BotConfig | ||||
| from earwigbot.irc import IRCConnection, Data | from earwigbot.irc import IRCConnection, Data | ||||
| from earwigbot.tasks import TaskManager | from earwigbot.tasks import TaskManager | ||||
| from earwigbot.wiki import SitesDBManager | |||||
| from earwigbot.wiki import SitesDB | |||||
| class CommandTestCase(TestCase): | class CommandTestCase(TestCase): | ||||
| re_sender = re.compile(":(.*?)!(.*?)@(.*?)\Z") | re_sender = re.compile(":(.*?)!(.*?)@(.*?)\Z") | ||||
| @@ -114,7 +114,7 @@ class FakeBot(Bot): | |||||
| self.logger = logging.getLogger("earwigbot") | self.logger = logging.getLogger("earwigbot") | ||||
| self.commands = CommandManager(self) | self.commands = CommandManager(self) | ||||
| self.tasks = TaskManager(self) | self.tasks = TaskManager(self) | ||||
| self.wiki = SitesDBManager(self.config) | |||||
| self.wiki = SitesDB(self) | |||||
| self.frontend = FakeIRCConnection(self) | self.frontend = FakeIRCConnection(self) | ||||
| self.watcher = FakeIRCConnection(self) | self.watcher = FakeIRCConnection(self) | ||||