Usuario:Angus/plantillasip.rb

De Wikipedia, la enciclopedia libre
require './wikilib'

WDH = "Wikisource documento histórico"
PLANTILLAS_IP = {
        "Commons"         => [ 'c'       ],
        "Commonscat"      => [ 'ccat'    ],
        "Wikibooks"       => [ 'b'       ],
        "Wikiquote"       => [ 'q'       ],
        "Wiktionarypar"   => [ 'wikt'    ],
        "Wiktionary"      => [ 'wikt'    ],
        "Wikisource"      => [ 's'       ],
        "Wikisource autor"=> [ 's', 's_preposicion=de'   ],
         WDH =>              [ 's',
                               's_objeto=el texto de este documento histórico:',
                               's_preposicion=<nowiki/>' ],
        "Wikisource obra" => [ 's',  's_objeto=una copia',
                               's_preposicion=de'        ],
}

todas = []
pr = ProyectoWikimedia.new "es.wikipedia.org"
pr.login_user(*load_auth('Bot', pr))

if ARGV.shift == "decero"
    PLANTILLAS_IP.each_key do |plantilla|
            puts "Plantilla:#{plantilla}.embedded_in..."
            todas.concat(pr.who_embeds("Plantilla:" + plantilla, ""))
    end
    todas.reject! {|titulo| titulo =~ /^\d+$/ }  # malditos años
    todas.sort!
    todas.uniq!

    File.open "lista", "w" do |f|
        f.puts todas
    end
end

porhacer = File.readlines("lista").map {|i| i.chomp }
hechas = File.readlines("hechas").map {|i| i.chomp } rescue []

porhacer = porhacer - hechas

#porhacer = ["Usuario:Angus/ref"]

def hecha pag
    File.open "hechas", "a" do |f|
        f.puts pag
    end
end

def seccion_ee secc
    secc.nivel == 2 &&
    secc.titulo &&
    secc.titulo =~ /^\s*((enlace|liga|v[iíI]nculo)s?\s+extern[ao]s?|links)\s*:?\s*$/i
end

VTS =   [ 'v[eéÉ]ase\s+tambi[eéÉ]n',
          'referencias',
          'm[aáÁ]s\s+informaci[oóÓ]n',
          'notas',
          'bibliograf[íÍi]a'
        ].join("|")

