User:Sambot/Code/Templates.php

From Wikipedia, the free encyclopedia

Config file[edit]

sourcetype=categorymembers
sourcename=Category:Films that need a synopsis
templatename=FilmsWikiProject:WikiProject Films,WikiProject Film:WikiProject Films,WPFILM:WikiProject Films,WP Film:WikiProject Films,FILM:WikiProject Films,WikiProject Films:WikiProject Films,Film:Film
fieldsremove=importance,attention,auto,nested,portal1-name,portal21-name,portal3-name,portal4-name,portal5-name
fieldsmigrate=needs-synopsis:needs-plot
onlyif=fieldsmigrate
editsummary=[[WP:Bots/Requests for approval/Sambot 3|BOT]]: Cleanup of {{[[Template:Film|Film]]}}

Code[edit]

<?php

define ('PILLAR','PILLAR');

require('class.pillar.php');

$pillar = Pillar::ini_launch('pillar.ini');

checkshutdown();

$settings = parse_ini_file('templates.ini');

if (!$settings['templatename'] || !$settings['sourcetype'] || !$settings['sourcename']) {
    print "templatename, sourcetype and sourcename must all be present in templates.ini\nShutting down\n";
}

if ($settings['templatename']) {
    if (false === strpos ($settings['templatename'],',')) {
        print "Migrating fields in {{{$settings['templatename']}}}\n";
    } else {
        $namesmigrate = explode(',',$settings['templatename']);
        foreach ($namesmigrate as $nm) {
            list ($namesmigratefrom[],$namesmigrateto[]) = explode(':',$nm);
        }
        print "Migrating the following template names:\n";
        for ($i = 0 ; $i < count($namesmigrate) ; $i++) {
            print " - {{" . $namesmigratefrom[$i] . "}} to {{" . $namesmigrateto[$i] . "}}\n";
        }
    }
    print "\n";
}

if ($settings['fieldsremove']) {
    $fieldsremove = explode(',',$settings['fieldsremove']);
    print "Removing the following fields: " . implode(', ',$fieldsremove) . "\n\n";
}

if ($settings['fieldsmigrate']) {
    $fieldsmigrate = explode(',',$settings['fieldsmigrate']);
    foreach ($fieldsmigrate as $fm) {
        list ($fieldsmigratefrom[],$fieldsmigrateto[]) = explode(':',$fm);
    }
    print "Migrating the following fields:\n";
    for ($i = 0 ; $i < count($fieldsmigrate) ; $i++) {
        print " - " . $fieldsmigratefrom[$i] . " to " . $fieldsmigrateto[$i] . "\n\n";
    }
}

do {
    unset ($e);
    $i = 0;
    do {
        try {
            switch ($settings['sourcetype']) {
                case 'embeddedin':
                    $pages = $pillar->cursite->get_embeddedin('Template:' . $settings['sourcename'],100,$continue);
                    break;
                case 'categorymembers':
                    $pages = $pillar->cursite->get_categorymembers($settings['sourcename'],100,$continue);
                    break;
                case 'imageuse':
                    $pages = $pillar->cursite->get_imageuse($settings['sourcename'],100,$continue);
            }
        } catch (PillarException $e) {
            print $e->getMessage() . "\n";
            if ($i++ == 5) {
                print "5 consecutive failures to retrieve list of pages.  Shutting down.\n";
                die();
            }
        }
    } while ($e);
    
    foreach ($pages as $title) {
        if ($settings['sourcetype'] == 'categorymembers') {
            $title = $title['title'];
        }
        
        print "\nEditing $title... ";
        
        unset ($e);
        $i = 0;
        do {
            try {
                $page = new Page($pillar->cursite,$title);
            } catch (PillarException $e) {
                print $e->getMessage() . "\n";
                if ($i++ == 5) {
                    print "5 consecutive failures to retrieve page $title.  Shutting down.\n";
                    die();
                }
            }
        } while ($e);
        
        $text = $page->get_text();
        
        foreach ($namesmigratefrom as $nmf) {
            $name = "(" . strtoupper(substr($nmf,0,1)) . "|" . strtolower(substr($nmf,0,1)) . ")" . substr($nmf,1);
            if (preg_match("/\{\{$name\s*((\|.*)|\})/s",$text,$match)) {
                $list = separatetemplate($text,$nmf);
                break;
            }
        }
        
        $template = $list['template'];
        
        $splittemplate = templatesplit($template);
        
        if ($settings['onlyif'] == 'namesmigrate') {
            $check = $template;
        }
        
        $found = false;
        
        if ($namesmigrate) {
            for ($i = 0 ; $i < count($namesmigratefrom) ; $i++) {
                $nameinsearch = "(" . strtoupper(substr($namesmigratefrom[$i],0,1)) . "|" . strtolower(substr($namesmigratefrom[$i],0,1)) . ")" . substr($namesmigratefrom[$i],1);
                if (preg_match("/^$nameinsearch(\s*)$/",$splittemplate['name'],$match)) {
                    $splittemplate['name'] = $namesmigrateto[$i] . $match[2];
                    $found = true;
                    break;
                }
            }
        }
        
        if (!$found) {
            $failures[] = $title;
            continue;
        }
        
        if ($settings['onlyif'] == 'namesmigrate') {
            if (templatebuild($splittemplate) == $check) {
                print "no change\n";
                continue;
            }
        } elseif ($settings['onlyif'] == 'fieldsmigrate') {
            $check = templatebuild($splittemplate);
        }
        
        if ($fieldsmigrate) {
            for ($i = 0 ; $i < count($fieldsmigratefrom) ; $i++) {
                for ($j = 0 ; $j < count($splittemplate['fields']) ; $j++) {
                    $splittemplate['fields'][$j] = preg_replace('/^(\s*)' . $fieldsmigratefrom[$i] . '(\s*=)/is',"$1" . $fieldsmigrateto[$i] . "$2",$splittemplate['fields'][$j]);
                }
            }
        }
        
        if ($settings['onlyif'] == 'fieldsmigrate') {
            if (templatebuild($splittemplate) == $check) {
                print "no change\n";
                continue;
            }
        } elseif ($settings['onlyif'] == 'fieldsremove') {
            $check = templatebuild($splittemplate);
        }
        
        if ($fieldsremove) {
            $keystoremove = array();
            for ($i = 0 ; $i < count($fieldsremove) ; $i++) {
                for ($j = 0 ; $j < count($splittemplate['fields']) ; $j++) {
                    if (preg_match('/^\s*' . $fieldsremove[$i] . '\s*=/is',$splittemplate['fields'][$j])) {
                        $keystoremove[] = $j;
                    }
                }
            }
            if ($keystoremove) {
                foreach ($keystoremove as $key) {
                    unset($splittemplate['fields'][$key]);
                }
            }
        }
        
        if ($settings['onlyif'] == 'fieldsremove') {
            if (templatebuild($splittemplate) == $check) {
                print "no change\n";
                continue;
            }
        }
        
        $text = $list['start'] . templatebuild($splittemplate) . $list['end'];
        
        checkshutdown();
        
        try {
            $page->put($text,$settings['editsummary'],0);
            print "success\n";
        } catch (PillarException $e) {
            print $e->getMessage() . "\n";
            $failures[] = $title;
        }
    }
} while ($continue != null);

