| @@ -30,18 +30,18 @@ class Dictionary(Command): | |||||
| def process(self, data): | def process(self, data): | ||||
| if not data.args: | if not data.args: | ||||
| self.reply(data, "what do you want me to define?") | |||||
| self.reply(data, "what do you want me to define?") | |||||
| return | return | ||||
| term = " ".join(data.args) | term = " ".join(data.args) | ||||
| lang = self.bot.wiki.get_site().lang | lang = self.bot.wiki.get_site().lang | ||||
| try: | try: | ||||
| definition = self.define(term, lang) | |||||
| defined = self.define(term, lang) | |||||
| except exceptions.APIError: | except exceptions.APIError: | ||||
| msg = "cannot find a {0}-language Wiktionary." | msg = "cannot find a {0}-language Wiktionary." | ||||
| self.reply(data, msg.format(lang)) | self.reply(data, msg.format(lang)) | ||||
| else: | else: | ||||
| self.reply(data, "{0}: {1}".format(term, definition)) | |||||
| self.reply(data, "{0}: {1}".format(term, defined.encode("utf8"))) | |||||
| def define(self, term, lang): | def define(self, term, lang): | ||||
| try: | try: | ||||
| @@ -274,7 +274,8 @@ class BotConfig(object): | |||||
| key = getpass("Enter key to decrypt bot passwords: ") | key = getpass("Enter key to decrypt bot passwords: ") | ||||
| self._decryption_cipher = Blowfish.new(sha256(key).digest()) | self._decryption_cipher = Blowfish.new(sha256(key).digest()) | ||||
| signature = self.metadata["signature"] | signature = self.metadata["signature"] | ||||
| assert bcrypt.hashpw(key, signature) == signature | |||||
| if bcrypt.hashpw(key, signature) != signature: | |||||
| raise RuntimeError("Incorrect password.") | |||||
| for node, nodes in self._decryptable_nodes: | for node, nodes in self._decryptable_nodes: | ||||
| self._decrypt(node, nodes) | self._decrypt(node, nodes) | ||||
| @@ -78,7 +78,7 @@ class _ResourceManager(object): | |||||
| try: | try: | ||||
| resource = klass(self.bot) # Create instance of resource | resource = klass(self.bot) # Create instance of resource | ||||
| except Exception: | except Exception: | ||||
| e = "Error instantiating {0} class in {1} (from {2})" | |||||
| e = "Error instantiating {0} class in '{1}' (from {2})" | |||||
| self.logger.exception(e.format(res_type, name, path)) | self.logger.exception(e.format(res_type, name, path)) | ||||
| else: | else: | ||||
| self._resources[resource.name] = resource | self._resources[resource.name] = resource | ||||
| @@ -98,7 +98,7 @@ class _ResourceManager(object): | |||||
| try: | try: | ||||
| module = imp.load_module(name, f, path, desc) | module = imp.load_module(name, f, path, desc) | ||||
| except Exception: | except Exception: | ||||
| e = "Couldn't load module {0} (from {1})" | |||||
| e = "Couldn't load module '{0}' (from {1})" | |||||
| self.logger.exception(e.format(name, path)) | self.logger.exception(e.format(name, path)) | ||||
| return | return | ||||
| finally: | finally: | ||||
| @@ -131,13 +131,19 @@ class Site(object): | |||||
| self._api_info_cache = {"maxlag": 0, "lastcheck": 0} | self._api_info_cache = {"maxlag": 0, "lastcheck": 0} | ||||
| # Attributes used for SQL queries: | # Attributes used for SQL queries: | ||||
| self._sql_data = sql | |||||
| if sql: | |||||
| self._sql_data = sql | |||||
| else: | |||||
| self._sql_data = {} | |||||
| self._sql_conn = None | self._sql_conn = None | ||||
| self._sql_lock = Lock() | self._sql_lock = Lock() | ||||
| self._sql_info_cache = {"replag": 0, "lastcheck": 0, "usable": None} | self._sql_info_cache = {"replag": 0, "lastcheck": 0, "usable": None} | ||||
| # Attribute used in copyright violation checks (see CopyrightMixIn): | # Attribute used in copyright violation checks (see CopyrightMixIn): | ||||
| self._search_config = search_config | |||||
| if search_config: | |||||
| self._search_config = search_config | |||||
| else: | |||||
| self._search_config = {} | |||||
| # Set up cookiejar and URL opener for making API queries: | # Set up cookiejar and URL opener for making API queries: | ||||
| if cookiejar: | if cookiejar: | ||||
| @@ -150,9 +156,6 @@ class Site(object): | |||||
| self._opener.addheaders = [("User-Agent", user_agent), | self._opener.addheaders = [("User-Agent", user_agent), | ||||
| ("Accept-Encoding", "gzip")] | ("Accept-Encoding", "gzip")] | ||||
| # Get all of the above attributes that were not specified as arguments: | |||||
| self._load_attributes() | |||||
| # Set up our internal logger: | # Set up our internal logger: | ||||
| if logger: | if logger: | ||||
| self._logger = logger | self._logger = logger | ||||
| @@ -160,6 +163,9 @@ class Site(object): | |||||
| self._logger = getLogger("earwigbot.wiki") | self._logger = getLogger("earwigbot.wiki") | ||||
| self._logger.addHandler(NullHandler()) | self._logger.addHandler(NullHandler()) | ||||
| # Get all of the above attributes that were not specified as arguments: | |||||
| self._load_attributes() | |||||
| # 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: | ||||
| @@ -278,6 +278,7 @@ class SitesDB(object): | |||||
| else: | else: | ||||
| conn.execute("DELETE FROM sql_data WHERE sql_site = ?", (name,)) | conn.execute("DELETE FROM sql_data WHERE sql_site = ?", (name,)) | ||||
| conn.execute("DELETE FROM namespaces WHERE ns_site = ?", (name,)) | conn.execute("DELETE FROM namespaces WHERE ns_site = ?", (name,)) | ||||
| self._logger.info("Removed site '{0}'".format(name)) | |||||
| return True | return True | ||||
| def get_site(self, name=None, project=None, lang=None): | def get_site(self, name=None, project=None, lang=None): | ||||
| @@ -376,34 +377,20 @@ 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", 3) | wait_between_queries = config.wiki.get("waitTime", 3) | ||||
| logger = self._logger.getChild(name) | |||||
| search_config = config.wiki.get("search") | |||||
| if user_agent: | if user_agent: | ||||
| user_agent = user_agent.replace("$1", __version__) | user_agent = user_agent.replace("$1", __version__) | ||||
| user_agent = user_agent.replace("$2", python_version()) | user_agent = user_agent.replace("$2", python_version()) | ||||
| if search_config: | |||||
| nltk_dir = path.join(self.config.root_dir, ".nltk") | |||||
| search_config["nltk_dir"] = nltk_dir | |||||
| search_config["exclusions_db"] = self._exclusions_db | |||||
| if not sql: | |||||
| sql = config.wiki.get("sql", {}) | |||||
| for key, value in sql.iteritems(): | |||||
| if "$1" in value: | |||||
| sql[key] = value.replace("$1", name) | |||||
| # Create a Site object to log in and load the other attributes: | # Create a Site object to log in and load the other attributes: | ||||
| site = Site(base_url=base_url, script_path=script_path, sql=sql, | site = Site(base_url=base_url, script_path=script_path, sql=sql, | ||||
| 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, | |||||
| logger=logger, search_config=search_config) | |||||
| maxlag=maxlag, wait_between_queries=wait_between_queries) | |||||
| self._logger.info("Added site '{0}'".format(site.name)) | |||||
| self._add_site_to_sitesdb(site) | self._add_site_to_sitesdb(site) | ||||
| self._sites[site.name] = site | |||||
| return site | |||||
| return self._get_site_object(site.name) | |||||
| def remove_site(self, name=None, project=None, lang=None): | def remove_site(self, name=None, project=None, lang=None): | ||||
| """Remove a site from the sitesdb. | """Remove a site from the sitesdb. | ||||