Browse Source

afc_statistics: Split up charts into different pages

main
Ben Kurtovic 5 years ago
parent
commit
cf8e6d38bb
2 changed files with 49 additions and 26 deletions
  1. +43
    -21
      tasks/afc_statistics.py
  2. +6
    -5
      tasks/schema/afc_statistics.sql

+ 43
- 21
tasks/afc_statistics.py View File

@@ -20,6 +20,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE. # SOFTWARE.


from collections import OrderedDict
from datetime import datetime from datetime import datetime
import re import re
from os.path import expanduser from os.path import expanduser
@@ -33,13 +34,27 @@ from earwigbot import exceptions
from earwigbot import wiki from earwigbot import wiki
from earwigbot.tasks import Task from earwigbot.tasks import Task


_DEFAULT_PAGE_TEXT = """<noinclude><!-- You can edit anything on this page \
except for content inside of <!-- stat begin/end -> and <!-- sig begin/end -> \
without causing problems. Most of the chart can be modified by editing the \
templates it uses, documented in [[Template:AFC statistics/doc]]. -->
{{NOINDEX}}</noinclude>
<!-- stat begin --><!-- stat end -->
<span style="font-style: italic; font-weight: bold;">Last updated by \
{{#ifeq:{{REVISIONUSER:Template:AFC statistics}}|EarwigBot|<!-- sig begin -->\
<!-- sig end -->|{{User|{{REVISIONUSER:Template:AFC statistics}}}} at \
{{#time:H:i, j F Y "(UTC)"|{{REVISIONTIMESTAMP:Template:AFC statistics}}}}}}\
</span><noinclude>
{{Documentation}}</noinclude>
"""

class AFCStatistics(Task): class AFCStatistics(Task):
"""A task to generate statistics for WikiProject Articles for Creation. """A task to generate statistics for WikiProject Articles for Creation.


Statistics are stored in a MySQL database ("u_earwig_afc_statistics") Statistics are stored in a MySQL database ("u_earwig_afc_statistics")
accessed with oursql. Statistics are synchronied with the live database 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" name = "afc_statistics"
number = 2 number = 2
@@ -58,7 +73,7 @@ class AFCStatistics(Task):
self.revision_cache = {} self.revision_cache = {}


# Set some wiki-related attributes: # 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.pending_cat = cfg.get("pending", "Pending AfC submissions")
self.ignore_list = cfg.get("ignoreList", []) self.ignore_list = cfg.get("ignoreList", [])
default_summary = "Updating statistics for [[WP:WPAFC|WikiProject Articles for creation]]." 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. """Save our local statistics to the wiki.


After checking for emergency shutoff, the statistics chart is compiled, 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") self.logger.info("Saving chart")
if kwargs.get("fromIRC"): if kwargs.get("fromIRC"):
@@ -124,43 +139,50 @@ class AFCStatistics(Task):
summary = self.summary summary = self.summary


statistics = self._compile_charts() 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"<!-- stat begin -->(.*?)<!-- stat end -->", newtext = re.sub(u"<!-- stat begin -->(.*?)<!-- stat end -->",
"<!-- stat begin -->\n" + statistics + "\n<!-- stat end -->",
"<!-- stat begin -->\n" + chart + "\n<!-- stat end -->",
text, flags=re.DOTALL) text, flags=re.DOTALL)
if newtext == text: 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("<!-- sig begin -->(.*?)<!-- sig end -->", newtext = re.sub("<!-- sig begin -->(.*?)<!-- sig end -->",
"<!-- sig begin -->~~~ at ~~~~~<!-- sig end -->", "<!-- sig begin -->~~~ at ~~~~~<!-- sig end -->",
newtext) newtext)
page.edit(newtext, summary, minor=True, bot=True) 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): def _compile_charts(self):
"""Compile and return all statistics information from our local db.""" """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") cursor.execute("SELECT * FROM chart")
for chart in cursor: 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): def _compile_chart(self, chart_info):
"""Compile and return a single statistics chart.""" """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 + "}}" chart = "{{" + chart + "}}"


query = "SELECT * FROM page JOIN row ON page_id = row_id WHERE row_chart = ?" query = "SELECT * FROM page JOIN row ON page_id = row_id WHERE row_chart = ?"
with self.conn.cursor(oursql.DictCursor) as cursor: 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(): for page in cursor.fetchall():
chart += "\n" + self._compile_chart_row(page) chart += "\n" + self._compile_chart_row(page)




+ 6
- 5
tasks/schema/afc_statistics.sql View File

@@ -15,6 +15,7 @@ CREATE DATABASE `u_earwig_afc_statistics`
DROP TABLE IF EXISTS `chart`; DROP TABLE IF EXISTS `chart`;
CREATE TABLE `chart` ( CREATE TABLE `chart` (
`chart_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT, `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_title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`chart_special_title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `chart_special_title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`chart_id`) PRIMARY KEY (`chart_id`)
@@ -26,11 +27,11 @@ CREATE TABLE `chart` (


LOCK TABLES `chart` WRITE; LOCK TABLES `chart` WRITE;
INSERT INTO `chart` VALUES 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; UNLOCK TABLES;


-- --


Loading…
Cancel
Save