if ($failures) {
    print "Edit-failures:\n";
    foreach ($failures as $f) {
        print "* [[$f]]";
    }
}

function checkshutdown() {
    global $pillar;
    $page = new Page($pillar->cursite,'User:Sambot/shutdown');
    if ($page->get_text() != '') {
        print "\nOn-wiki shutdown\n";
        die();
    }
    unset($page);
}

function separatetemplate($text,$template) {
    $from = (int) stripos($text,'{{' . $template);
    
    $name = "(" . strtoupper(substr($template,0,1)) . "|" . strtolower(substr($template,0,1)) . ")" . substr($template,1);
    preg_match("/\{\{" . $name . "\s*((\|.*)|(\}.*))/s",$text,$match);
    
    $from = (int) stripos($text,$match[0]);
    
    $i = 2;
    $counter = 2;
    
    while (strlen($match[0]) > $i) {
        if ($match[0][$i] == '{') {
            $counter++;
        }
        elseif ($match[0][$i] == '}') {
            $counter--;
        }
        
        if ($counter == 1) {
            $end = $i + 2;
            
            $return = array ('start'=>substr($text,0,$from),'template'=>substr($text,$from,$end),'end'=>substr($match[0],$end));
            return $return;
        }
        
        $i++;
    }
}

function templatesplit ($template) {
    preg_match('/(\{\{\s*)([^|}]*)(.*)/s',$template,$match);
    
    $return['open'] = $match[1];
    $return['name'] = $match[2];
    
    if (false === strpos($template,'|')) {
        $return['fields'] = array();
        $return['end'] = '}}';
    }
    
    $subtemplate = 0;
    $current = '';
    
    for ($i = 0 ; $i < strlen($match[3]) ; $i++) {
        if ($current && !$subtemplate && (($match[3][$i] == '|') || ($match[3][$i] == '}'))) {
            $fields[] = $current;
            $current = '';
            $lastletter = $match[3][$i];
            continue;
        }
        
        if (!$current && !$subtemplate && ($lastletter == '}') && ($match[3][$i] == '}')) {
            break;
        }
        
        if (($lastletter == '{') && ($match[3][$i] == '{')) {
            $subtemplate++;
        }
        
        if (($lastletter == '}') && ($match[3][$i] == '}')) {
            $subtemplate--;
        }
        
        if (!$subtemplate && !$current && ($match[3][$i] == '|') && ($lastletter == '|')) {
            $fields[] = '';
        }
        
        if ((!$subtemplate && ($match[3][$i] != '|')) || $subtemplate) {
            $current .= $match[3][$i];
        }
        
        $lastletter = $match[3][$i];
    }
    
    $last = (count($fields)) - 1;
    if ($fields[$last] == '}') { //this is actually impossible to set, so it will always indicate an empty field
        $fields[$last] = '';
    }
    
    $return['fields'] = $fields;
    
    $return['end'] = '}}';
    
    return $return;
}

function templatebuild($splittemplate) {
    $return = $splittemplate['open'];
    $return .= $splittemplate['name'];
    foreach ($splittemplate['fields'] as $field) {
        $return .= "|$field";
    }
    $return .= $splittemplate['end'];
    return $return;
}