Utilisateur:Darkoneko/ImageLinkErasor.py

Une page de Wikipédia, l'encyclopédie libre.
# -*- coding: utf-8 -*-
# this script deletes any calls to deleted images. Image list is fetched from the deletion log. 
# Distributed under the terms of the PSF license.

# Auteurs : Dake (2005) ; Darkoneko (aout 2006), Bayo (dec 2006), Phe (janvier 2007), Louperivois (mai 2007)
#(v2) refonte pour utiliser /w/api.php, fusion avec le script listant les images : fr:user:Darkoneko (avril 2008 + )
#(v3) refonte pour utiliser directement la classe de replace.py et les nouveaux generateurs de pywikipediabot (oct 2010 + )
#Version en cours : 3.2 - 24/10/2010
 
import pagegenerators, wikipedia as pywikibot
import config, sys, urllib, replace
from xml.dom.minidom import parse, parseString

#========================================== PARAMETRES ========================
#Namespaces in which we can remove dead media links. pour faire des tests, créez une sous page user et autorisez le namespace 2
allowedNamespaces = [
#'2',
  '0', # (main)
  '10', #template
  '12', #aide
  '14', #category
  '100', #portal
  '102', #projet
  '104' #reference
]
#===============================================================================


#phe janvier 2007
def build_regex_from_title(title):
    result = u''
    for ch in title:
        if ch in u'()*.': # |[] is invalid in title no need to quote it
            result += u'\\'
        result += ch
    result = result.replace(u' ', u'[ _]?')
    result = u'[' + result[0].lower() + result[0].upper() + u']' + result[1:]
    return result


#create the regex that will be used to delete image call occurences and return them as a list
def create_regexes(img) :
    regexed_image = build_regex_from_title(img)   

    #cas du genre [[ Image : blabla.gif]] qui reviennent souvent
    regexed_namespace = u'[ _]*(?:image|m[ée]dia|fi(?:chier|le))[ _]*:[ _]*'

    #liens du type [[ Image : blabla.gif | blablabla [[eventuel lien]] ]]
    regexp = '(?i)\[\[%s%s.*?(\[\[.*?\]\].*?)*\]\]' % (regexed_namespace, regexed_image)

    #ce regex repere les lignes du type "Image:blablabla|commentaire" que contiennent les <gallery>.
    #un \n est ajouté lors du remplacement pour pallier au fait qu'il y en ai 2 detectés par la regex
    regexpTagNoLinkGallery = '(?i)\n%s%s\s*(:?\|[^\n]*)*\n' % (regexed_namespace, regexed_image)
    replaceTagNoLinkGallery = u'\n'

    #ce regex detecte les <gallery> vides et les <center> vides (regulierement present autour des images, j'ai remarqué)
    regexpEmptyGallery = '(?i)<gallery>\s*</gallery>'
    regexpEmptyCenter = '(?i)<center>\s*</center>'

    #ce regex detecte si l'image a été passée en parametre à un modele
    #possibilités : |Image:blabla.jpg ; |blabla.jpg ; |img=Image:blabla.jpg ; |img=blabla.jpg
    regexpNoTag = u'(?P<beforeZone>\||=)\s*(?:%s|)%s\s*' % ( regexed_namespace, regexed_image)
    replaceNoTag = r'\g<beforeZone>' 

    #ce regex detecte les {{son}} et {{listen}} dont le 2eme parametre (le nom du fichier) est maintenant vide
    regexpSound = '{{\s*([Ss]on|[Ll]isten)[\n\s]*\|[^\|}]+\|[\n\s]*}}'

    return [
      (regexp, u''),
      (regexpTagNoLinkGallery, replaceTagNoLinkGallery), 
      (regexpNoTag, replaceNoTag), 
      (regexpEmptyGallery, u''),
      (regexpEmptyCenter, u''), 
      (regexpSound, u''), 
    ]


#get the pages containing a link of any sort to the image.
def get_related_pages(nom_image) :
    url = u"/w/api.php?format=xml&action=query&list=imageusage&iutitle=%s&iunamespace=%s" % (urllib.quote(nom_image.encode("utf-8")), "|".join(allowedNamespaces) )
    res = pywikibot.getSite().getUrl(url)
    xm = parseString( res.encode( "utf-8" ) )
    relpages = [] 
    for node in xm.documentElement.getElementsByTagName("iu") : 
	relpages.append(node.getAttribute('title') )
    return relpages


#test the non-existence of an image. If it exists on commons or was restored, return True.
def image_exists(nom_image):
    url = u"/w/api.php?format=xml&action=query&prop=imageinfo&titles=%s" % urllib.quote(nom_image.encode("utf-8"))
    res = pywikibot.getSite().getUrl(url)
    xm = parseString( res.encode( "utf-8" ) )
    if len( xm.documentElement.getElementsByTagName("page")[0].getAttribute('imagerepository') ) != 0 :
	return True
    return False

#get the image list. It's not possible to limit the API to namespace:6 for logs so we have to filter ourselves.
def get_deleted_images_list() :
    logUrl = "/w/api.php?format=xml&action=query&letype=delete&list=logevents&leprop=title&lelimit=500"
    res = pywikibot.getSite().getUrl(logUrl)
    xm = parseString( res.encode( "utf-8" ) )
    liste = []
    for node in xm.documentElement.getElementsByTagName("item") : 
	if node.getAttribute('ns') == '6' :
	    liste.append(node.getAttribute('title') )  
    return liste



listInput = get_deleted_images_list() 

pywikibot.output(u"%s images were found in the last 500 deletions. " % len(listInput) ) 

for image in listInput :
    nom_image = urllib.unquote(image.strip())

    if image_exists(nom_image) : 
	continue #the image was either restored or exists on commons.

    relatedPagesList = get_related_pages(nom_image)
    nb_related_pages = len(relatedPagesList)
    if nb_related_pages == 0: 
	continue #no links to that image. go to next one.
      
    pywikibot.output(u"%s lien(s) trouvé(s) vers %s" % (nb_related_pages, nom_image) )	

    replaceList = create_regexes(nom_image[8:])
    pywikibot.setAction(u"Robot: retrait lien vers média effacé (%s) + ménage éventuel" % nom_image)
    pagegen = pagegenerators.PagesFromTitlesGenerator( relatedPagesList )
    bot = replace.ReplaceRobot( pagegen, replaceList, [], acceptall=True)
    bot.run()