@@ -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) | ||||