Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
204 lines (184 sloc) 8.52 KB
#!/usr/bin/env python
from __future__ import unicode_literals
import datetime
import mwparserfromhell
import pywikibot
import re
site = pywikibot.Site('en', 'wikipedia')
GA_SUBPAGES = ['Agriculture, food and drink', 'Art and architecture', 'Engineering and technology',
'Geography and places', 'History', 'Language and literature', 'Mathematics', 'Music', 'Natural sciences',
'Philosophy and religion', 'Social sciences and society', 'Sports and recreation',
'Media and drama', 'Warfare', 'Video games']
ARTICLE_HISTORY = ['Article history', 'Article History', 'Article milestones', 'ArticleHistory', 'Articlehistory', 'Article milestones']
GA_TEMPLATE = ['GA', 'Ga']
('Wikipedia:Featured article candidates/Featured log', True, 'FA'),
('Wikipedia:Featured article candidates/Archived nominations', False, 'FA'),
('Wikipedia:Featured list candidates/Featured log', True, 'FL'),
('Wikipedia:Featured list candidates/Failed log', False, 'FL'),
def get_facs_to_handle(prefix):
monthyear = datetime.datetime.utcnow().strftime('%B %Y')
monthpage = pywikibot.Page(site, prefix + '/' + monthyear)
data = {}
# Assumes that log will have <100 edits
print 'Fetching log page history'
site.loadrevisions(monthpage, getText=True, rvdir=False,
step=100, total=100, startid=None)
hist = monthpage.fullVersionHistory(total=100) # This should fetch nothing...
for revision in hist:
for temp in mwparserfromhell.parse(revision[3]).filter_templates():
data[unicode(] = (revision[0], revision[1], revision[2])
return data
def promote_fac(fac_name, rev_info, was_promoted, featured_type='FA'):
pg = pywikibot.Page(site, fac_name)
article_title = fac_name.split('/')[1]
oldid = rev_info[0]
c_abbr = featured_type + 'C' # Either 'FLC' or 'FAC'
is_fa = featured_type == 'FA'
timestamp = rev_info[1].strftime('%H:%M, %d %B %Y (UTC)')
username = rev_info[2]
text = pg.get()
if was_promoted:
prom_text = 'promoted'
prom_text = 'not promoted'
if '<!--FAtop-->' in text or '<!--FLtop-->' in text:
# Already handled
print '%s has already been handled, skipping.' % fac_name
print unicode(fac_name), oldid
if is_fa:
top_text = "{{{{subst:Fa top|result='''{prom}''' by [[User:{user}|{user}]] {ts} " \
.format(user=username, ts=timestamp, oldid=oldid, prom=prom_text)
bottom_text = '{{subst:Fa bottom}}'
top_text = '{{{{subst:User:Hahc21/FLTop|result={prom}|closer={user}|time={ts}|link=diff={oldid}]}}}}'\
.format(prom=prom_text, user=username, ts=timestamp, oldid=oldid)
bottom_text = '{{subst:User:Hahc21/FCloseBottom}}'
newtext = top_text + '\n' + text + '\n' + bottom_text
pg.put(newtext, 'Bot: Archiving ' + c_abbr)
article = pywikibot.Page(site, article_title)
article_text = article.get()
if was_promoted:
# add the FA icon, possibly removing the GA icon
needs_fa_icon = True
if is_fa:
icon = '{{featured article}}'
icon = '{{featured list}}'
if'\{\{featured\s?(small|article|list)\}\}', article_text, re.IGNORECASE):
needs_fa_icon = False
new_article_text = None # Shut up PyCharm
elif'\{\{(good|ga) article\}\}', article_text, re.IGNORECASE):
new_article_text = re.sub('\{\{(good|ga) article\}\}', icon, article_text, flags=re.IGNORECASE)
new_article_text = icon + '\n' + article_text
if needs_fa_icon:
article.put(new_article_text, 'Bot: Adding '+icon)
latest_rev = pywikibot.Page(site, article_title).latestRevision()
article_talk = article.toggleTalkPage()
article_talk_text = article_talk.get()
if was_promoted:
current_status = featured_type # 'FA' or 'FL'
current_status = 'F' + c_abbr # 'FFAC' or 'FFLC'
has_article_history = False
parsed = mwparserfromhell.parse(article_talk_text)
# First we're going to do a preliminary check for {{GA}} and stuffs.
pre_stuff_params = {}
for temp in parsed.filter_templates():
for ga_name in GA_TEMPLATE:
pre_stuff_params[''] = 'GAN'
pre_stuff_params['date'] = temp.get(1).value
pre_stuff_params['result'] = 'promoted' # Safe to assume?
pre_stuff_params['link'] = article_talk.title() + '/GA' + unicode(temp.get('page').value)
for param in ['topic', 'oldid']:
pre_stuff_params[param] = temp.get(param).value
for temp in parsed.filter_templates():
# This might have some false positives, may need adjusting later.
if was_promoted and temp.has_param('class'):
temp.get('class').value = featured_type
for ah_name in ARTICLE_HISTORY:
has_article_history = True
num = 1
while temp.has_param('action' + str(num)):
num += 1
for param in pre_stuff_params:
if param == 'topic':
temp.add('topic', pre_stuff_params['topic'])
temp.add('action'+str(num)+param, pre_stuff_params[param])
num += 1
action_prefix = 'action' + str(num)
temp.add(action_prefix, c_abbr)
temp.add(action_prefix+'date', timestamp.replace(' (UTC)', ''))
temp.add(action_prefix+'link', fac_name)
temp.add(action_prefix+'result', prom_text)
temp.add(action_prefix+'oldid', latest_rev)
if temp.has('currentstatus', ignore_empty=False):
if was_promoted or temp.get('currentstatus').value != 'GA':
temp.get('currentstatus').value = current_status
temp.add('currentstatus', current_status)
article_talk_text = unicode(parsed)
if not has_article_history:
article_history_text = mwparserfromhell.parse('{{Article history}}')
temp = article_history_text.filter_templates()[0]
for param in pre_stuff_params:
if param == 'topic':
temp.add('topic', pre_stuff_params[param])
temp.add('action1'+param, pre_stuff_params[param])
new_params = {
'action2': c_abbr,
'action2date': timestamp,
'action2link': fac_name,
'action2result': prom_text,
'action2oldid': latest_rev,
'currentstatus': current_status,
for param in new_params:
temp.add(param, new_params[param])
article_talk_text = unicode(article_history_text) + article_talk_text
article_talk_text = re.sub('\{\{(featured (list|article) candidates|ga)\s*\|.*?\}\}', '', article_talk_text,
article_talk.put(unicode(article_talk_text).strip(), 'Bot: Updating {{Article history}} after ' + c_abbr)
if was_promoted and is_fa:
print 'Checking GA listings...'
# Only FA's can be GA's, not FL's.
def update_ga_listings(article):
This whole function is pretty bad.
We can optimize checking all the subpages by doing a db query
on the pagelinks table and only look for subpages of "WP:GA"
for subj in GA_SUBPAGES:
pg = pywikibot.Page(site, 'Wikipedia:Good articles/' + subj)
if pg.isRedirectPage():
pg = pg.getRedirectTarget()
text = pg.get()
if not article in text:
# This part is weird, but meh
lines = text.splitlines()
for line in lines[:]:
if article in line:
pg.put('\n'.join(lines), 'Bot: Removing [[%s]] since it was promoted to FA' % article)
if __name__ == '__main__':
for prefix, was_promoted, featured_type in STUFF_TO_PROCESS:
facs = get_facs_to_handle(prefix)
for fac, rev_info in facs.iteritems():
if fac == 'TOClimit':
promote_fac(fac, rev_info, was_promoted=was_promoted, featured_type=featured_type)