<?php
/** goodarticles.php -- Maintains WP:GAN
* STABLE Version 4.0
*
* (c) 2010 James Hare - http://en.wikipedia.org/wiki/User:Harej
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Developers (add your self here if you worked on the code):
* James Hare - [[User:Harej]] - Wrote everything
**/
set_time_limit(600);
ini_set("display_errors", 1);
error_reporting(E_ALL ^ E_NOTICE);
include("./public_html/botclasses.php"); // Botclasses.php was written by User:Chris_G and is available under the GNU General Public License
include("logininfo.php");
include("Twitter.class.php");
include("bitly.class.php");
function cmp($a, $b) {
if ($a == $b) {
return 0;
}
return ($a > $b) ? -1 : 1;
}
function templateprocess($processed) {
// Normalizes the GA nominee templates into a consistent format
$processed = preg_replace("/\s?\|\s?/", "|", $processed);
$processed = preg_replace("/\{{2}GA\s?nominee\s?/", "GA nominee", $processed);
$processed = preg_replace("/\s?=\s?/", "=", $processed);
$processed = preg_replace("/\|(?=([0-2]\d))/", "|1=", $processed);
$processed = substr($processed, 0, -2);
return $processed;
}
echo "Logging in...";
$objwiki = new wikipedia();
$objwiki->login($gauser, $gapass);
echo " done.\n";
/* Connect to the database */
echo "Retrieving database login credentials...";
$toolserver_mycnf = parse_ini_file("/home/messedrocker/.my.cnf");
$toolserver_username = $toolserver_mycnf['user'];
$toolserver_password = $toolserver_mycnf['password'];
unset($toolserver_mycnf);
echo " done.\n";
echo "Logging into database...";
mysql_connect("sql",$toolserver_username,$toolserver_password);
@mysql_select_db('u_messedrocker_reqs') or die(mysql_error());
echo " done.\n";
// This looks for transclusions of the GA nominee template, with some filtering done to restrict the list to the talk namespace.
echo "Checking for transclusions...";
do {
$transcludes = $objwiki->getTransclusions("Template:GA nominee");
} while (count($transcludes) == 0);
echo " done.\n";
$counter = 0;
for ($i = 0; $i < count($transcludes); $i++) {
if (preg_match("/^Talk:/", $transcludes[$i])) {
$articles[$counter] = $transcludes[$i];
$counter++;
}
}
unset($transcludes);
// Each GA nominee tag will now be standardized and stripped apart, with each detail found in each tag sorted into the right array
for ($i = 0; $i < count($articles); $i++) {
$title = str_replace("Talk:", "", $articles[$i]);
do {
$contents = $objwiki->getpage($articles[$i]);
} while ($contents == "");
preg_match("/\{{2}\s?GA\s?nominee.*\}{2}/i", $contents, $m);
$tagmeta = templateprocess($m[0]);
unset($m);
preg_match("/1=[^|]*/", $tagmeta, $date);
$date = str_replace("1=", "", $date[0]);
$unixtime[$title] = strtotime($date);
preg_match("/page=[^|]*/", $tagmeta, $reviewpage);
$reviewpage2 = "GA" . str_replace("page=", "", $reviewpage[0]);
$reviewpage = $articles[$i] . "/GA" . str_replace("page=", "", $reviewpage[0]);
$reviewpage = str_replace(" ", "_", $reviewpage);
preg_match("/subtopic=[^|]*/", $tagmeta, $subtopicraw);
$subtopic[$title] = str_replace("subtopic=", "", $subtopicraw[0]);
preg_match("/status=[^|]*/", $tagmeta, $status);
$status = str_replace("status=", "", $status[0]);
preg_match("/nominator=.*/", $tagmeta, $nominator);
$nominator = str_replace("nominator=", "", $nominator[0]);
$nominator = preg_replace("/\|(page|subtopic|status|nominator|note)=.*/", "", $nominator);
preg_match("/note=.*$/", $tagmeta, $note);
$note = str_replace("note=", "", $note[0]);
$lookup = mysql_query("select * from `gan` where `page`=\"" . mysql_real_escape_string($title) . "\"");
$row = mysql_fetch_assoc($lookup);
if ($row['page'] == $title && $row['reviewer'] != "") {
$reviewer = $row['reviewer'];
$reviewer_plain[$title] = $row['reviewerplain'];
$subtopic[$title] = $row['subtopic'];
}
else {
$reviewpageregex = str_replace("/", "\/", $reviewpage);
$reviewpageregex = str_replace("(", "\(", $reviewpageregex);
$reviewpageregex = str_replace(")", "\)", $reviewpageregex);
$reviewpageregex = str_replace(".", "\.", $reviewpageregex);
$reviewpageregex = str_replace("_", "( |_)", $reviewpageregex);
$reviewpageregex = str_replace("?", "\?", $reviewpageregex);
$reviewpageregex = str_replace("*", "\*", $reviewpageregex);
$reviewpageregex = "/\{{2}\s?" . $reviewpageregex . "\s?\}{2}/i";
$createdcheck = $objwiki->getpage($reviewpage);
if (preg_match("/'''Reviewer:''' .*\n/", $createdcheck, $reviewer)) {
$reviewer = str_replace("'''Reviewer:''' ", "", $reviewer[0]);
$reviewer = preg_replace("/\n/", "", $reviewer);
preg_match("/\[{2}User([_ ]talk)?:[^|]*\|/i", $reviewer, $rp);
$rp[0] = preg_replace("/\[{2}User([_ ]talk)?:/i", "", $rp[0]);
$rp[0] = str_replace("|", "", $rp[0]);
$reviewer_plain[$title] = $rp[0];
unset($rp);
$contents_preserved = $contents;
$contents = str_replace("status=|", "status=onreview|", $contents);
if ($contents != $contents_preserved) {
$status = "onreview";
}
if (!preg_match($reviewpageregex, $contents) && !preg_match("/\{\{.*\/" . $reviewpage2 . "\s?\}{2}/i", $contents)) {
$contents .= "\n\n{{" . $articles[$i] . "/" . $reviewpage2 . "}}";
}
if ($contents != $contents_preserved && $objwiki->nobots($articles[$i],$gauser,$contents) == true) {
$objwiki->edit($articles[$i],$contents,"Transcluding GA review",true,true);
}
unset($contents_preserved);
mysql_query("delete from `gan` where `page` = \"" . mysql_real_escape_string($title) . "\""); // in case it is already defined in the db
mysql_query("insert into `gan` (`page`, `reviewerplain`, `reviewer`, `subtopic`) values (\"" . mysql_real_escape_string($title) . "\", \"" . mysql_real_escape_string($reviewer_plain[$title]) . "\", \"" . mysql_real_escape_string($reviewer) . "\", \"" . mysql_real_escape_string($subtopic[$title]) . "\")");
#preg_match_all("/([0-2]\d):([0-5]\d),\s(\d{1,2})\s(\w*)\s(\d{4})\s\(UTC\).*/", $createdcheck, $rptime);
#for ($x = 0; $x < count($rptime[0]); $x++) {
# $rptime[0][$x] = strtotime($rptime[0][$x]);
#}
#usort($rptime[0], "cmp");
#$rptime = time() - $rptime[0][0];
#if ($rptime > 1209600) {
# $overtwoweeks = true;
#}
#unset($rpdate);
}
else {
$reviewer = "";
}
}
if ($subtopic[$title] == " " || $subtopic[$title] == "") {
$subtopic[$title] = "Miscellaneous";
}
// With all the details known, each GA nominee's entry on the GAN list is now generated.
$sector[$title] = "# {{GANentry|1=" . $title . "|2=" . str_replace("GA", "", $reviewpage2) . "}} " . $nominator . " " . $date . "\n";
if ($status == "on hold" || $status == "onhold" || $status == "hold") {
$sector[$title] .= "#:{{GAReview|status=on hold}} " . $reviewer . "\n";
}
elseif ($status == "2nd opinion" || $status == "2ndopinion" || $status == "second opinion" || $status== "2nd op" || $status == "2ndop" || $status == "opinion") {
$sector[$title] .= "#: {{GAReview|status=2nd opinion}} " . $reviewer . "\n";
}
elseif ($status == "review" || $status == "on review" || $status == "onreview") {
$sector[$title] .= "#:{{GAReview}} " . $reviewer . "\n";
}
if ($overtwoweeks == true) {
$sector[$title] .= "#:{{Stale GAN}}\n";
}
if ($note != "") {
$sector[$title] .= "#: [[File:Ambox_notice.png|15px]] '''Note:''' " . $note . "\n";
}
unset($title);
unset($tagmeta);
unset($date);
unset($reviewpage);
unset($reviewpage2);
unset($status);
unset($nominator);
unset($reviewer);
unset($subtopicraw);
unset($reviewpageregex);
unset($createdcheck);
unset($note);
unset($overtwoweeks);
}
// Now sorting the entries from oldest to youngest, and putting together the GAN list.
// cheers to caffinated on irc.freenode.net ##php for this sorting jazz.
$keys = array_keys($unixtime);
$values = array_values($unixtime);
array_multisort($values, $keys);
$unixtime = array_combine($keys, $values);
do {
$wpgan = $objwiki->getpage("Wikipedia:Good article nominations");
} while ($wpgan == "");
$regex1 = "/<!-- EVERYTHING BELOW THIS COMMENT IS UPDATED AUTOMATICALLY BY A BOT -->";
$regex2 = "<!-- EVERYTHING ABOVE THIS COMMENT IS UPDATED AUTOMATICALLY BY A BOT -->/";
do {
$regex1 .= "\n*.*";
preg_match($regex1 . $regex2, $wpgan, $m);
} while ($m[0] == "");
$currentcontent = $m[0];
unset($m);
// The variable assignment immediately beneath this comment defines the variable containing the submission, which is based on the already-existing list but stripped of all its entries.
// This is the base from which the sections are defined and the list is defined.
$submission = preg_replace("/\n#.*/", "", $wpgan);
preg_match_all("/={2,3}\s?[^=]*={2,3}/", $submission, $secs);
for ($i = 0; $i < count($secs[0]); $i++) {
$head = preg_replace("/\s?={2,3}\s?/", "", $secs[0][$i]);
$regex1 = "/" . $secs[0][$i];
$regex2 = "(={2,3}|<!-- EVERYTHING)/";
do {
$regex1 .= "\n*.*";
preg_match($regex1 . $regex2, $submission, $m);
} while ($m[0] == "");
$listing[$head] = preg_replace("/(={2,3}|<!-- EVERYTHING).*$/", "", $m[0]);
}
// Now $submission is being cleared out so that it can be written over. First, each entry is added to a section, and then the sections are added to the whole page.
$submission = "";
foreach ($unixtime as $name => $timestamp) {
$listing[$subtopic[$name]] .= $sector[$name];
}
foreach ($listing as $topic => $stuff) {
$submission .= $stuff;
}
$submission = "<!-- EVERYTHING BELOW THIS COMMENT IS UPDATED AUTOMATICALLY BY A BOT -->\n" . $submission . "<!-- EVERYTHING ABOVE THIS COMMENT IS UPDATED AUTOMATICALLY BY A BOT -->";
// Now begins the creation of edit summaries.
// First, the second-level topics ("broad topics") are defined.
preg_match_all("/={2}\s?[^=]*\s?={2}\n/", $submission, $lvl2secs);
for ($i = 0; $i < count($lvl2secs[0]); $i++) {
$lvl2secs[0][$i] = preg_replace("/\n/", "", $lvl2secs[0][$i]);
$regex1 = "/" . $lvl2secs[0][$i];
$regex2 = "\n(==\s?[^=]+\s?==|<!-- EVERYTHING)/";
do {
preg_match($regex1 . $regex2, $submission, $m);
$regex1 .= "\n*.*";
} while ($m[0] == "");
$m[0] = preg_replace("/(={2}\s?[^=]+\s?={2}|<!-- EVERYTHING)$/", "", $m[0]);
$m[0] = str_replace($lvl2secs[0][$i] . "\n", "", $m[0]);
$lvl2secs[0][$i] = str_replace("=", "", $lvl2secs[0][$i]);
$lvl2secs[0][$i] = preg_replace("/^\s*/", "", $lvl2secs[0][$i]);
$lvl2secs[0][$i] = preg_replace("/\s*$/", "", $lvl2secs[0][$i]);
preg_match_all("/={3}\s?[^=]*\s?={3}\n/", $m[0], $lvl3secs);
for ($j = 0; $j < count($lvl3secs[0]); $j++) {
$lvl3secs[0][$j] = str_replace("=", "", $lvl3secs[0][$j]);
$lvl3secs[0][$j] = preg_replace("/^\s*/", "", $lvl3secs[0][$j]);
$lvl3secs[0][$j] = preg_replace("/\s*$/", "", $lvl3secs[0][$j]);
$broadcat[$lvl3secs[0][$j]] = $lvl2secs[0][$i];
}
$broadcat[$lvl2secs[0][$i]] = $lvl2secs[0][$i];
$subpage[$lvl2secs[0][$i]] = "{{Wikipedia:Good article nominations/Topic lists}}\n" . $m[0];
$topicsummary[$lvl2secs[0][$i]] = "";
$topicsummarypart[$lvl2secs[0][$i]]["New"] = "";
$topicsummarypart[$lvl2secs[0][$i]]["Passed"] = "";
$topicsummarypart[$lvl2secs[0][$i]]["Failed"] = "";
$topicsummarypart[$lvl2secs[0][$i]]["On review"] = "";
$topicsummarypart[$lvl2secs[0][$i]]["On hold"] = "";
$topicsummarypart[$lvl2secs[0][$i]]["2nd opinion"] = "";
unset($m);
unset($regex1);
unset($regex2);
}
unset($lvl2secs);
unset($lvl3secs);
// Compiling the edit summary parts
$editsummarypart["New"] = "";
$editsummarypart["Passed"] = "";
$editsummarypart["Failed"] = "";
$editsummarypart["On review"] = "";
$editsummarypart["On hold"] = "";
$editsummarypart["2nd opinion"] = "";
preg_match_all("/\{{2}GANentry\|1=[^|]*/", $currentcontent, $entries);
for ($i = 0; $i < count($entries[0]); $i++) {
$entries[0][$i] = str_replace("{{GANentry|1=", "", $entries[0][$i]);
}
for ($i = 0; $i < count($articles); $i++) {
$articles[$i] = str_replace("Talk:", "", $articles[$i]);
if (!in_array($articles[$i], $entries[0])) {
$editsummarypart["New"] .= "[[" . $articles[$i] . "]] (" . $subtopic[$articles[$i]] . "), ";
$topicsummarypart[$broadcat[$subtopic[$articles[$i]]]]["New"] .= "[[" . $articles[$i] . "]] (" . $subtopic[$articles[$i]] . "), ";
}
}
for ($i = 0; $i < count($entries[0]); $i++) {
if (!in_array($entries[0][$i], $articles)) { // Those that have been removed
$lookup = mysql_query("select `subtopic` from `gan` where `page` = \"" . mysql_real_escape_string($entries[0][$i]) . "\"") or die(mysql_error());
$row2 = mysql_fetch_assoc($lookup);
$thesubtopic = $row2['subtopic'];
$contents = $objwiki->getpage("Talk:" . $entries[0][$i]);
if ((preg_match("/\|\s?currentstatus\s?=\s?GA/i", $contents) || preg_match("/\{{2}\s?GA/", $contents)) && !preg_match("/\{{2}\s?FailedGA/i", $contents)) {
$editsummarypart["Passed"] .= "[[" . $entries[0][$i] . "]], ";
$topicsummarypart[$broadcat[$thesubtopic]]["Passed"] .= "[[" . $entries[0][$i] . "]], ";
mysql_query("delete from `gan` where `page` = \"" . mysql_real_escape_string($entries[0][$i]) . "\"");
// Update Twitter
#$bitly = new Bitly($bitlyuser, $bitlykey);
#$shortlink = $bitly->shortenSingle("http://en.wikipedia.org/wiki/" . urlencode(str_replace(" ", "_", $entries[0][$i])));
#$tweet = "Newly promoted good article: " . $entries[0][$i] . " " . $shortlink;
#if (strlen($tweet) > 140) {
# $tweet = str_replace("Newly promoted good article: ", "", $tweet);
#}
#$twitter = new Twitter($twitteruser, $twitterpass);
#$update = $twitter->update($tweet);
}
else {
$editsummarypart["Failed"] .= "[[" . $entries[0][$i] . "]], ";
$topicsummarypart[$broadcat[$thesubtopic]]["Failed"] .= "[[" . $entries[0][$i] . "]], ";
mysql_query("delete from `gan` where `page` = \"" . mysql_real_escape_string($entries[0][$i]) . "\"");
}
}
if (in_array($entries[0][$i], $articles)) { // For those that are in both
$articlesiregexed = str_replace("/", "\/", $articles[$i]);
$articlesiregexed = str_replace("(", "\(", $articlesiregexed);
$articlesiregexed = str_replace(")", "\)", $articlesiregexed);
$articlesiregexed = str_replace(".", "\.", $articlesiregexed);
$articlesiregexed = str_replace("_", "( |_)", $articlesiregexed);
$articlesiregexed = str_replace("?", "\?", $articlesiregexed);
$articlesiregexed = str_replace("*", "\*", $articlesiregexed);
preg_match("/\{{2}GANentry\|1=" . $articlesiregexed . ".*\n.*/", $currentcontent, $then);
preg_match("/\{{2}GANentry\|1=" . $articlesiregexed . ".*\n.*/", $submission, $now); // Then and Now, an album by The Who
if ($then[0] != $now[0]) {
if (strpos($now[0], "{{GAReview}}") !== false) {
$editsummarypart["On review"] .= "[[" . $articles[$i] . "]] by [[User:" . $reviewer_plain[$articles[$i]] . "|" . $reviewer_plain[$articles[$i]] . "]], ";
$topicsummarypart[$broadcat[$subtopic[$articles[$i]]]]["On review"] .= "[[" . $articles[$i] . "]] by [[User:" . $reviewer_plain[$articles[$i]] . "|" . $reviewer_plain[$articles[$i]] . "]], ";
}
elseif (strpos($now[0], "{{GAReview|status=on hold}}") !== false) {
$editsummarypart["On hold"] .= "[[" . $articles[$i] . "]] by [[User:" . $reviewer_plain[$articles[$i]] . "|" . $reviewer_plain[$articles[$i]] . "]], ";
$topicsummarypart[$broadcat[$subtopic[$articles[$i]]]]["On hold"] .= "[[" . $articles[$i] . "]] by [[User:" . $reviewer_plain[$articles[$i]] . "|" . $reviewer_plain[$articles[$i]] . "]], ";
}
elseif (strpos($now[0], "{{GAReview|status=2nd opinion}}") !== false) {
$editsummarypart["2nd opinion"] .= "[[" . $articles[$i] . "]] by [[User:" . $reviewer_plain[$articles[$i]] . "|" . $reviewer_plain[$articles[$i]] . "]], ";
$topicsummarypart[$broadcat[$subtopic[$articles[$i]]]]["2nd opinion"] .= "[[" . $articles[$i] . "]] by [[User:" . $reviewer_plain[$articles[$i]] . "|" . $reviewer_plain[$articles[$i]] . "]], ";
}
unset($now);
unset($then);
unset($contents);
}
}
}
// Combining the edit summary parts into one edit summary per page
$editsummary = "";
foreach ($editsummarypart as $label => $part) {
if ($part != "") {
$editsummary .= $label . ": " . substr($part, 0, -2) . " ";
}
}
$editsummary = str_replace("[[User:|]]", "???", $editsummary);
$editsummary = substr($editsummary, 0, -1);
foreach ($topicsummarypart as $broadtopic => $statusarray) {
foreach ($statusarray as $label => $part) {
if ($part != "") {
$topicsummary[$broadtopic] .= $label . ": " . substr($part, 0, -2) . " ";
}
}
$topicsummary[$broadtopic] = str_replace("[[User:|]]", "???", $topicsummary[$broadtopic]);
$topicsummary[$boradtopic] = substr($topicsummary[$broadtopic], 0, -1);
if ($topicsummary[$broadtopic] == "") {
$topicsummary[$broadtopic] = "Maintenance";
}
}
if ($editsummary == "") {
$editsummary = "Maintenance";
}
// Submitting the changes to Wikipedia
foreach ($subpage as $broadtopic => $stuff) {
$objwiki->edit("Wikipedia:Good article nominations/Topic lists/" . $broadtopic,$stuff,$topicsummary[$broadtopic],false,true);
}
$submission = str_replace($currentcontent, $submission, $wpgan);
$submission = preg_replace("/\n{3,}/", "\n\n", $submission);
$objwiki->edit("Wikipedia:Good article nominations",$submission,$editsummary,false,true);
?>