Browse Source

Statistics chart generation from MySQL is ready!

tags/v0.1^2
Ben Kurtovic 12 years ago
parent
commit
c6b3827f6b
2 changed files with 79 additions and 16 deletions
  1. +77
    -15
      bot/tasks/afc_statistics.py
  2. +2
    -1
      bot/wiki/site.py

+ 77
- 15
bot/tasks/afc_statistics.py View File

@@ -1,7 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-


import re import re
from os import path
from os.path import expanduser
from time import strftime, strptime

import oursql


from classes import BaseTask from classes import BaseTask
import config import config
@@ -10,22 +13,32 @@ import wiki
class Task(BaseTask): class Task(BaseTask):
"""A task to generate statistics for WikiProject Articles for Creation. """A task to generate statistics for WikiProject Articles for Creation.


Statistics are stored in the file indicated by self.filename,
"statistics.txt" in the bot's root directory being the default. They are
updated live while watching the recent changes IRC feed.

The bot saves its statistics once an hour, on the hour, to self.pagename.
Statistics are stored in a MySQL database ("u_earwig_afc_statistics")
accessed with oursql. Statistics are updated live while watching the recent
changes IRC feed and saved once an hour, on the hour, to self.pagename.
In the live bot, this is "Template:AFC statistics". In the live bot, this is "Template:AFC statistics".
""" """
name = "afc_statistics" name = "afc_statistics"
number = 2 number = 2


def __init__(self): def __init__(self):
self.filename = path.join(config.root_dir, "statistics.txt")
self.cfg = config.tasks.get(self.name, {}) self.cfg = config.tasks.get(self.name, {})

# Set some wiki-related attributes:
self.pagename = cfg.get("page", "Template:AFC statistics") self.pagename = cfg.get("page", "Template:AFC statistics")
default = "Updating statistics for [[WP:WPAFC|WikiProject Articles for creation]]."
self.summary = self.make_summary(cfg.get("summary", default))
default_summary = "Updating statistics for [[WP:WPAFC|WikiProject Articles for creation]]."
self.summary = self.make_summary(cfg.get("summary", default_summary))

# Templates used in chart generation:
templates = cfg.get("templates", {})
self.tl_header = templates.get("header", "AFC statistics/header")
self.tl_row = templates.get("row", "AFC statistics/row")
self.tl_footer = templates.get("footer", "AFC statistics/footer")

# Establish a connection with our SQL database:
kwargs = cfg.get("sql", {})
kwargs["read_default_file"] = expanduser("~/.my.cnf")
self.conn = oursql.connect(**kwargs)


def run(self, **kwargs): def run(self, **kwargs):
self.site = wiki.get_site() self.site = wiki.get_site()
@@ -50,13 +63,12 @@ class Task(BaseTask):
method(page) method(page)


def save(self): def save(self):
self.check_integrity()

if self.shutoff_enabled(): if self.shutoff_enabled():
return return
try:
with open(self.filename) as fp:
statistics = fp.read()
except IOError:
pass

statistics = self.compile_charts()


page = self.site.get_page(self.pagename) page = self.site.get_page(self.pagename)
text = page.get() text = page.get()
@@ -68,7 +80,57 @@ class Task(BaseTask):


newtext = re.sub("(<!-- sig begin -->)(.*?)(<!-- sig end -->)", newtext = re.sub("(<!-- sig begin -->)(.*?)(<!-- sig end -->)",
"\\1~~~ at ~~~~~\\3", newtext) "\\1~~~ at ~~~~~\\3", newtext)
page.edit(newtext, self.summary, minor=True)
page.edit(newtext, self.summary, minor=True, bot=True)

def compile_charts(self):
stats = ""
with self.conn.cursor() as cursor:
cursor.execute("SELECT * FROM chart")
charts = cursor.fetchall()
for chart_info in charts:
stats += self.compile_chart(chart_info) + "\n"
return stats[:-1] # Drop the last newline

def compile_chart(self, chart_info):
chart_id, chart_title, special_title = chart_info

if special_title:
chart = "{{{0}|{1}|{2}}}".format(self.tl_header, chart_title, special_title)
else:
chart = "{{{0}|{1}}}".format(self.tl_header, chart_title)

query = "SELECT * FROM page JOIN row ON page_id = row_id WHERE row_chart = ?"
with self.conn_cursor(oursql.DictCursor) as cursor:
cursor.execute(query, chart_id)
for page in cursor:
chart += "\n" + self.compile_chart_row(page)

chart += "\n{{{0}}}".format(self.tl_footer)
return chart

def compile_chart_row(self, page):
row = "{{{0}|s={page_status}|t={page_title}|h={page_short}|z={page_size}|"
row += "cr={page_create_user}|cd={page_create_time}|ci={page_create_oldid}|"
row += "mr={page_modify_user}|md={page_modify_time}|mi={page_modify_oldid}|"

page["page_create_time"] = format_timestamp(page["page_create_time"])
page["page_modify_time"] = format_timestamp(page["page_modify_time"])

if page["page_special_user"]:
row += "sr={page_special_user}|sd={page_special_time}|si={page_special_oldid}|"
page["page_special_time"] = format_timestamp(page["page_special_time"])

if page["page_notes"]:
row += "n=1{page_notes}"

row += "}}"
return row.format(self.tl_row, **page)

def format_timestamp(self, ts):
return strftime("%H:%M, %d %B %Y", strptime(ts, "%Y-%m-%d %H:%M:%S"))

def check_integrity(self):
pass


def process_edit(self, page): def process_edit(self, page):
pass pass


+ 2
- 1
bot/wiki/site.py View File

@@ -3,6 +3,7 @@
from cookielib import CookieJar from cookielib import CookieJar
from gzip import GzipFile from gzip import GzipFile
from json import loads from json import loads
from os.path import expanduser
from re import escape as re_escape, match as re_match from re import escape as re_escape, match as re_match
from StringIO import StringIO from StringIO import StringIO
from time import sleep from time import sleep
@@ -446,7 +447,7 @@ class Site(object):
args[key] = value args[key] = value


if "read_default_file" not in args and "user" not in args and "passwd" not in args: if "read_default_file" not in args and "user" not in args and "passwd" not in args:
args["read_default_file"] = "~/.my.cnf"
args["read_default_file"] = expanduser("~/.my.cnf")


self._sql_conn = oursql.connect(**args) self._sql_conn = oursql.connect(**args)




Loading…
Cancel
Save