User:Caesar Schinas/pwb/cg_inactiveeditor.py

From Citizendium
< User:Caesar Schinas
Revision as of 09:21, 4 September 2009 by imported>Daniel Mietchen (further bug fix)
Jump to navigation Jump to search

This is a PWB script which I wrote to automatically enforce CZ:Editorial Council Resolution 0012 by moving editors who haven't made a single edit in the last 3 months, or less than 500 over the last year, to the Inactive Editor categories.

#!/usr/bin/python
# -*- coding: utf-8	 -*-

# Copyright © 2009 Caesar Schinas.
# Released under the CC-by-nc-sa-3.0 licence (http://creativecommons.org/licenses/by-nc-sa/3.0/).
# May be distributed and modified under the following condtions :
# (by) Attribution must be given to Caesar Schinas in all distributions and derivatives.
# (nc) Commercial use is prohibited except with prior written permission from Caesar Schinas.
# (sa) Derivative works must be released under the same licence and conditions.

"""
This bot enforces [[CZ:Editorial Council Resolution 0012]] by moving editors who
haven't made any edits in the last 3 months to the Inactive Editor categories.

The following parameters are supported:

-start            Start checking usernames alphabetically from this point,
                  instead of starting from the beginning.

-always           Don't ask each time before changing editor categories;
                  just do it anyway.

-debug            Don't actually change any editor categories; just show
                  what would have been chnaged.

"""
__version__ = '$Id: cg_inactiveeditor.py 0 2009-06-30 00:20:00 caesarsgrunt $'
import time, re
import wikipedia, catlib, pagegenerators, query

class InactiveEditorBot:
	# Edit summary
	msg = {
		'en': u'Robot: Changing category from Editor to Inactive Editor, per [[CZ:Editorial Council Resolution 0012]]. You are very welcome to revert this edit if you plan to contribute further to the project.',
	}

	def __init__(self, generator, debug, always, depth=500):
		self.generator = generator
		self.debug = debug
		self.always = always
		self.prev = None
		
	
	def run(self):
		# Set the edit summary message
		wikipedia.setAction(wikipedia.translate(wikipedia.getSite(), self.msg))
		for page in self.generator:
			self.check(page)
		
	
	def check(self, user):
		wikipedia.output(u"\n\n>>> \03{lightpurple}%s\03{default} <<<" % user.title())
		data = query.GetData({'action':'query', 'list':'usercontribs', 'ucuser':user.title(), 'uclimit':'500', 'ucprop':'timestamp'}, useAPI = True, encodeTitle = False)
		try :
			date = data['query']['usercontribs'][0]['timestamp']
			lastaction = u"Last edit was"
		except IndexError :
			wikipedia.output(u"No edits.")
			data = query.GetData({'action':'query', 'list':'users', 'ususers':user.title(), 'usprop':'registration'}, useAPI = True, encodeTitle = False)
			try :
				date = data['query']['users'][0]['registration']
				lastaction = u"Account created"
			except KeyError : return
		except KeyError : return
		
		edit = time.mktime(time.strptime(date, "%Y-%m-%dT%H:%M:%SZ"))
		daysago = (time.time() - edit) / 86400
		
		wikipedia.output(u"%s %.0f days ago." % (lastaction, daysago))
		
		if daysago <= 93 : return
		
		try :
			date = data['query']['usercontribs'][499]['timestamp']
			lastaction = u"500th last edit was"
			edit = time.mktime(time.strptime(date, "%Y-%m-%dT%H:%M:%SZ"))
			daysago = (time.time() - edit) / 86400
			wikipedia.output(u"%s %.0f days ago." % (lastaction, daysago))
			if daysago <= 366 : return
		except IndexError :
			wikipedia.output(u"Less than 500 edits.")
		except KeyError : return
		
		self.deactivate(user)
		
	
	def deactivate(self, user):
		username = user.titleWithoutNamespace()
		# Remove disambig brackets, if any, from end of name.
		match = re.compile('(.*) \(.+?\)').match(username)
		if match : username = match.group(1)
		# Last name first
		words = username.split(' ')
		if len(words) > 1 : sort = words[-1] + ', ' + ' '.join(words[:-1])
		else : sort = user.titleWithoutNamespace()

		oldcats = user.categories()
		newcats = []
		for i in range(len(oldcats)) :
			oldcat = oldcats[i]
			if oldcat.title().endswith("Editors") :
				newcat = catlib.Category(wikipedia.getSite(), 'Category:Inactive '+oldcat.titleWithoutNamespace(), sortKey=sort.strip())
				newcats.append(newcat)
			else :
				newcats.append(oldcat)
		
		wikipedia.showDiff("\n".join([oldcat.aslink() for oldcat in oldcats]), "\n".join([newcat.aslink() for newcat in newcats]))
		
		# If -debug is set, we don't need to do anything more.
		if self.debug :
			return
		
		# Confirm that we should create the page (unless -always is set).
		if not self.always :
			choice = wikipedia.inputChoice(u'Do you want to make the above changes?', ['Yes', 'No'], ['Y', 'N'], 'N')
			if not choice == 'y' :
				return
		
		oldtext = user.get()
		newtext = wikipedia.replaceCategoryLinks(oldtext, newcats)
		
		try:
			user.put(newtext)
		except wikipedia.LockedPage:
			wikipedia.output(u"Page %s is locked; skipping." % page.aslink())
		except wikipedia.EditConflict:
			wikipedia.output(u'Skipping %s because of edit conflict' % (page.title()))
		except wikipedia.SpamfilterError, error:
			wikipedia.output(u'Cannot change %s because of spam blacklist entry %s' % (page.title(), error.url))
		

def main():
	start = '!'
	debug = False
	always = False

	# Parse command line arguments
	for arg in wikipedia.handleArgs():
		if arg.startswith("-start"):
			start = arg[7:]
		elif arg.startswith("-debug"):
			debug = True
		elif arg.startswith("-always"):
			always = True

	gen = pagegenerators.PreloadingGenerator(pagegenerators.CategorizedPageGenerator(catlib.Category(wikipedia.getSite(),'CZ Editors'), start=start))
	bot = InactiveEditorBot(gen, debug, always)
	bot.run()
	

if __name__ == "__main__":
	try:
		main()
	finally:
		wikipedia.stopme()