@@ -21,7 +21,6 @@ | |||||
# SOFTWARE. | # SOFTWARE. | ||||
import re | import re | ||||
from urllib import quote | |||||
from earwigbot.commands import Command | from earwigbot.commands import Command | ||||
@@ -31,12 +31,13 @@ __all__ = ["IRCConnection"] | |||||
class IRCConnection(object): | class IRCConnection(object): | ||||
"""Interface with an IRC server.""" | """Interface with an IRC server.""" | ||||
def __init__(self, host, port, nick, ident, realname): | |||||
def __init__(self, host, port, nick, ident, realname, logger): | |||||
self._host = host | self._host = host | ||||
self._port = port | self._port = port | ||||
self._nick = nick | self._nick = nick | ||||
self._ident = ident | self._ident = ident | ||||
self._realname = realname | self._realname = realname | ||||
self.logger = logger | |||||
self._is_running = False | self._is_running = False | ||||
self._send_lock = Lock() | self._send_lock = Lock() | ||||
@@ -42,7 +42,7 @@ class Data(object): | |||||
def __repr__(self): | def __repr__(self): | ||||
"""Return the canonical string representation of the Data.""" | """Return the canonical string representation of the Data.""" | ||||
res = "Data(bot={0!r}, my_nick={1!r}, line={2!r})" | res = "Data(bot={0!r}, my_nick={1!r}, line={2!r})" | ||||
return res.format(self.bot, self.my_nick, self.line) | |||||
return res.format(self._bot, self.my_nick, self.line) | |||||
def __str__(self): | def __str__(self): | ||||
"""Return a nice string representation of the Data.""" | """Return a nice string representation of the Data.""" | ||||
@@ -39,12 +39,10 @@ class Frontend(IRCConnection): | |||||
def __init__(self, bot): | def __init__(self, bot): | ||||
self.bot = bot | self.bot = bot | ||||
self.logger = bot.logger.getChild("frontend") | |||||
cf = bot.config.irc["frontend"] | cf = bot.config.irc["frontend"] | ||||
base = super(Frontend, self) | base = super(Frontend, self) | ||||
base.__init__(cf["host"], cf["port"], cf["nick"], cf["ident"], | base.__init__(cf["host"], cf["port"], cf["nick"], cf["ident"], | ||||
cf["realname"]) | |||||
cf["realname"], bot.logger.getChild("frontend")) | |||||
self._connect() | self._connect() | ||||
def __repr__(self): | def __repr__(self): | ||||
@@ -39,12 +39,10 @@ class Watcher(IRCConnection): | |||||
def __init__(self, bot): | def __init__(self, bot): | ||||
self.bot = bot | self.bot = bot | ||||
self.logger = bot.logger.getChild("watcher") | |||||
cf = bot.config.irc["watcher"] | cf = bot.config.irc["watcher"] | ||||
base = super(Watcher, self) | base = super(Watcher, self) | ||||
base.__init__(cf["host"], cf["port"], cf["nick"], cf["ident"], | base.__init__(cf["host"], cf["port"], cf["nick"], cf["ident"], | ||||
cf["realname"]) | |||||
cf["realname"], bot.logger.getChild("watcher")) | |||||
self._prepare_process_hook() | self._prepare_process_hook() | ||||
self._connect() | self._connect() | ||||
@@ -114,7 +114,7 @@ class ExclusionsDB(object): | |||||
else: | else: | ||||
conn.execute(query3, (sitename, url)) | conn.execute(query3, (sitename, url)) | ||||
conn.executemany(query4, [(sitename, url) for url in urls]) | conn.executemany(query4, [(sitename, url) for url in urls]) | ||||
if conn.execute(query5, (name,)).fetchone(): | |||||
if conn.execute(query5, (sitename,)).fetchone(): | |||||
conn.execute(query6, (time(), sitename)) | conn.execute(query6, (time(), sitename)) | ||||
else: | else: | ||||
conn.execute(query7, (sitename, time())) | conn.execute(query7, (sitename, time())) | ||||
@@ -136,7 +136,7 @@ class ExclusionsDB(object): | |||||
This only updates the exclusions database for the *sitename* site. | This only updates the exclusions database for the *sitename* site. | ||||
""" | """ | ||||
max_staleness = 60 * 60 * 24 * 30 | max_staleness = 60 * 60 * 24 * 30 | ||||
time_since_update = int(time() - self._get_last_update()) | |||||
time_since_update = int(time() - self._get_last_update(sitename)) | |||||
if time_since_update > max_staleness: | if time_since_update > max_staleness: | ||||
log = u"Updating stale database: {0} (last updated {1} seconds ago)" | log = u"Updating stale database: {0} (last updated {1} seconds ago)" | ||||
self._logger.info(log.format(sitename, time_since_update)) | self._logger.info(log.format(sitename, time_since_update)) | ||||
@@ -23,9 +23,9 @@ | |||||
from os import path | from os import path | ||||
try: | try: | ||||
from bs4 import BeautifulSoup | |||||
import bs4 | |||||
except ImportError: | except ImportError: | ||||
BeautifulSoup = None | |||||
bs4 = None | |||||
try: | try: | ||||
import mwparserfromhell | import mwparserfromhell | ||||
@@ -52,7 +52,7 @@ class BaseTextParser(object): | |||||
def __str__(self): | def __str__(self): | ||||
"""Return a nice string representation of the text parser.""" | """Return a nice string representation of the text parser.""" | ||||
name = self.__class__.__name__ | name = self.__class__.__name__ | ||||
return "<{0} of text with size {1}>".format(name, len(text)) | |||||
return "<{0} of text with size {1}>".format(name, len(self.text)) | |||||
class ArticleTextParser(BaseTextParser): | class ArticleTextParser(BaseTextParser): | ||||
@@ -136,9 +136,9 @@ class HTMLTextParser(BaseTextParser): | |||||
(http://www.crummy.com/software/BeautifulSoup/). | (http://www.crummy.com/software/BeautifulSoup/). | ||||
""" | """ | ||||
try: | try: | ||||
soup = BeautifulSoup(self.text, "lxml").body | |||||
soup = bs4.BeautifulSoup(self.text, "lxml").body | |||||
except ValueError: | except ValueError: | ||||
soup = BeautifulSoup(self.text).body | |||||
soup = bs4.BeautifulSoup(self.text).body | |||||
is_comment = lambda text: isinstance(text, bs4.element.Comment) | is_comment = lambda text: isinstance(text, bs4.element.Comment) | ||||
[comment.extract() for comment in soup.find_all(text=is_comment)] | [comment.extract() for comment in soup.find_all(text=is_comment)] | ||||
@@ -185,9 +185,9 @@ class Site(object): | |||||
name, password = self._login_info | name, password = self._login_info | ||||
login = "({0}, {1})".format(repr(name), "hidden" if password else None) | login = "({0}, {1})".format(repr(name), "hidden" if password else None) | ||||
cookies = self._cookiejar.__class__.__name__ | cookies = self._cookiejar.__class__.__name__ | ||||
try: | |||||
cookies += "({0!r})".format(self._cookiejar.filename) | |||||
except AttributeError: | |||||
if hasattr(self._cookiejar, "filename"): | |||||
cookies += "({0!r})".format(getattr(self._cookiejar, "filename")) | |||||
else: | |||||
cookies += "()" | cookies += "()" | ||||
agent = self._opener.addheaders[0][1] | agent = self._opener.addheaders[0][1] | ||||
return res.format(login, cookies, agent, **self.__dict__) | return res.format(login, cookies, agent, **self.__dict__) | ||||
@@ -445,10 +445,11 @@ class Site(object): | |||||
FileCookieJar raises NotImplementedError) or no default filename was | FileCookieJar raises NotImplementedError) or no default filename was | ||||
given (LWPCookieJar and MozillaCookieJar raise ValueError). | given (LWPCookieJar and MozillaCookieJar raise ValueError). | ||||
""" | """ | ||||
try: | |||||
self._cookiejar.save() | |||||
except (AttributeError, NotImplementedError, ValueError): | |||||
pass | |||||
if hasattr(self._cookiejar, "save"): | |||||
try: | |||||
gettattr(self._cookiejar, "save")() | |||||
except (NotImplementedError, ValueError): | |||||
pass | |||||
def _login(self, login, token=None, attempt=0): | def _login(self, login, token=None, attempt=0): | ||||
"""Safely login through the API. | """Safely login through the API. | ||||
@@ -323,7 +323,7 @@ class SitesDB(object): | |||||
# Name arg given, but don't look at others unless `name` isn't found: | # Name arg given, but don't look at others unless `name` isn't found: | ||||
if name: | if name: | ||||
try: | try: | ||||
return self._get_site_object(name) | |||||
return self._get_site_object(name) | |||||
except SiteNotFoundError: | except SiteNotFoundError: | ||||
if project and lang: | if project and lang: | ||||
name = self._get_site_name_from_sitesdb(project, lang) | name = self._get_site_name_from_sitesdb(project, lang) | ||||