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