User:Jitse's bot/afc.py

From Wikipedia, the free encyclopedia

# Bot for archiving [[Wikipedia:Articles for creation]] on the English
# Wikipedia. 
#
# Written by [[User:Jitse Niesen]].
# Based on a previous version by [[User:Fetofs]].

import os, re, sys, datetime, time
sys.path.append(os.getcwd())
import wikipedia
from wikipedia import Page

import config
config.maxlag = None                    # to prevent edit conflicts

site = wikipedia.Site("en", "wikipedia")
afc = "Articles for creation"
summary_prefix = "Daily edit: "
if os.access("logs/afc", os.R_OK):
    os.rename("logs/afc", "logs/afc.old")
wikipedia.setLogfileStatus(True, "afc")


# ----------
# Move [[Wikipedia:Articles for creation/Today]]
# to [[Wikipedia:Articles for creation/YYYY-MM-DD]] 
# ----------

now = datetime.datetime.utcnow()
todaypage = Page(site, '%s:%s/Today' % (site.namespace(4), afc))
archive = '%s:%s/%s' % (site.namespace(4), afc,
                        (now-datetime.timedelta(1)).strftime('%Y-%m-%d'))
summary = summary_prefix + 'Archiving'
if todaypage.move(archive, summary, movetalkpage = False) == False:
    wikipedia.stopme()
    raise RuntimeError('Page move failed')

# ----------
# Replace the redirect created by the move with a generic header
# ----------

todaypage = Page(site, '%s:%s/Today' % (site.namespace(4), afc))
headerpage = '%s:%s/Daily header' % (site.namespace(4), afc)
text = '{{' + headerpage + '}}\n'
summary = summary_prefix + 'Replace redirect with header'
todaypage.put(text, summary)

# ----------
# Add text in [[Wikipedia:Articles for creation/Archive header]] at the top
# of the archive page, replace "[[Category:" with "[[:Category:", and make
# template inactive by replacing "{{..." with "{{tlx|..."
# ----------

header = '%s:%s/Archive header' % (site.namespace(4), afc)
headertext = Page(site, header).get()

for attempts in range(5):
    archivepage = Page(site, archive)
    try:
        archivetext = archivepage.get()
        break
    except wikipedia.NoPage:
        # The page move may take some time, so try again
        print "Got a NoPage when getting archive page (attempt %d)" % (attempts+1)
        time.sleep(2**attempts*60)
else:
    raise RuntimeError('Could not get archive page')

summary = summary_prefix + 'Add header to archive page'

c = archivetext.count("[[Category:")
if c:
    archivetext = archivetext.replace("[[Category:", "[[:Category:")
    if c == 1:
        summary = summary + ", remove 1 category"
    else:
        summary = summary + ", remove %d categories" % c
(new,c) = re.subn(r'(?<!{)'
                  + r'{{'
                  + r'(?![#{]|tl\||tlx\||afc |Wikipedia:Articles for creation/Daily header)',
                  r'{{tlx|', archivetext)

if c:
    archivetext = new
    if c == 1:
        summary = summary + ", defang 1 template"
    else:
        summary = summary + ", defang %d templates" % c

archivepage.put(headertext + archivetext, summary)

# ----------
# Edit [[Wikipedia:Articles for creation/List]] and add the day's
# archive to the top of the page 
# ----------

listpage = Page(site, '%s:%s/List' % (site.namespace(4), afc))
newtext = '* [[%s]] — archive made at %s [[UTC]] on [[%s]]\n' \
           % (archive, now.strftime('%H:%M'), now.strftime('%Y-%m-%d'))
newtext = newtext + listpage.get()
summary = summary_prefix + 'Listing archive page'
listpage.put(newtext, summary)

# ----------
# Check whether script on [[User:Jitse's bot/afc.py]] is up-to-date, and 
# update with current version if necessary
# ----------

scriptpage = Page(site, "User:Jitse's bot/afc.py")
text = file('afc.py').read()
text = '<pre><nowiki>\n' + text + '</no' + 'wiki></p' + 're>' # Split to confuse MW parser
if scriptpage.get() != text:
    summary = summary_prefix + 'Update script'
    scriptpage.put(text, summary)

# ----------
# Epilogue
# ----------

wikipedia.stopme()
if now.day == 1:
    print "REMINDER: First day of month; can archive [[%s]]" % listpage.title()