<?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);
 
?>