def seccion_extraible secc
    seccion_ee(secc) ||
    secc.nivel == 2 &&
    secc.titulo &&
    secc.titulo =~ /^\s*(#{VTS})\s*$/i
end

class Object
def prt
    p self
    self
end
end

def redundante titulo, enlace, tipo
    if tipo == "wikt"
        titulo.downcase_first == enlace
    else
        titulo == enlace
    end
end

def params_ipr_y_etiqueta titulo, nombre, params
    nombre.tr!('_', ' ')
    return nil unless PLANTILLAS_IP[nombre]
    return [ PLANTILLAS_IP[nombre], nil ]  if params.empty? # caso fácil
    #p nombre, params
    i=1
    params = Hash[*params.map {|p|
                        param = p.split('=', 2)
                        if param.length == 1
                            param.unshift(i.to_s)
                            i += 1
                        end
                        param
                    }.flatten
                 ].prt

    if nombre == "Commons" && params["1"]
        params["1"] = params["1"].gsub(/:?category:/i) { |c|
                                                nombre = "Commonscat"
                                                ""
                                            }
    end
    iprdata = PLANTILLAS_IP[nombre].dup
    inicial = iprdata[0]
    idioma = params["idioma"]
    iprdata << "#{inicial}_idioma=#{idioma}"  if idioma
    enlace = params["1"]   || nombre == "Wikisource autor" && params["autor"]
    etiqueta = params["2"] || nombre == "Wikisource autor" && params["autor"] ||
                              nombre == WDH && enlace
    iprdata[0] = iprdata[0] + "=#{enlace}"    if enlace &&
                                                !redundante(titulo, enlace, inicial)
    iprdata[1, 0] = "#{inicial}_etiqueta=#{etiqueta}"  if etiqueta &&
                                                !redundante(titulo, etiqueta, inicial)
    
    [ iprdata, etiqueta ]
end

def saca_acentos s
    s = s.tr "ẃéŕýúíóṕáǽśǵḱĺźćńḿŵêûîôâŝĝĥĵẑĉẅëẗÿüïöäḧẍẽỹũĩõãṽñẁèỳùìòàǹȩŗţşḑģḩķļçņ",
             "weryuiopaasgklzcnmweuioasghjzcwetyuioahxeyuioavnweyuioanertsdghklcn"
    s.tr! "ẉẹṛṭỵụịọạṣḍḥḳḷẓṿḅṇṃűőěřťǐǒǎšďǧȟǰǩľžčňẘẙůåēȳūīoāḡĕŭĭŏăğęųįǫąłøþæßðđŋħĸ",
          "wertyuioasdhklzvbnmuoertioasdghjklzcnwyuaeyuioageuioageuioalodasddnhk"
    s
end

def sineses s
    s.gsub(/e?s\b/, '').strip
end

def sinarticulos s
    s.gsub(/\s*\b(el|la|los|las)\b/, "").gsub(/\bdel\b/, "de").gsub(/\bal\b/, "a").strip
end

def nombres_parecidos? uno, otro
    uno, otro = [uno, otro].map {|s| saca_acentos(s.downcase).
                                     tr("^ a-z", "").
                                     gsub(/\s+/, ' ')
                                }
    p "#{uno} == #{otro} || #{sinarticulos(uno)} == #{sinarticulos(otro)} ||
    #{sineses(sinarticulos(uno))} == #{sineses(sinarticulos(otro))}"
    res = uno == otro || sinarticulos(uno) == sinarticulos(otro) ||
    sineses(sinarticulos(uno)) == sineses(sinarticulos(otro))
    p res
    res
end

def hace_ipr data
    res = "{{ipr|" + data.map{|d| d.join("|")}.join("\n     |") + "}}"
    p res
    res
end

NO_FINALES = ["Ref-libro", "Cita libro", "Botánico"]

# a lo bruto!
def extrae_ultimas_plantillas secc
    res = ""
    sigue_sacando = true
    while sigue_sacando
        encontro = secc.texto.sub!(/\s*\{\{[^{}]+\}\}\s*\z/) { |subst|
                        nombre = subst[/\{\{[^|}]+/][2..-1].strip.upcase_first
                        p nombre
                        if NO_FINALES.include? nombre
                            sigue_sacando = false
                            next subst
                        end
                        res = subst + res
                        ""
                    }
        sigue_sacando &&= encontro
    end
    p res
    res
end

t_antes = 0
    
porhacer.each do |titulo|
    puts "** #{titulo}..."
    edicion = pr.edit_page titulo
    seccs = ArticuloSeccionado.new pr, edicion.texto
    
    ipr = []
    saltea = ledamos = false
    seccs.each_with_index do |secc, i|
        iprsecc = []
        antes = secc.texto.dup
        secc.texto.gsub!(/\{\{(.*?)\}\}\s*/) { |plant|
            p plant
            next plant if $1.count("{[]}").nonzero?
            nombre_pl, *params_pl = $1.split("|").map{|s| s.strip }
            nombre_pl.upcase_first!
            iprdata, etiqueta = params_ipr_y_etiqueta titulo, nombre_pl, params_pl
            #p iprdata, etiqueta
            next plant unless iprdata
            # ya tenemos la ipr... ahora a ver si tenemos huevos.
            # si está en la primera sección,
            # o en una extraíble,
            # o no tiene etiqueta, sacamos sin miedo :)
            if i == 0 || !etiqueta || seccion_extraible(secc)
                ipr << iprdata
                next ""
            end
            # si la etiqueta coincide con la sección,
            # es un caso de ipr en sección (o un gran error. 50% y 50% ;)
            if nombres_parecidos?(secc.titulo, etiqueta)
                iprsecc << iprdata
                next ""
            end
            # si no, debería coincidir con el artículo, ¿no?
            if nombres_parecidos?(titulo, etiqueta)
                ipr << iprdata
                next ""
            end
            # llegados acá, mejor no tocamos nada
            # ya arreglará otro ese artículo
            saltea = true
            break
        }
        break if saltea
        next unless secc.texto != antes
        # ajustemos...
        secc.texto.strip!
        secc.texto << "\n\n#{hace_ipr(iprsecc)}"   if iprsecc.length > 0
        # si quedó vacía, la anulamos
        if secc.texto.empty? && !secc.tiene_subseccion?
            secc.titulo = nil
        else
            secc.texto << "\n"
        end
        ledamos = true
    end
    if saltea || !ledamos
        puts " - salteando #{titulo} (" + if saltea
                                            "no me animo"
                                       else
                                            "nada que hacer"
                                       end + ")"
        hecha titulo
        next
    end
    
    if !ipr.empty?
        # buscamos una sección ee
        ee = seccs.reverse.find {|s| seccion_ee s }
        unless ee
            plantillas = extrae_ultimas_plantillas(seccs[-1])
            ee = Seccion.new("== ee ==\n\n")
            ee.texto << plantillas
            seccs << ee
        end
        ee.titulo = "Enlaces externos"
        ee.texto = hace_ipr(ipr) + "\n" + ee.texto
    end

    # a grabar!
    edicion.texto = seccs.texto
    edicion.menor = true
    edicion.resumen = 'ipr'
    
    #puts edicion.texto
    pr.post edicion
    hecha titulo
    puts " * #{titulo}"
    t_ahora = Time.now.to_i
    if t_ahora - t_antes < 30
    	sleep(30 - (t_ahora - t_antes))
    	t_ahora = Time.now.to_i
    end
    t_antes = t_ahora
end