From 1201c213a12442b2231b254ced49e0976d97d3b8 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Tue, 10 Sep 2013 17:54:16 -0400 Subject: [PATCH] Delete this unused code so we can remove the matplotlib imports. --- tasks/afc_history.py | 200 +-------------------------------------------------- 1 file changed, 3 insertions(+), 197 deletions(-) diff --git a/tasks/afc_history.py b/tasks/afc_history.py index c57aa57..1c5b325 100644 --- a/tasks/afc_history.py +++ b/tasks/afc_history.py @@ -20,208 +20,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from collections import OrderedDict -from datetime import datetime, timedelta -from itertools import count -from os.path import expanduser -from threading import Lock -from time import sleep - -from matplotlib import pyplot as plt -from numpy import arange -import oursql - -from earwigbot import wiki from earwigbot.tasks import Task class AFCHistory(Task): - """A task to generate charts about AfC submissions over time. - - The main function of the task is to work through the "AfC submissions by - date" categories (e.g. [[Category:AfC submissions by date/12 July 2011]]) - and determine the number of declined, accepted, and currently pending - submissions every day. - - This information is saved to a MySQL database ("u_earwig_afc_history") and - used to generate a graph showing the number of AfC submissions by date - with matplotlib and numpy. The chart is saved as a PNG to - config.tasks["afc_history"]["graph"]["dest"], which defaults to - "afc_history.png". - """ + """A task to generate information about AfC submissions over time.""" name = "afc_history" - # Valid submission statuses: - STATUS_NONE = 0 - STATUS_PEND = 1 - STATUS_DECLINE = 2 - STATUS_ACCEPT = 3 - def setup(self): - cfg = self.config.tasks.get(self.name, {}) - self.num_days = cfg.get("days", 90) - self.categories = cfg.get("categories", {}) - - # Graph stuff: - self.graph = cfg.get("graph", {}) - self.destination = self.graph.get("dest", "afc_history.png") - - # Connection data for our SQL database: - kwargs = cfg.get("sql", {}) - kwargs["read_default_file"] = expanduser("~/.my.cnf") - self.conn_data = kwargs - self.db_access_lock = Lock() + pass def run(self, **kwargs): - self.site = self.bot.wiki.get_site() - with self.db_access_lock: - self.conn = oursql.connect(**self.conn_data) - - action = kwargs.get("action") - try: - num_days = int(kwargs.get("days", self.num_days)) - if action == "update": - self.update(num_days) - elif action == "generate": - self.generate(num_days) - finally: - self.conn.close() - - def update(self, num_days): - self.logger.info("Updating past {0} days".format(num_days)) - generator = self.backwards_cat_iterator() - for i in xrange(num_days): - category = generator.next() - date = category.title.split("/")[-1] - self.update_date(date, category) - sleep(10) - self.logger.info("Update complete") - - def generate(self, num_days): - self.logger.info("Generating chart for past {0} days".format(num_days)) - data = OrderedDict() - generator = self.backwards_cat_iterator() - for i in xrange(num_days): - category = generator.next() - date = category.title.split("/")[-1] - data[date] = self.get_date_counts(date) - - data = OrderedDict(reversed(data.items())) # Oldest to most recent - self.generate_chart(data) - dest = expanduser(self.destination) - plt.savefig(dest) - self.logger.info("Chart saved to {0}".format(dest)) - - def backwards_cat_iterator(self): - date_base = self.categories["dateBase"] - current = datetime.utcnow() - while 1: - subcat = current.strftime("%d %B %Y") - title = "/".join((date_base, subcat)) - yield self.site.get_category(title) - current -= timedelta(1) # Subtract one day from date - - def update_date(self, date, category): - msg = "Updating {0} ([[{1}]])".format(date, category.title) - self.logger.debug(msg) - - q_select = "SELECT page_date, page_status FROM page WHERE page_id = ?" - q_delete = "DELETE FROM page WHERE page_id = ?" - q_update = "UPDATE page SET page_date = ?, page_status = ? WHERE page_id = ?" - q_insert = "INSERT INTO page VALUES (?, ?, ?)" - members = category.get_members() - - with self.conn.cursor() as cursor: - for title, pageid in members: - cursor.execute(q_select, (pageid,)) - stored = cursor.fetchall() - status = self.get_status(title, pageid) - - if status == self.STATUS_NONE: - if stored: - cursor.execute(q_delete, (pageid,)) - continue - - if stored: - stored_date, stored_status = list(stored)[0] - if date != stored_date or status != stored_status: - cursor.execute(q_update, (date, status, pageid)) - - else: - cursor.execute(q_insert, (pageid, date, status)) - - def get_status(self, title, pageid): - page = self.site.get_page(title) - ns = page.namespace - - if ns == wiki.NS_FILE_TALK: # Ignore accepted FFU requests - return self.STATUS_NONE - - if ns == wiki.NS_TALK: - new_page = page.toggle_talk() - sleep(2) - if new_page.is_redirect: - return self.STATUS_NONE # Ignore accepted AFC/R requests - return self.STATUS_ACCEPT - - cats = self.categories - sq = self.site.sql_query - query = "SELECT 1 FROM categorylinks WHERE cl_to = ? AND cl_from = ?" - match = lambda cat: list(sq(query, (cat.replace(" ", "_"), pageid))) - - if match(cats["pending"]): - return self.STATUS_PEND - elif match(cats["unsubmitted"]): - return self.STATUS_NONE - elif match(cats["declined"]): - return self.STATUS_DECLINE - return self.STATUS_NONE - - def get_date_counts(self, date): - query = "SELECT COUNT(*) FROM page WHERE page_date = ? AND page_status = ?" - statuses = [self.STATUS_PEND, self.STATUS_DECLINE, self.STATUS_ACCEPT] - counts = {} - with self.conn.cursor() as cursor: - for status in statuses: - cursor.execute(query, (date, status)) - count = cursor.fetchall()[0][0] - counts[status] = count - return counts - - def generate_chart(self, data): - plt.title(self.graph.get("title", "AfC submissions by date")) - plt.xlabel(self.graph.get("xaxis", "Date")) - plt.ylabel(self.graph.get("yaxis", "Submissions")) - - pends = [d[self.STATUS_PEND] for d in data.itervalues()] - declines = [d[self.STATUS_DECLINE] for d in data.itervalues()] - accepts = [d[self.STATUS_ACCEPT] for d in data.itervalues()] - pends_declines = [p + d for p, d in zip(pends, declines)] - ind = arange(len(data)) - xsize = self.graph.get("xsize", 1200) - ysize = self.graph.get("ysize", 900) - width = self.graph.get("width", 1) - xstep = self.graph.get("xAxisStep", 6) - pcolor = self.graph.get("pendingColor", "#f0e460") - dcolor = self.graph.get("declinedColor", "#f291a6") - acolor = self.graph.get("acceptedColor", "#81fc4c") - - p1 = plt.bar(ind, pends, width, color=pcolor) - p2 = plt.bar(ind, declines, width, color=dcolor, bottom=pends) - p3 = plt.bar(ind, accepts, width, color=acolor, bottom=pends_declines) - - xticks = arange(xstep-1, ind.size+xstep-1, xstep) + width/2.0 - xlabels = [d for c, d in zip(count(1), data.keys()) if not c % xstep] - plt.xticks(xticks, xlabels) - plt.yticks(arange(0, plt.ylim()[1], 10)) - plt.tick_params(direction="out") - - leg = plt.legend((p1[0], p2[0], p3[0]), ("Pending", "Declined", - "Accepted"), loc="upper left", fancybox=True) - leg.get_frame().set_alpha(0.5) - - fig = plt.gcf() - fig.set_size_inches(xsize/100, ysize/100) - fig.autofmt_xdate() - - ax = plt.gca() - ax.yaxis.grid(True) + pass