Преглед на файлове

A bunch of updates.

tags/v0.1^2
Ben Kurtovic преди 12 години
родител
ревизия
015eb44a89
променени са 1 файла, в които са добавени 75 реда и са изтрити 19 реда
  1. +75
    -19
      earwigbot/tasks/drn_clerkbot.py

+ 75
- 19
earwigbot/tasks/drn_clerkbot.py Целия файл

@@ -22,6 +22,8 @@

from os import expanduser
import re
from threading import RLock
from time import sleep, time

import oursql

@@ -46,9 +48,13 @@ class DRNClerkBot(Task):
def setup(self):
"""Hook called immediately after the task is loaded."""
cfg = self.config.tasks.get(self.name, {})

# Set some wiki-related attributes:
self.title = cfg.get("page", "Wikipedia:Dispute resolution noticeboard")
default_summary = "Updating $3 cases for the [[WP:DRN|dispute resolution noticeboard]]."
self.summary = self.make_summary(cfg.get("summary", default_summary))

# Templates used in chart generation:
# Templates used:
templates = cfg.get("templates", {})
self.tl_status = templates.get("status", "DR case status")
self.tl_notify_party = templates.get("notifyParty", "DRN-notice")
@@ -61,16 +67,47 @@ class DRNClerkBot(Task):
kwargs = cfg.get("sql", {})
kwargs["read_default_file"] = expanduser("~/.my.cnf")
self.conn_data = kwargs
self.db_access_lock = Lock()
self.db_access_lock = RLock()

def run(self, **kwargs):
"""Entry point for a task event."""
if not self.db_access_lock.acquire(False): # Non-blocking
self.logger.info("A job is already ongoing; aborting")
return

with self.db_access_lock:
self.logger.info(u"Starting update to [[{0}]]".format(self.title))
start = time()
conn = oursql.connect(**self.conn_data)
cases = read_database(conn)
page = self.bot.wiki.get_site().get_page(self.title)
text = page.get()
current = read_page(cases, text)
read_page(conn, cases, text)

# Work!
# Send messages!

self.save(page, cases)

def save(self, page, cases):
newtext = text = page.get()
counter = 0
for case in cases:
if case.old != case.body:
newtext = newtext.replace(case.old, case.body)
counter += 1

worktime = time() - start
if worktime < 60:
sleep(60 - worktime)
page.reload()
if page.get() != text:
log = "Someone has edited the page while we were working; restarting"
self.logger.warn(log)
return self.run()
summary = self.summary.replace("$3", str(counter))
page.edit(text, summary, minor=False, bot=True)
self.logger.info(u"Saved page [[{0}]]".format(page.title))

def read_database(self, conn):
"""Return a list of _Cases from the database."""
@@ -82,24 +119,42 @@ class DRNClerkBot(Task):
cases.append(_Case(id_, title, status))
return cases

def read_page(self, cases, text):
def read_page(self, conn, cases, text):
"""Read the noticeboard content and update the list of _Cases."""
tl_status_esc = re.escape(self.tl_status)
split = re.split("(^==\s*[^=]+?\s*==$)", text, flags=re.M|re.U)
cases = []
case = None
for item in split:
if item.startswith("=="):
if case:
cases.append(case)
case = _Case()
case.title = item[2:-2].strip()
else:
templ = re.escape(self.tl_status)
if case and re.match("\s*\{\{" + templ, item, re.U):
case.body = case.old_body = item
case.status = self.read_status(body)
if case:
cases.append(case)
for i in xrange(len(split)):
if i + 1 == len(split):
break
if not split[i].startswith("=="):
continue
title = split[i][2:-2].strip()
body = old = split[i + 1]
if not re.search("\s*\{\{" + tl_status_esc, body, re.U):
continue
status = self.read_status(body)
re_id = "<!-- EarwigBot Case ID \(please don't modify me\): (.*?) -->"
try:
id_ = re.search(re_id, body).group(1)
case = [case for case in cases if case.id == id_][0]
except (AttributeError, IndexError):
id_ = self.select_next_id(conn)
re_id2 = "(\{\{" + tl_status_esc + "(.*?)\}\})(<!-- Case ID \(please don't modify\): .*? -->)?"
repl = ur"\1 <!-- Case ID (please don't modify): {0} -->"
body = re.sub(re_id2, repl.format(id_), body)
case = _Case(id_, title, status)
cases.append(case)
case.body, case.old = body, old

def select_next_id(self, conn):
"""Return the next incremental ID for a case."""
query = "SELECT MAX(case_id) FROM case"
with conn.cursor() as cursor:
cursor.execute(query)
current = cursor.fetchone()[0]
if current:
return current + 1
return 1

def read_status(self, body):
"""Parse the current status from a case body."""
@@ -130,3 +185,4 @@ class _Case(object):
self.status = status

self.body = None
self.old = None

Зареждане…
Отказ
Запис