diff --git a/tasks/afc_statistics.py b/tasks/afc_statistics.py
index 9bf33fa..9c75f94 100644
--- a/tasks/afc_statistics.py
+++ b/tasks/afc_statistics.py
@@ -20,6 +20,7 @@
# 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
import re
from os.path import expanduser
@@ -33,13 +34,27 @@ from earwigbot import exceptions
from earwigbot import wiki
from earwigbot.tasks import Task
+_DEFAULT_PAGE_TEXT = """
+{{NOINDEX}}
+
+Last updated by \
+{{#ifeq:{{REVISIONUSER:Template:AFC statistics}}|EarwigBot|\
+|{{User|{{REVISIONUSER:Template:AFC statistics}}}} at \
+{{#time:H:i, j F Y "(UTC)"|{{REVISIONTIMESTAMP:Template:AFC statistics}}}}}}\
+
+{{Documentation}}
+"""
+
class AFCStatistics(Task):
"""A task to generate statistics for WikiProject Articles for Creation.
Statistics are stored in a MySQL database ("u_earwig_afc_statistics")
accessed with oursql. Statistics are synchronied with the live database
- every four minutes and saved once an hour, on the hour, to self.pagename.
- In the live bot, this is "Template:AFC statistics".
+ every four minutes and saved once an hour, on the hour, to subpages of
+ self.pageroot. In the live bot, this is "Template:AFC statistics".
"""
name = "afc_statistics"
number = 2
@@ -58,7 +73,7 @@ class AFCStatistics(Task):
self.revision_cache = {}
# Set some wiki-related attributes:
- self.pagename = cfg.get("page", "Template:AFC statistics")
+ self.pageroot = cfg.get("page", "Template:AFC statistics")
self.pending_cat = cfg.get("pending", "Pending AfC submissions")
self.ignore_list = cfg.get("ignoreList", [])
default_summary = "Updating statistics for [[WP:WPAFC|WikiProject Articles for creation]]."
@@ -112,8 +127,8 @@ class AFCStatistics(Task):
"""Save our local statistics to the wiki.
After checking for emergency shutoff, the statistics chart is compiled,
- and then saved to self.pagename using self.summary iff it has changed
- since last save.
+ and then saved to subpages of self.pageroot using self.summary iff it
+ has changed since last save.
"""
self.logger.info("Saving chart")
if kwargs.get("fromIRC"):
@@ -124,43 +139,50 @@ class AFCStatistics(Task):
summary = self.summary
statistics = self._compile_charts()
+ for name, chart in statistics.iteritems():
+ self._save_page(name, chart)
+
+ def _save_page(self, name, chart):
+ """Save a statistics chart to a single page."""
+ page = self.site.get_page(u"{}/{}".format(self.pageroot, name))
+ try:
+ text = page.get()
+ except exceptions.PageNotFoundError:
+ text = _DEFAULT_PAGE_TEXT
- page = self.site.get_page(self.pagename)
- text = page.get()
newtext = re.sub(u"(.*?)",
- "\n" + statistics + "\n",
+ "\n" + chart + "\n",
text, flags=re.DOTALL)
if newtext == text:
- self.logger.info("Chart unchanged; not saving")
- return # Don't edit the page if we're not adding anything
+ self.logger.info(u"Chart for {} unchanged; not saving".format(name))
+ return
newtext = re.sub("(.*?)",
"~~~ at ~~~~~",
newtext)
page.edit(newtext, summary, minor=True, bot=True)
- self.logger.info(u"Chart saved to [[{0}]]".format(page.title))
+ self.logger.info(u"Chart for {} saved to [[{}]]".format(name, page.title))
def _compile_charts(self):
"""Compile and return all statistics information from our local db."""
- stats = ""
- with self.conn.cursor() as cursor:
+ stats = OrderedDict()
+ with self.conn.cursor(oursql.DictCursor) as cursor:
cursor.execute("SELECT * FROM chart")
for chart in cursor:
- stats += self._compile_chart(chart) + "\n"
- return stats[:-1] # Drop the last newline
+ name = chart['chart_name']
+ stats[name] = self._compile_chart(chart)
+ return stats
def _compile_chart(self, chart_info):
"""Compile and return a single statistics chart."""
- chart_id, chart_title, special_title = chart_info
-
- chart = self.tl_header + "|" + chart_title
- if special_title:
- chart += "|" + special_title
+ chart = self.tl_header + "|" + chart_info['chart_title']
+ if chart_info['chart_special_title']:
+ chart += "|" + chart_info['chart_special_title']
chart = "{{" + chart + "}}"
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,))
+ cursor.execute(query, (chart_info['chart_id'],))
for page in cursor.fetchall():
chart += "\n" + self._compile_chart_row(page)
diff --git a/tasks/schema/afc_statistics.sql b/tasks/schema/afc_statistics.sql
index eaf0e95..8e3ba8b 100644
--- a/tasks/schema/afc_statistics.sql
+++ b/tasks/schema/afc_statistics.sql
@@ -15,6 +15,7 @@ CREATE DATABASE `u_earwig_afc_statistics`
DROP TABLE IF EXISTS `chart`;
CREATE TABLE `chart` (
`chart_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
+ `chart_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`chart_title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`chart_special_title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`chart_id`)
@@ -26,11 +27,11 @@ CREATE TABLE `chart` (
LOCK TABLES `chart` WRITE;
INSERT INTO `chart` VALUES
-(1,'Pending submissions','Submitted'),
-(3,'Being reviewed','Reviewer'),
-(4,'Recently accepted','Accepted'),
-(5,'Recently declined','Declined'),
-(6,'Misplaced submissions','Created');
+(1,'pending','Pending submissions','Submitted'),
+(3,'reviewing','Being reviewed','Reviewer'),
+(4,'accepted','Recently accepted','Accepted'),
+(5,'declined','Recently declined','Declined'),
+(6,'created','Misplaced submissions','Created');
UNLOCK TABLES;
--