From 453059c217813a8bb4d27ba043ef7125f54fe0ac Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Thu, 12 Apr 2012 22:53:33 -0400 Subject: [PATCH] Thread safety in Site, bugfix in Category, cleanup in Page --- earwigbot/wiki/category.py | 2 +- earwigbot/wiki/page.py | 16 +++++++--------- earwigbot/wiki/site.py | 19 +++++++++++-------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/earwigbot/wiki/category.py b/earwigbot/wiki/category.py index 9f43e7b..e0209b2 100644 --- a/earwigbot/wiki/category.py +++ b/earwigbot/wiki/category.py @@ -55,7 +55,7 @@ class Category(Page): title = self.title().replace(" ", "_").split(":", 1)[1] if limit: - query += " LIMIT = ?" + query += " LIMIT ?" result = self._site.sql_query(query, (title, limit)) else: result = self._site.sql_query(query, (title,)) diff --git a/earwigbot/wiki/page.py b/earwigbot/wiki/page.py index 957878e..701500e 100644 --- a/earwigbot/wiki/page.py +++ b/earwigbot/wiki/page.py @@ -194,19 +194,17 @@ class Page(CopyrightMixin): else: self._is_redirect = True - self._pageid = result["query"]["pages"].keys()[0] - if int(self._pageid) < 0: - try: - res["missing"] - except KeyError: + self._pageid = int(result["query"]["pages"].keys()[0]) + if self._pageid < 0: + if "missing" in res: + # If it has a negative ID and it's missing; we can still get + # data like the namespace, protection, and URL: + self._exists = 2 + else: # If it has a negative ID and it's invalid, then break here, # because there's no other data for us to get: self._exists = 1 return - else: - # If it has a negative ID and it's missing; we can still get - # data like the namespace, protection, and URL: - self._exists = 2 else: self._exists = 3 diff --git a/earwigbot/wiki/site.py b/earwigbot/wiki/site.py index d723bdb..2675ed0 100644 --- a/earwigbot/wiki/site.py +++ b/earwigbot/wiki/site.py @@ -27,6 +27,7 @@ from logging import getLogger, NullHandler from os.path import expanduser from re import escape as re_escape, match as re_match from StringIO import StringIO +from threading import Lock from time import sleep, time from urllib import unquote_plus, urlencode from urllib2 import build_opener, HTTPCookieProcessor, URLError @@ -114,6 +115,7 @@ class Site(object): # Attributes used for SQL queries: self._sql_data = sql self._sql_conn = None + self._sql_lock = Lock() # Attribute used in copyright violation checks (see CopyrightMixin): self._search_config = search_config @@ -577,19 +579,20 @@ class Site(object): (oursql.ProgrammingError, oursql.InterfaceError, ...) if there were problems with the query. """ - if not self._sql_conn: - self._sql_connect() - if not cursor_class: if dict_cursor: cursor_class = oursql.DictCursor else: cursor_class = oursql.Cursor - - with self._sql_conn.cursor(cursor_class, show_table=show_table) as cur: - cur.execute(query, params, plain_query) - for result in cur: - yield result + klass = cursor_class + + with self._sql_lock: + if not self._sql_conn: + self._sql_connect() + with self._sql_conn.cursor(klass, show_table=show_table) as cur: + cur.execute(query, params, plain_query) + for result in cur: + yield result def get_replag(self): """Return the estimated database replication lag in seconds.