r106211 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r106210‎ | r106211 | r106212 >
Date:17:17, 14 December 2011
Author:reedy
Status:deferred (Comments)
Tags:
Comment:
Modified paths:
  • /trunk/tools/rotatebot (added) (history)
  • /trunk/tools/rotatebot/login.php (added) (history)
  • /trunk/tools/rotatebot/rotbot.php (added) (history)
  • /trunk/tools/rotatebot/upload.php (added) (history)

Diff [purge]

Index: trunk/tools/rotatebot/rotbot.php
@@ -0,0 +1,1070 @@
 2+<?php
 3+/* Copyright © by Luxo & Saibo, 2011
 4+
 5+ This program is free software: you can redistribute it and/or modify
 6+ it under the terms of the GNU General Public License as published by
 7+ the Free Software Foundation, either version 3 of the License, or
 8+ (at your option) any later version.
 9+
 10+ This program is distributed in the hope that it will be useful,
 11+ but WITHOUT ANY WARRANTY; without even the implied warranty of
 12+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13+ GNU General Public License for more details.
 14+
 15+ You should have received a copy of the GNU General Public License
 16+ along with this program. If not, see <http://www.gnu.org/licenses/>.
 17+ */
 18+
 19+$homedir = "/home/luxo/rotbot/";
 20+$myLockfile = $homedir."rotatebotlock";
 21+
 22+ini_set('memory_limit', '100M'); //Speicher auf 100 MBytes hochsetzen
 23+ini_set('user_agent', ' User:Rotatebot by Luxo on the Toolserver / PHP');
 24+
 25+
 26+logfile("Starte Bot!");
 27+$config = botsetup();
 28+if($config['active'] == "false") {
 29+ die("Bot disabled.");
 30+} else if($config['active'] != "true") {
 31+ die("Bot error.");
 32+}
 33+
 34+// Killer bot
 35+if ($config['killAllRotatebots'] == "true") {
 36+ logfile("ATTENTION: Going to killAllRotatebots (also myself)!");
 37+ // "php rotbot/rotbot.php" needs to be the process name
 38+ logfile("signal 15");
 39+ system("pkill -15 -f 'php rotbot/rotbot.php'");
 40+ sleep(10);
 41+ logfile("signal 9");
 42+ system("pkill -9 -f 'php rotbot/rotbot.php'");
 43+ // we should be all dead now
 44+}
 45+
 46+$dontDieOnLockProblems = false;
 47+if ($config['dontDieOnLockProblems'] == "true") {
 48+ logfile("ATTENTION: dontDieOnLockProblems is true! Lockfile problems (like lockfile already present) will be ignored.");
 49+ $dontDieOnLockProblems = true;
 50+}
 51+getLockOrDie($dontDieOnLockProblems); //check for other concurrently running rotatebot instances. Exit if not alone on the world
 52+// continue ONLY if we are not dead ...
 53+// after this line only suicide() should be done instead of die()!
 54+
 55+
 56+logfile("Verbinde zur Datenbank!");
 57+include("/home/luxo/public_html/contributions/logindata.php");
 58+$myslink = mysql_connect($databanknames2, $userloginname, $databasepw) or suicide ("Can't connect to MySQL");
 59+$database = "commonswiki_p";
 60+mysql_select_db($database, $myslink)
 61+ or suicide ("Konnte $databas nicht öffnen: ".mysql_error());
 62+//Datenbank verbunden
 63+
 64+$wrongfiles = array();
 65+
 66+//Kategorie auf Bilder überprüfen
 67+$katname = "Images_requiring_rotation_by_bot";
 68+logfile("Prüfe 'Category:$katname' auf Bilder");
 69+
 70+$queryurl = "http://commons.wikimedia.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:".$katname."&format=php&cmprop=ids|title|sortkey|timestamp&cmnamespace=6&cmsort=timestamp&cmtype=file&cmlimit=".$config['limit'];
 71+$rawrequ = file_get_contents($queryurl) or suicide("Error api.php not accessible.");
 72+$contentarray = unserialize($rawrequ);
 73+
 74+if(!$contentarray['query']['categorymembers']['0'])
 75+{
 76+ suicide(logfile("Kategorie leer."));
 77+}
 78+
 79+//NS filter (was disabled on api 10.07.09)
 80+
 81+foreach($contentarray['query']['categorymembers'] as $temp_img)
 82+{
 83+ if($temp_img['ns'] == 6)
 84+ {
 85+ $contentarray['pages'][] = $temp_img;
 86+ }
 87+}
 88+
 89+
 90+/*
 91+[0] => Array
 92+ (
 93+ [pageid] => 3830049
 94+ [ns] => 6
 95+ [title] => Image:WTM wikiWhat 074.jpg
 96+ [sortkey] => 270
 97+ [timestamp] => 2008-04-06T00:03:01Z
 98+ )
 99+[1] => Array
 100+ (
 101+ ...
 102+*/
 103+
 104+//noch restliche daten nachladen von api.php
 105+
 106+foreach($contentarray['pages'] as $picture)
 107+{
 108+ $urlpageids .= "|".$picture['pageid'];
 109+}
 110+$urlpageids = substr($urlpageids,1); //vorderster | wieder wegnehmen (JA, unsauber ;-)
 111+
 112+$queryurl = "http://commons.wikimedia.org/w/api.php?action=query&pageids=".$urlpageids."&prop=revisions|imageinfo&format=php&iiprop=timestamp|user|url|size|metadata";
 113+$rawrequ = file_get_contents($queryurl) or suicide("Error api.php not accessible.");
 114+$contentarray2 = unserialize($rawrequ);
 115+
 116+$contentarray2['pages'] = $contentarray2['query']['pages'];
 117+//vorhandenes array einbinden
 118+
 119+foreach($contentarray['pages'] as $picture)
 120+{
 121+ $ctidd = $picture['pageid'];
 122+ foreach($picture as $contXB => $contXI)
 123+ {
 124+ $contentarray2['pages'][$ctidd][$contXB] = $contXI;
 125+ }
 126+}
 127+
 128+$contentarray = $contentarray2;
 129+
 130+
 131+
 132+$catcontent = array();
 133+$arraykey = 0;
 134+foreach($contentarray['pages'] as $picture)
 135+{
 136+logfile("-------------");
 137+logfile("check ".$picture['title']."...");
 138+
 139+//dateiendung bestimmen - gültiges Dateiformat?
 140+if(substr(strtolower($picture['title']),-4) == ".jpg" OR substr(strtolower($picture['title']),-5) == ".jpeg") { $catcontent[$arraykey]['filetype'] = "jpg"; }
 141+else if(substr(strtolower($picture['title']),-4) == ".png") { $catcontent[$arraykey]['filetype'] = "png"; }
 142+else if(substr(strtolower($picture['title']),-4) == ".gif") { $catcontent[$arraykey]['filetype'] = "gif"; }
 143+else { $wrongfile = true;
 144+ $wrongfiles[$picture["title"]] = "wrong filetype (".substr(strtolower($picture['title']),-3).")";
 145+ }
 146+//sortkey ab umbruchstelle beschneiden
 147+$picture["sortkey"] = trim(stristr(hexToStr($picture["sortkey"]), "\n", true));
 148+
 149+// Do not process big images ...
 150+logfile("Size of this picture: ".$picture['imageinfo']['0']["size"]." bytes. Limit set to ".$config['fileSizeLimit']." bytes");
 151+ if($picture['imageinfo']['0']["size"] > $config['fileSizeLimit']) {
 152+ logfile("File bigger (".$picture['imageinfo']['0']["size"]." B) than limit (".$config['fileSizeLimit']." B)");
 153+ $wrongfiles[$picture["title"]] = "File bigger (".$picture['imageinfo']['0']["size"]." B) than limit (".$config['fileSizeLimit']." B). Please wait until someone does a lossless(!) fix by hand.";
 154+ $wrongfile = true;
 155+ }
 156+
 157+
 158+ //Korrekte Grade/Aktion prüfen
 159+ if($picture["sortkey"] != 90 AND $picture["sortkey"] != 180 AND $picture["sortkey"] != 270) {
 160+ // exceptions for jpegs... last chance. ;-)
 161+ if(($catcontent[$arraykey]['filetype'] == "jpg" AND ($picture["sortkey"] == "RESETEXIF" OR $picture["sortkey"] == "0" OR $picture["sortkey"] == "00" OR $picture["sortkey"] == "000" ))) {
 162+ // okay, jpg AND (reset OR 0°) requested (cannot include in the in comparision since any string would match == 0) - EXIF based orientation should be applied apparently or be resetted
 163+ } else {
 164+ logfile("wrong degree-parameter (".$picture["sortkey"]."°)");
 165+ $wrongfiles[$picture["title"]] = "wrong degree-parameter (".$picture["sortkey"]."°)";
 166+ $wrongfile = true;
 167+ }
 168+ }
 169+
 170+
 171+//User, der das Template gesetzt hat, identifizieren
 172+
 173+$revitimestp = trim($picture["timestamp"]);
 174+
 175+foreach($picture['revisions'] as $key => $revisions)
 176+{
 177+ if(trim($revisions['timestamp']) == $revitimestp)
 178+ {
 179+ $catcontent[$arraykey]['tmplsetter'] = $picture['revisions'][$key]['user'];
 180+ logfile("Template by: ".$catcontent[$arraykey]['tmplsetter']);
 181+ }
 182+ else
 183+ {
 184+ logfile("set time($revitimestp) not identical with this rv, ".$revisions['timestamp'].".");
 185+ //Rev's nachladen
 186+ $ctxctx = file_get_contents("http://commons.wikimedia.org/w/api.php?action=query&prop=revisions&pageids=".$picture['pageid']."&rvlimit=20&rvprop=timestamp|user|comment&format=php") or suicide("api error");
 187+ $totrevs = unserialize($ctxctx);
 188+ logfile("ID: ".$picture['pageid']." ");
 189+
 190+ if(is_array($totrevs))
 191+ {
 192+ foreach($totrevs['query']['pages'] as $cxxx)
 193+ {
 194+ foreach($cxxx['revisions'] as $cxxxx)
 195+ {
 196+ if($cxxxx['timestamp'] == $revitimestp)
 197+ {
 198+ $catcontent[$arraykey]['tmplsetter'] = $cxxxx['user'];
 199+ logfile("Older rev, template by: ".$catcontent[$arraykey]['tmplsetter']);
 200+ }
 201+ }
 202+ }
 203+ }
 204+ else
 205+ {
 206+ logfile("API: Error: not a array!");
 207+ logfile($totrevs);
 208+ }
 209+ }
 210+}
 211+
 212+
 213+//Benutzer prüfen! #########################################
 214+if($catcontent[$arraykey]['tmplsetter']) //autoconfirmed
 215+{
 216+ $wgAuthor = $catcontent[$arraykey]['tmplsetter'];
 217+ logfile("check user ".$wgAuthor.".");
 218+
 219+ //Datenbank abfragen nach status
 220+ if(!$cachedbar["$wgAuthor"])
 221+ {
 222+ $mysresult = mysql_query( "SELECT * FROM user WHERE user_name='".mysql_real_escape_string($wgAuthor)."'") or suicide("MySQL error");
 223+ $a_row = mysql_fetch_row($mysresult);
 224+ $cachedbar[$wgAuthor] = $a_row;
 225+ }
 226+ else
 227+ {
 228+ $a_row = $cachedbar["$wgAuthor"];
 229+ }
 230+
 231+
 232+ $setuserid = $a_row[0];
 233+ $user_registration = $a_row[2];
 234+ $user_editcount = $a_row[3];
 235+ $chckx = $user_registration;//zum prüfen
 236+
 237+ if(!$setuserid){ $setuserid = "-"; }
 238+ if(!$user_editcount){ $user_editcount = 0; }
 239+ if(!$user_registration){ $user_registration = 20070101000000; $vcx = true; } //alte accounts haben diesen zeitstempel noch nicht
 240+
 241+ logfile("Edits: ".$user_editcount);
 242+ logfile("Registred at: ".$user_registration);
 243+ //Wikizeitstempel in unixzeit umrechnen
 244+
 245+ $regiUnix = TsToUnixTime($user_registration);
 246+
 247+ $actuUnix = time();
 248+ $registeredtime = $actuUnix - $regiUnix;
 249+ $registereddays = number_format($registeredtime / 86400,1,"."," ");//Stunden ausrechnen und runden/formatieren
 250+ if($registeredtime < 345600 OR !$chckx AND $setuserid == "-") //345600 sec = 4 Tage
 251+ {
 252+ logfile($wgAuthor." is not autoconfirmed!");
 253+ //Zu neu, nicht autoconfirmed
 254+ if($config['rotatepermission'] == "1")
 255+ {
 256+ $wrongfile = true;
 257+ $wrongfiles[$picture["title"]] = "The account of the user who set the template ([[User:".$catcontent[$arraykey]['tmplsetter']."|]]) is ''not autoconfirmed''.<br />'''Unlock:''' An autoconfirmed user should delete the parameters <code><nowiki>|</nowiki>nobot=true<nowiki>|</nowiki>reason=...</code> in this image. Thank you --~~~~";
 258+ }
 259+ $xx = "not ";
 260+ } else {
 261+ $xx = ""; //autoconfirmed
 262+ }
 263+
 264+ if($vcx == true)
 265+ {
 266+ $registereddays = "?";
 267+ }
 268+
 269+ $userforlog[$wgAuthor] = "***$wgAuthor, userid $setuserid, $user_editcount edits, registered since $registereddays days, is '''".$xx."autoconfirmed.'''";
 270+
 271+ if($config['mincontribs'] > 0 AND $user_editcount < $config['mincontribs']) //zu wenige edits
 272+ {
 273+ if($config['rotatepermission'] == "1")
 274+ {
 275+ logfile($catcontent[$arraykey]['tmplsetter']." has not enough edits!");
 276+ $wrongfile = true;
 277+ $wrongfiles[$picture["title"]] = "The account of the user who set the template ([[User:".$wgAuthor."|]]) has under ".$config['mincontribs']." edits.<br />'''Unlock:''' An autoconfirmed user with more than ".$config['mincontribs']." edits should delete the parameters <code><nowiki>|</nowiki>nobot=true<nowiki>|</nowiki>reason=...</code> in this image. Thank you --~~~~";
 278+ }
 279+ }
 280+}
 281+//Benutzer geprüft #########################################
 282+
 283+
 284+
 285+
 286+//per regex auf schlechte dateinamen prüfen
 287+$regex = "File:(?:DVC|CIMG|IMGP?|PICT|DSC[FN]?|DUW|JD|MGP|scan|untitled|foto|imagen|img|image|picture|p|BILD)?[0-9_ \-\(\)\{\}\[\]]+\..*";
 288+if(preg_match("/".$regex."/",$picture['title']) == 1)
 289+{
 290+ //Kann nicht hochgeladen werden, Blacklisted
 291+ /*#######################
 292+Im moment deaktiviert
 293+######################*/
 294+ //$wrongfile = true;
 295+ //$wrongfiles[$picture["title"]] = "Image can't be rotated by Rotatebot because it has a senseless title. Please rename first.";
 296+ $addrename[$picture["title"]] = true;
 297+} else {
 298+ $addrename[$picture["title"]] = false;
 299+}
 300+
 301+
 302+if(!$wrongfile) //Bild scheint OK zu sein
 303+{
 304+ logfile("picture and user check finished, sorted for download");
 305+
 306+ $catcontent[$arraykey]['title'] = str_replace(" ", "_", $picture["title"]);
 307+ $catcontent[$arraykey]['degree'] = $picture["sortkey"];
 308+ $catcontent[$arraykey]['since'] = $revitimestp;
 309+ $catcontent[$arraykey]['pageid'] = $picture['pageid'];
 310+ $catcontent[$arraykey]['url'] = $picture['imageinfo']['0']['url'];
 311+ $catcontent[$arraykey]['metadata'] = $picture['imageinfo']['0']['metadata'];
 312+ $catcontent[$arraykey]['uploader'] = $picture['imageinfo']['0']['user'];
 313+ $catcontent[$arraykey]['upltime'] = $picture['imageinfo']['0']['timestamp'];
 314+ $catcontent[$arraykey]['size'] = $picture['imageinfo']['0']['width']."x".$picture['imageinfo']['0']['height'];
 315+ $catcontent[$arraykey]['exifkey'] = 0;
 316+ $catcontent[$arraykey]['exifkeyafter'] = 0;
 317+ $catcontent[$arraykey]['exifwriteerr'] = "";
 318+ $arraykey = $arraykey +1;
 319+}
 320+else
 321+{
 322+//array löschen!
 323+$papierkorb = array_splice($catcontent,$arraykey,1);
 324+}
 325+
 326+
 327+
 328+}
 329+
 330+$picture = array();//leeren (Speicherplatz)
 331+
 332+$countimages = count($catcontent);
 333+
 334+/* ***********************************************************
 335+ ******* ARRAY MIT BILDER & GRADE GELADEN ***************
 336+ ******* WEITER GEHT'S MIT IMAGESAVE ***************
 337+ *********************************************************** */
 338+logfile("------------");
 339+logfile("Picture load finished - $countimages pictures ready for download.");
 340+
 341+
 342+foreach($catcontent as $filename => $arraycontent)
 343+{
 344+logfile("save ".$arraycontent['title']);
 345+$savepath = $homedir."cache/";
 346+
 347+//$fp = fopen($arraycontent['url'], "rb");
 348+//fpassthru($fp);
 349+//fclose($fp);
 350+//$file = ob_get_contents();
 351+//ob_clean();
 352+$file = file_get_contents($arraycontent['url']) or suicide("Kann ".$arraycontent['title']." nicht downloaden! (".$arraycontent['url'].")");
 353+
 354+$fp = fopen($savepath.$filename.".".$arraycontent['filetype'], "wb+");
 355+fwrite($fp, $file);
 356+fclose($fp);
 357+//sleep(1);
 358+}
 359+$file = "";//Datei löschen um Speicherplatz zu bekommen
 360+logfile("Download finished!");
 361+
 362+
 363+
 364+/*########## BILDER DREHEN, EXIF ANPASSEN ############# */
 365+$catcontent2 = array();
 366+foreach($catcontent as $filename => $arraycontent)
 367+{
 368+ $return=0; // reset
 369+ if($arraycontent['filetype'] == "jpg") //Für JPEG lossless methode
 370+ {
 371+ //Exif auslesen
 372+ // /home/luxo/rotbot/exiftool/exiftool -IFD0:Orientation -b 1.jpg -a is to get dupe tags, too
 373+ $exif = system("/home/luxo/rotbot/exiftool/exiftool -IFD0:Orientation -b -a ".$savepath.$filename.".".$arraycontent['filetype']."");
 374+ settype($exif, "integer");
 375+ logfile("EXIF ist auf $exif");
 376+ $arraycontent['exifkey'] = $exif; //for editsummary
 377+
 378+ if ($arraycontent['degree'] == "RESETEXIF") { // if ignoring EXIF is wished ...
 379+ switch($exif) {
 380+ case 0: // no Orientation tag existent
 381+ case 1:
 382+ logfile("reset EXIF Orientation reset requested but it was already 0 or 1");
 383+ $return=1007; // unexpected EXIF was found
 384+ break;
 385+ default:
 386+ $exifR = 0; // ignore any existing EXIF
 387+ }
 388+
 389+ } else {
 390+ if ($exif >= 10) { //do we have duplicate Orientation tags? They get reported by exiftool like "18".
 391+ logfile("duplicate Orientation tags!");
 392+ $return=1009; // Duplicate Orientation tags were found
 393+ } else {
 394+ //Use EXIF Orientation (= roation applied by MediaWiki for displaying) and user input to find the correct rotation
 395+ switch($exif) {
 396+ case 0: // no Orientation tag existent
 397+ case 1:
 398+ if ($arraycontent['degree'] == 0) { // No rotation requested AND exif normal?
 399+ logfile("exif was 0 or 1 and no rotation requested");
 400+ $return=1008; //
 401+ } else {
 402+ $exifR = 0;
 403+ }
 404+ break;
 405+ case 3:
 406+ $exifR = 180;
 407+ break;
 408+ case 6:
 409+ $exifR = 90;
 410+ break;
 411+ case 8:
 412+ $exifR = 270;
 413+ break;
 414+ default:
 415+ logfile("exif was not 0,1,3,6,8");
 416+ $return=1003; // unexpected EXIF was found
 417+ }
 418+ }
 419+ }
 420+
 421+ if ($return == 0) { // if no unexpected EXIF was found
 422+
 423+ if ($arraycontent['degree'] == "RESETEXIF") { // if ignoring EXIF is wished ...
 424+ $realrotate = 0; // do not rotate
 425+ $arraycontent['realdegree'] = 0; // for editsummary
 426+ } else {
 427+ $realrotate = $arraycontent['degree'] + $exifR; // Saibo2 formula. user specified rotaation + already applied rotation by MW
 428+ logfile("Bild muss um $realrotate Grad gedreht werden.");
 429+ $realrotate = (360 + ($realrotate % 360)) % 360; // convert to 0-259
 430+ $arraycontent['realdegree'] = $realrotate; // for editsummary
 431+ }
 432+ switch($realrotate)
 433+ {
 434+ case 0:
 435+ //kopie erstellen
 436+ logfile("just exif correction, picture correct");
 437+ $cmd = "cp ".$savepath.$filename.".".$arraycontent['filetype']." ".$savepath.$filename."_2.".$arraycontent['filetype'];
 438+ logfile($cmd);
 439+ passthru($cmd);
 440+ break;
 441+ case 90:
 442+ case 180:
 443+ case 270:
 444+ //rotieren ...
 445+ $cmd = "jpegtran -rotate ".$realrotate." -trim -copy all ".$savepath.$filename.".".$arraycontent['filetype']." > ".$savepath.$filename."_2.".$arraycontent['filetype'];
 446+ logfile($cmd);
 447+ passthru($cmd,$return);
 448+ logfile($arraycontent['title']." rotated by ".$realrotate."°.");
 449+ break;
 450+
 451+ default:
 452+ logfile("Bullshit happend: realrotate was $realrotate.");
 453+ $return=1004;
 454+ }
 455+
 456+//escape shell nicht notwendig, keine Benutzerdaten im cmd verwendet
 457+
 458+ $doBruteForceClean = false; // init
 459+
 460+ if ($return == 0 && !($exif == 0 || $exif == 1)) { // only if no error occured and change necessary
 461+ //EXIF-orient-tag auf 1 stellen, nur bei jpeg
 462+ // /home/luxo/rotbot/exiftool/exiftool -Orientation=1 -n 1.jpg
 463+ if ($exif >= 10) { //dupe Orientation tags? Kill 'em all!
 464+ // Needs to be removed because otherwise the duplicate tag stays
 465+ // first attempt
 466+ $cmd = "/home/luxo/rotbot/exiftool/exiftool -IFD0:Orientation= -n ".$savepath.$filename."_2.".$arraycontent['filetype'];
 467+ logfile($cmd);
 468+ passthru($cmd,$retexifwrite);
 469+
 470+ if ($retexifwrite == 0) { // if successful
 471+ logfile("No errors on EXIF-to-0");
 472+ $exifwriteerr = ""; // clear - no error since it worked in first attempt
 473+ } else {
 474+ // second attempt (ignoring minor errors)
 475+ $cmd = "/home/luxo/rotbot/exiftool/exiftool -IFD0:Orientation= -n -m ".$savepath.$filename."_2.".$arraycontent['filetype'];
 476+ logfile($cmd);
 477+ passthru($cmd,$retexifwrite);
 478+
 479+ if ($retexifwrite == 0) { // if successful
 480+ logfile("No errors on EXIF-to-0 (second try)");
 481+ $exifwriteerr = " - EXIF had minor errors. Some EXIF could be lost. - ";
 482+ } else {
 483+ $doBruteForceClean = true;
 484+ }
 485+ }
 486+ } else {
 487+ // first attempt
 488+ $cmd = "/home/luxo/rotbot/exiftool/exiftool -IFD0:Orientation=1 -n ".$savepath.$filename."_2.".$arraycontent['filetype'];
 489+ logfile($cmd);
 490+ passthru($cmd,$retexifwrite);
 491+
 492+ if ($retexifwrite == 0) { // if successful
 493+ logfile("no errors when setting EXIF to 1");
 494+ $exifwriteerr = ""; // clear - no error since it worked in first attempt
 495+ } else {
 496+ // second attempt (ignoring minor errors)
 497+ $cmd = "/home/luxo/rotbot/exiftool/exiftool -IFD0:Orientation=1 -n -m ".$savepath.$filename."_2.".$arraycontent['filetype'];
 498+ logfile($cmd);
 499+ passthru($cmd,$retexifwrite);
 500+
 501+ if ($retexifwrite == 0) { // if successful
 502+ logfile("no errors when setting EXIF to 1 (second try)");
 503+ $exifwriteerr = " - EXIF had minor errors. Some EXIF could be lost. - ";
 504+ } else {
 505+ $doBruteForceClean = true;
 506+ }
 507+ }
 508+ }
 509+
 510+
 511+ if ($doBruteForceClean) {
 512+ // third attempt (ignoring nearly all errors) - copy all readable tags but leave the Orientation tag away
 513+ $cmd = "/home/luxo/rotbot/exiftool/exiftool -all= -tagsfromfile @ -all:all --IFD0:Orientation ".$savepath.$filename."_2.".$arraycontent['filetype'];
 514+ logfile($cmd);
 515+ passthru($cmd,$retexifwrite);
 516+
 517+ if ($retexifwrite == 0) { // if successful
 518+ logfile("no errors when setting EXIF to 0 (third try)");
 519+ $exifwriteerr = " - EXIF had major errors. Great parts of EXIF could be lost. - ";
 520+ } else {
 521+ // complete failure
 522+ $return = 1005;
 523+ }
 524+ }
 525+
 526+
 527+ $arraycontent['exifwriteerr'] = $exifwriteerr; //for editsummary
 528+ }
 529+
 530+ if ($return == 0) { // only if no error occured
 531+ //Exif auslesen als Test
 532+ // /home/luxo/rotbot/exiftool/exiftool -IFD0:Orientation -b 1.jpg -a is to get dupe tags, too
 533+ $exifafter = system("/home/luxo/rotbot/exiftool/exiftool -IFD0:Orientation -b -a ".$savepath.$filename."_2.".$arraycontent['filetype']."");
 534+ settype($exifafter, "integer");
 535+ logfile("read EXIF after finish: $exifafter");
 536+ $arraycontent['exifkeyafter'] = $exifafter; //for editsummary
 537+
 538+ if (!($exifafter == 0 || $exifafter == 1)) { // if unsuccessful
 539+ $return = 1006;
 540+ }
 541+ }
 542+ }
 543+ }
 544+ else //Für png's und gif's
 545+ {
 546+ passthru("convert ".$savepath.$filename.".".$arraycontent['filetype']." -rotate ".$arraycontent['degree']." ".$savepath.$filename."_2.".$arraycontent['filetype'],$returnP);
 547+ logfile($arraycontent['title']." rotated by ".$arraycontent['degree']."°: ".$returnP);
 548+ }
 549+ // TODO: ich bau mal ne Verwendung von $returnP in der Fehlerbehandlung nachfolgend ein.. der Fehlerwert beim PNG/GIF-Drehen wird gar nicht verwendet
 550+
 551+
 552+// sleep(5); //wait 5 sec. between rotating images
 553+
 554+ if($return != 0)
 555+ {
 556+ //Bild aussortieren, da defekt
 557+
 558+ $rx = "";
 559+ switch($return) {
 560+ case 1:
 561+ $rx = " (DCT coefficient out of range)";
 562+ $wrongfiles[$arraycontent["title"]] = "corrupt JPEG file.".$rx;
 563+ logfile("sort out; corrupt JPEG file.".$rx);
 564+ break;
 565+ case 2:
 566+ $rx = " (Premature end of JPEG file)";
 567+ $wrongfiles[$arraycontent["title"]] = "corrupt JPEG file.".$rx;
 568+ logfile("sort out; corrupt JPEG file.".$rx);
 569+ break;
 570+ case 1003:
 571+ $rx = " ($exif)";
 572+ $wrongfiles[$arraycontent["title"]] = "Unexpected exif orientation: ".$rx;
 573+ logfile("unexpected exif orientation.".$rx);
 574+ break;
 575+ case 1004:
 576+ $rx = " ($realrotate)";
 577+ $wrongfiles[$arraycontent["title"]] = "Bullshit happend: realrotate was.".$rx;
 578+ logfile("Bullshit happend: realrotate was.".$rx);
 579+ break;
 580+ case 1005:
 581+ $rx = " (ec: $retexifwrite)";
 582+ $wrongfiles[$arraycontent["title"]] = "EXIF had severe errors on write attempt.".$rx;
 583+ logfile("EXIF had severe errors on write attempt.".$rx);
 584+ break;
 585+ case 1006:
 586+ $rx = " ($exifafter)";
 587+ $wrongfiles[$arraycontent["title"]] = "EXIF had not 0 or 1 after process.".$rx;
 588+ logfile("EXIF had not 0 or 1 after process.".$rx);
 589+ break;
 590+ case 1007:
 591+ $rx = " ($exif)";
 592+ $wrongfiles[$arraycontent["title"]] = "reset EXIF Orientation reset requested but it was already 0 or 1.".$rx;
 593+ logfile("reset EXIF Orientation reset requested but it was already 0 or 1.".$rx);
 594+ break;
 595+ case 1008:
 596+ $rx = " ($exif)";
 597+ $wrongfiles[$arraycontent["title"]] = "No rotation requested and no EXIF-based rotation? Sorry, there is nothing I can do!".$rx;
 598+ logfile("No rotation requested and no EXIF-based rotation present. Nothing to do.".$rx);
 599+ break;
 600+ case 1009:
 601+ $rx = " ($exif)";
 602+ $wrongfiles[$arraycontent["title"]] = "Duplicate IFD0:Orientation tags were found. MW handles those in a strange way. Use rotate template's parameter 'resetexif' (instead of degree number) to reset the EXIF orientation information of this file.".$rx;
 603+ logfile("Duplicate IFD0:Orientation tags were found.".$rx);
 604+ break;
 605+ }
 606+ }
 607+ else
 608+ {
 609+ //Korrekt gedreht, Weiter gehen
 610+ $catcontent2[$filename] = $arraycontent;
 611+ }
 612+}
 613+logfile("ALl images turned and exif corrected!\nStart upload...");
 614+
 615+// ####################### Bilder gedreht! Weiter gehts mit Hochladen :) ############
 616+include("upload.php");
 617+include("login.php");
 618+
 619+
 620+foreach($catcontent2 as $filename => $arraycontent)
 621+ {
 622+
 623+ //upload summary
 624+
 625+ if ($arraycontent['degree'] == "RESETEXIF") {
 626+ $filesum = sprintf($config['resetuploadsummary']." ".$config['exifuploadsum'],$arraycontent['exifkey'],$arraycontent['exifkeyafter'],$arraycontent['exifwriteerr'],$arraycontent['realdegree']);
 627+ } else {
 628+
 629+ if (!($arraycontent['exifkey'] == 0 || $arraycontent['exifkey'] == 1)) { // if EXIF was not 0 or 1
 630+ $filesum = sprintf($config['uploadsummary']." ".$config['exifuploadsum'],$arraycontent['degree'],$arraycontent['exifkey'],$arraycontent['exifkeyafter'],$arraycontent['exifwriteerr'],$arraycontent['realdegree']);
 631+ } else {
 632+ $filesum = sprintf($config['uploadsummary'],$arraycontent['degree']);
 633+ }
 634+ }
 635+
 636+ //Hochladen
 637+ Logfile("upload ".$arraycontent['title']." ... intern name: ".$filename."_2.".$arraycontent['filetype']);
 638+ wikiupload("commons.wikimedia.org",$filename."_2.".$arraycontent['filetype'],substr($arraycontent['title'],5),"",$filesum);
 639+ Logfile($arraycontent['title']." uploaded!");
 640+ $catcontent2[$filename]['doneat'] = date("Y-m-d\TH:i:s\Z",time());//2007-10-01T10:13:15Z
 641+ //Quelltext laden
 642+ $quelltext = file_get_contents("http://commons.wikimedia.org/w/index.php?title=".urlencode(str_replace(" ", "_",$arraycontent['title']))."&action=raw");
 643+
 644+ //Template erkennen
 645+ $strabtemp = NULL;
 646+ $strabtemp = stristr($quelltext, "{{Rotate");
 647+ if(!$strabtemp) { $strabtemp = stristr($quelltext, "{{Template:Rotate"); }
 648+ $upto = strpos($strabtemp,"}}");
 649+ $template = substr($strabtemp,0,$upto+2);
 650+
 651+ //löschen
 652+ $forupload = str_ireplace($template."\n", "", $quelltext, $count); // delete template and a newline directly afterwards
 653+ $forupload = str_ireplace($template, "", $forupload, $count2); // delete template
 654+
 655+ //Speichern
 656+ if($count + $count2 > 0)
 657+ {
 658+ logfile("remove template $template");
 659+
 660+ //Editsummary generieren
 661+ if($arraycontent['degree'] == "RESETEXIF") {
 662+ $edsum = $config['reseteditsummary'];
 663+
 664+ } else {
 665+ $edsum = sprintf($config['editsummary'],$arraycontent['degree']);
 666+ }
 667+
 668+ $c = wikiedit("commons.wikimedia.org",$arraycontent['title'],$forupload,$edsum,"1");
 669+
 670+ if($c == true)
 671+ {
 672+ $nodelete[$arraycontent['title']] = 0;
 673+ }
 674+ else
 675+ {
 676+ $nodelete[$arraycontent['title']] = 1;
 677+ }
 678+
 679+ }
 680+ else
 681+ {
 682+ logfile("ERROR: TEMPLATE NICHT GEFUNDEN!");
 683+ $nodelete[$arraycontent['title']] = 1;
 684+ }
 685+ logfile("\n-------NEXT--------- \n");
 686+// sleep(5);
 687+}
 688+logfile("Upload finished. Do error pictures now.");
 689+
 690+
 691+
 692+
 693+
 694+
 695+//Cache leeren
 696+foreach($catcontent2 as $filename => $arraycontent)
 697+{
 698+unlink("/home/luxo/rotbot/cache/".$filename.".".$arraycontent['filetype']);
 699+unlink("/home/luxo/rotbot/cache/".$filename."_2.".$arraycontent['filetype']);
 700+unlink("/home/luxo/rotbot/cache/".$filename."_2.".$arraycontent['filetype']."_original");
 701+}
 702+logfile("cache cleared. Write log now.");
 703+
 704+//##################### LOG LOG LOG LOG LOG LOG LOG #########################
 705+
 706+$logfilew = file_get_contents("http://commons.wikimedia.org/w/index.php?title=User:Rotatebot/Log&action=raw");
 707+$somanyrot = count($catcontent2);
 708+
 709+$logfilew = deleteold($logfilew,$somanyrot,$config['logfilesize'],$config['logheader']);
 710+
 711+// Fehlerbilder durchgehen
 712+foreach($wrongfiles as $title => $reason)
 713+{
 714+
 715+
 716+
 717+ $quelltext = file_get_contents("http://commons.wikimedia.org/w/index.php?title=".urlencode(str_replace(" ", "_",$title))."&action=raw");
 718+
 719+ $forupload = str_ireplace("{{Rotate", "{{Rotate|nobot=true|reason='''Reason''': $reason", $quelltext, $count);
 720+
 721+ if($addrename[$title] == true && !stristr($forupload,"{{rename"))
 722+ {
 723+ $renametemp = "{{Rename}}\n";
 724+ }
 725+ else
 726+ {
 727+ $renametemp = "";
 728+ }
 729+
 730+ $forupload = $renametemp.$forupload;
 731+ if($count > 0)
 732+ {
 733+
 734+ wikiedit("commons.wikimedia.org",str_replace(" ", "_",$title),$forupload,"Bot: Can't rotate image","1");
 735+ $logfilew .= "\n----\n
 736+ <span style=\"color:red;text-decoration:blink\">'''Error'''</span> can't rotate [[:$title]]:\n ''$reason''\n";
 737+
 738+ logfile("set template of $title to nobot");
 739+ }
 740+ else
 741+ {
 742+ logfile("Template:Rotate in $title NOT FOUND!");
 743+ $logfilew .= "\n----\n
 744+ <span style=\"color:red;text-decoration:blink\">'''Error'''</span> can't rotate [[:$title]]:\n ''$reason''\n";
 745+ $logfilew .= "<big style='color:red;text-decoration:blink;'>'''Warning:''' Template not found, file probably still in the category!!</big>\n";
 746+ }
 747+
 748+}
 749+
 750+
 751+//Normaler Log schreiben
 752+
 753+foreach($catcontent2 as $arraycontent)
 754+{
 755+ $logfilew .= "\n----\n";
 756+ $logfilew .= "[[".$arraycontent['title']."|thumb]]\n";
 757+ $logfilew .= "*[[:".$arraycontent['title']."]] (".$arraycontent['size'].")\n";
 758+
 759+ if($nodelete[$arraycontent['title']] == 1)
 760+ {
 761+
 762+ $logfilew .= "<big style='color:red;text-decoration:blink;'>'''Warning:''' Template not found, file probably still in the category!!</big>\n";
 763+
 764+ }
 765+
 766+
 767+ if($arraycontent['metadata']['Make'] and $arraycontent['metadata']['DateTimeDigitized'])
 768+ {
 769+ $logfilew .= "**Image taken with a [[:en:".trim($arraycontent['metadata']['Make'])."|".ucwords(strtolower(trim($arraycontent['metadata']['Make'])))."]] ".ucwords(strtolower(trim($arraycontent['metadata']['Model'])))." at ".trim($arraycontent['metadata']['DateTimeDigitized']).".\n";
 770+ }
 771+
 772+ $logfilew .= "**Last image-version uploaded by [[User:".$arraycontent['uploader']."|]] at ".timestampto($arraycontent['upltime'])." (UTC)\n";
 773+ if($arraycontent['tmplsetter'])
 774+ {
 775+ $logfilew .= "**{{[[Template:Rotate|]]}} added (or modified) by [[User:".$arraycontent['tmplsetter']."|]] at ".timestampto($arraycontent['since'])." (UTC)\n";
 776+ $logfilew .= $userforlog[$arraycontent['tmplsetter']]."\n";
 777+ }
 778+ $logfilew .= "**Rotated by ~~~ through ".$arraycontent['degree']."° at ".timestampto($arraycontent['doneat'])." (UTC) (=".difftime($arraycontent['since'],$arraycontent['doneat'])." later)\n";
 779+ $logfilew .= "<br style=\"clear:both;\" clear=\"all\" />";
 780+}
 781+
 782+if($somanyrot > 0 OR count($wrongfiles) > 0)
 783+{
 784+ logfile("write logfile. ($somanyrot pictures)");
 785+
 786+ if(count($wrongfiles) > 0)
 787+ {
 788+ $msgerr = ", ".count($wrongfiles)." errors";
 789+ }
 790+
 791+ wikiedit("commons.wikimedia.org","User:Rotatebot/Log",$logfilew,"Bot: $somanyrot images rotated".$msgerr.".","1");
 792+}
 793+
 794+mysql_close($myslink); // TODO should/can this be moved to function suicide? - Probably not due to line 33.
 795+suicide ("Bot finished.");
 796+// END script
 797+
 798+
 799+
 800+
 801+
 802+// functions start:
 803+
 804+
 805+
 806+
 807+function logfile($text)
 808+{
 809+ echo $text."\n";
 810+}
 811+
 812+function timestampto($intime,$unix=false)
 813+{
 814+//UNIX-zeit erstellen
 815+//2007-11-20T19:11:17Z
 816+$year = substr($intime,0,4);
 817+$month = substr($intime,5,2);
 818+$day = substr($intime,8,2);
 819+$hour = substr($intime,11,2);
 820+$min = substr($intime,14,2);
 821+$sec = substr($intime,17,2);
 822+
 823+$unixtime = mktime($hour,$min,$sec,$month,$day,$year);
 824+if($unix == true)
 825+{
 826+return $unixtime;
 827+}
 828+else
 829+{
 830+return date("H:i, d F Y",$unixtime);
 831+}
 832+
 833+}
 834+
 835+function difftime($settime, $rottime)
 836+{
 837+$unixset = timestampto($settime,true);
 838+$unixrot = timestampto($rottime,true);
 839+
 840+$diff = $unixrot - $unixset; //differenz in sekunden
 841+
 842+
 843+
 844+return tellSeconds($diff);
 845+
 846+}
 847+
 848+function tellSeconds($NumberOfSeconds) // function Copyright (C) simplecontent.net
 849+{
 850+
 851+ $time_map = array(
 852+
 853+ 'Years' => 31536000, # 365 Tage
 854+ 'Months' => 2592000, # 30 Tage
 855+ 'Weeks' => 604800, # 7 Tage
 856+ 'Days' => 86400,
 857+ 'Hours' => 3600,
 858+ 'Minutes' => 60,
 859+ 'Seconds' => 1,
 860+ );
 861+
 862+ $SecondsTotal = $NumberOfSeconds;
 863+
 864+ $SecondsLeft = $SecondsTotal;
 865+
 866+ $stack = array();
 867+
 868+ foreach ($time_map as $k => $v) {
 869+
 870+ if ($SecondsLeft < $v || $SecondsLeft == 0) {
 871+ continue;
 872+ } else {
 873+ $amount = floor($SecondsLeft/ $v);
 874+ $SecondsLeft = $SecondsLeft % $v;
 875+
 876+ $label = ($amount>1)
 877+ ? $k
 878+ : substr($k, 0, -1);
 879+
 880+ $stack[] = sprintf("'''%s''' %s", $amount, $label);
 881+ }
 882+ }
 883+ $cnt = count($stack);
 884+
 885+ if ($cnt > 1){
 886+ $tmp1 = array_pop($stack);
 887+ $tmp2 = array_pop($stack);
 888+ array_push ($stack, $tmp2 . ' and '.$tmp1);
 889+ };
 890+ $result = join (', ', $stack);
 891+ return $result;
 892+
 893+}
 894+
 895+function deleteold($content,$newab,$maxonlog,$logheader)
 896+{
 897+//$maxonlog = 20; //Maximale Logfileabschnitte hier einstellen
 898+
 899+$beginnat = 0;
 900+$abschnittarray = array("0");
 901+while($pos = strpos($content,"----",$beginnat))
 902+{
 903+$abschnittarray[] = $pos;
 904+
 905+$beginnat = $pos + 4;
 906+}
 907+$abschnittarray[] = strlen($content);//letzter ist am seitenende
 908+
 909+$alte = count($abschnittarray) - 2;
 910+
 911+logfile("$alte sections found!");
 912+$totneu = $newab + $alte;
 913+if($totneu <= $maxonlog)
 914+{
 915+//Neue Abschnitte nur anhängen KORREKT
 916+logfile("nothing to delete, just add");
 917+return $content;
 918+
 919+//COUNTER
 920+$counter = file_get_contents("/home/luxo/rotbot/counter.txt");
 921+$counter = $counter + $newab;
 922+file_put_contents("/home/luxo/rotbot/counter.txt",$counter);
 923+}
 924+else
 925+{
 926+//alte löschen
 927+$zuviele = $totneu - $maxonlog ;
 928+
 929+
 930+if($zuviele > $alte) //nicht mehr löschen als da sind.
 931+{
 932+$zuviele = $alte;
 933+}
 934+
 935+//zählen wie viele abschnitte neu auf der seite sind
 936+$abschnitteneu = $totneu - $zuviele;
 937+
 938+
 939+logfile("delete $zuviele old sections.");
 940+
 941+
 942+$bereich = $zuviele+1;
 943+logfile("delete section 1 to $bereich");
 944+
 945+$intro = substr($content,0,$abschnittarray['1']);
 946+
 947+//COUNTER
 948+$counter = file_get_contents("/home/luxo/rotbot/counter.txt");
 949+$counter = $counter + $newab;
 950+file_put_contents("/home/luxo/rotbot/counter.txt",$counter);
 951+logfile("new counter: $counter.");
 952+
 953+$intro = sprintf($logheader."\n",$abschnitteneu,$counter); //NEU in settings definiert: der header vom Log
 954+$deleteabschn = substr($content,$abschnittarray['1'],$abschnittarray[$bereich]-$abschnittarray['1']);
 955+$rest = substr($content,$abschnittarray[$bereich]);
 956+
 957+return $intro.$rest;
 958+
 959+}
 960+
 961+}
 962+
 963+function botsetup()
 964+{
 965+ $setupraw = file("http://commons.wikimedia.org/w/index.php?title=User:Rotatebot/config.js&action=raw");
 966+
 967+ foreach($setupraw as $line)
 968+ {
 969+ $line = trim($line);
 970+
 971+ if(substr($line,0,2) != "//" AND $line != "")
 972+ {
 973+
 974+ $gleich = strpos($line, "=");
 975+
 976+ $namecon = trim(substr($line,3,$gleich-3));
 977+
 978+ $stripu = strpos($line,";");
 979+
 980+ $content = trim(substr($line,$gleich+1,$stripu - ($gleich + 1)));
 981+
 982+ //falls vorhanden "" entfernen
 983+ if(substr($content, 0, 1) == '"')
 984+ {
 985+ $content = substr($content, 1);
 986+ }
 987+
 988+ if(substr($content, -1) == '"')
 989+ {
 990+ $content = substr($content, 0, -1);
 991+ }
 992+
 993+ $content = trim($content);
 994+
 995+ $array[$namecon] = $content;
 996+
 997+ }
 998+ }
 999+ return $array;
 1000+}
 1001+
 1002+function TsToUnixTime($tstime)
 1003+{
 1004+ $regYear = substr($tstime,0,4);
 1005+ $regMonth = substr($tstime,4,2);
 1006+ $regDay = substr($tstime,6,2);
 1007+ $regHour = substr($tstime,8,2);
 1008+ $regMin = substr($tstime,10,2);
 1009+ $regSec = substr($tstime,12,2);
 1010+
 1011+return mktime($regHour, $regMin, $regSec, $regMonth, $regDay, $regYear);
 1012+}
 1013+
 1014+function hexToStr($hex)
 1015+{
 1016+ $string='';
 1017+ for ($i=0; $i < strlen($hex)-1; $i+=2)
 1018+ {
 1019+ $string .= chr(hexdec($hex[$i].$hex[$i+1]));
 1020+ }
 1021+ return $string;
 1022+}
 1023+
 1024+
 1025+//checks for other concurrently running rotatebot instances. Exits if not alone on the world
 1026+//Params:
 1027+// global $myLockfile - String containing a filename to be touched
 1028+// $dontDieOnLockProblems - Boolean for overriding death
 1029+function getLockOrDie($dontDieOnLockProblems) {
 1030+ global $myLockfile;
 1031+
 1032+ if (!file_exists($myLockfile)) {
 1033+ system("touch ".$myLockfile);
 1034+ if (!file_exists($myLockfile)) {
 1035+ if ($dontDieOnLockProblems) {
 1036+ logfile("Could not create lock file. DontDieMode prevents death.");
 1037+ } else {
 1038+ die("Could not create lock file. Exit.");
 1039+ }
 1040+ }
 1041+ } else {
 1042+ if ($dontDieOnLockProblems) {
 1043+ logfile("Could not get lock. Lock file already present. DontDieMode prevents death.");
 1044+ } else {
 1045+ die("Could not get lock. Lock file already present. Exit.");
 1046+ }
 1047+ }
 1048+}
 1049+
 1050+// tries to remove the lockfile. Logs any errors.
 1051+//Params: global $myLockfile - String containing a filename to be removed
 1052+function removeLock() {
 1053+ global $myLockfile;
 1054+
 1055+ if (file_exists($myLockfile)) {
 1056+ system("rm ".$myLockfile);
 1057+ if (file_exists($myLockfile)) {
 1058+ logfile("Warning: for some reason the lockfile could not be removed.");
 1059+ }
 1060+ } else {
 1061+ logfile("Warning: for some reason the lockfile was missing although it was expected to exist.");
 1062+ }
 1063+}
 1064+
 1065+// gracefully commits sucide. Removes the lock file before...
 1066+function suicide ($exitcodeOrString) {
 1067+ removeLock();
 1068+ die($exitcodeOrString);
 1069+}
 1070+
 1071+?>
Property changes on: trunk/tools/rotatebot/rotbot.php
___________________________________________________________________
Added: svn:eol-style
11072 + native
Index: trunk/tools/rotatebot/upload.php
@@ -0,0 +1,156 @@
 2+<?php
 3+/* Rotbot © Luxo 2008
 4+
 5+
 6+ */
 7+
 8+/*$descri = "{{Information
 9+|Description=Test-Image for my new rotate-bot. Please do '''not delete''' - I request a speedy deletion if I'm finished with testing. Thank you --~~~~
 10+|Source=self made
 11+|Date=17.11.2007
 12+|Author=[[User:Luxo]]
 13+|Permission= Public Domain
 14+|other_versions= -
 15+}}
 16+
 17+{{PD-self}}
 18+";
 19+
 20+wikiupload("commons.wikimedia.org","test2.jpg","Test for Rotatebot.jpg","",$descri);*/
 21+
 22+// ############### EDIT WIKIPEDIA - FUNCTION ###############
 23+function wikiupload($project,$filename_local,$filename_wiki,$license,$desc)
 24+{
 25+global $cookies;
 26+$username = "Rotatebot";
 27+$password = "**removed**";
 28+
 29+logfile("Lade Bild '$filename_wiki' hoch am ".date("r",time()).".");
 30+
 31+//$cookies
 32+if(!$cookies["commonswikiUserName"] OR !$cookies["commonswikiUserID"])
 33+{
 34+ $username = "Rotatebot";
 35+ $password = "**removed**";
 36+ logfile("Login to $project!\n");
 37+ wikilogin($username,$password,$project,$useragent);
 38+ logfile("logged in to $project!\n");
 39+ print_r($cookies);
 40+}
 41+else
 42+{
 43+ logfile("already logged in to $project for upload\n");
 44+}
 45+
 46+
 47+if($cookies) {
 48+logfile("Angemeldet in $project!\n");
 49+} else {
 50+die("Keine Cookies! Abbruch\n$header\n");
 51+}
 52+
 53+//Angemeldet, Cookies formatieren**************
 54+
 55+
 56+foreach ($cookies as $key=>$value)
 57+{
 58+ $cookie .= trim($value).";";
 59+}
 60+$cookie = substr($cookie,0,-1);
 61+
 62+//************ BILD HOCHLADEN ****************
 63+wiki_upload_file ($filename_local,$filename_wiki,$license,$desc,$project,$cookie);
 64+
 65+}
 66+
 67+/* ###########################################
 68+ ########## FUNKTIONEN #####################
 69+ ########################################### */
 70+
 71+function wiki_upload_file ($filename_local,$filename_wiki,$license,$desc,$wiki,$cookies)
 72+{
 73+ $file1 = "";//Löschen wegen Speicherplatz
 74+$file1 = file_get_contents("/home/luxo/rotbot/cache/".$filename_local) or die("Fehler - Datei nicht gefunden! ($filename_local)");
 75+
 76+
 77+ $data_l = array("file.file" => $file1,
 78+ "wpDestFile" => $filename_wiki,
 79+ "wpUploadDescription" => str_replace("\\'","'",$desc),
 80+ "wpLicense" => $license,
 81+ "wpIgnoreWarning" => "1",
 82+ "wpUpload" => "Upload file");
 83+ $file1 = "";//Löschen wegen Speicherplatz
 84+ wiki_PostToHostFD($wiki, "/wiki/Special:Upload", $data_l, $wiki, $cookies);
 85+
 86+
 87+ $data_l = array();//Das auch löschen wegen Speicherplatz
 88+
 89+}
 90+function wiki_PostToHostFD ($host, $path, $data_l, $wiki, $cookies) //this function was developed by [[:de:User:APPER]] (Christian Thiele)
 91+{
 92+logfile("verbinde zu $host ...");
 93+ $useragent = "Luxobot/1.1 (toolserver; php) luxo@ts.wikimedia.org";
 94+ $dc = 0;
 95+ $bo="-----------------------------305242850528394";
 96+ $filename=$data_l['wpDestFile'];
 97+ $fp = fsockopen($host, 80, $errno, $errstr, 30);
 98+ if (!$fp) { echo "$errstr ($errno)<br />\n"; exit; }
 99+
 100+ fputs($fp, "POST $path HTTP/1.0\r\n");
 101+ fputs($fp, "Host: $host\r\n");
 102+ fputs($fp, "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n");
 103+ fputs($fp, "Accept-Charset: iso-8859-1,*,utf-8\r\n");
 104+ fputs($fp, "Cookie: ".$cookies."\r\n");
 105+ fputs($fp, "User-Agent: ".$useragent."\r\n");
 106+ fputs($fp, "Content-type: multipart/form-data; boundary=$bo\r\n");
 107+
 108+ foreach($data_l as $key=>$val)
 109+ {
 110+ // Hack for attachment
 111+ if ($key == "file.file")
 112+ {
 113+ $ds =sprintf("--%s\r\nContent-Disposition: attachment; name=\"wpUploadFile\"; filename=\"%s\"\r\nContent-type: image/png\r\nContent-Transfer-Encoding: binary\r\n\r\n%s\r\n", $bo, $filename, $val);
 114+ }
 115+ else
 116+ {
 117+ $ds =sprintf("--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", $bo, $key, $val);
 118+ }
 119+ $dc += strlen($ds);
 120+ }
 121+ $dc += strlen($bo)+3;
 122+ fputs($fp, "Content-length: $dc \n");
 123+ fputs($fp, "\n");
 124+
 125+ foreach($data_l as $key=>$val)
 126+ {
 127+ if ($key == "file.file")
 128+ {
 129+ $ds =sprintf("--%s\r\nContent-Disposition: attachment; name=\"wpUploadFile\"; filename=\"%s\"\r\nContent-type: image/png\r\nContent-Transfer-Encoding: binary\r\n\r\n%s\r\n", $bo, $filename, $val);
 130+ $data_1["file.file"] = "";//löschen
 131+ }
 132+ else
 133+ {
 134+ $ds =sprintf("--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", $bo, $key, $val);
 135+ }
 136+ fputs($fp, $ds );
 137+ }
 138+ $ds = "--".$bo."--\n";
 139+ fputs($fp, $ds);
 140+
 141+ $res = "";
 142+ while(!feof($fp))
 143+ {
 144+ $res .= fread($fp, 1);
 145+ }
 146+ fclose($fp);
 147+ file_put_contents("/home/luxo/rotbot/cache/log.txt",$res);
 148+ return $res;
 149+ $data_l = array();
 150+}
 151+
 152+
 153+
 154+
 155+
 156+
 157+?>
Property changes on: trunk/tools/rotatebot/upload.php
___________________________________________________________________
Added: svn:eol-style
1158 + native
Index: trunk/tools/rotatebot/login.php
@@ -0,0 +1,317 @@
 2+<?php
 3+/* Bilderbot © Luxo 2007
 4+
 5+ This file is part of Luxobot.
 6+
 7+ Luxobot is free software: you can redistribute it and/or modify
 8+ it under the terms of the GNU General Public License as published by
 9+ the Free Software Foundation, either version 3 of the License, or
 10+ (at your option) any later version.
 11+
 12+ Foobar is distributed in the hope that it will be useful,
 13+ but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ GNU General Public License for more details.
 16+
 17+ You should have received a copy of the GNU General Public License
 18+ along with Foobar. If not, see <http://www.gnu.org/licenses/>.
 19+
 20+ */
 21+
 22+
 23+
 24+// ############### EDIT WIKIPEDIA - FUNCTION ###############
 25+function wikiedit($project,$page,$newtext,$description,$minor)
 26+{
 27+global $cookies;
 28+ logfile("Funktion gestartet...");
 29+ logfile("Schreibe Text am ".date("r",time())." in die Seite '$page'.");
 30+
 31+ $useragent = "Luxo (toolserver; php) luxo@ts.wikimedia.org";
 32+
 33+//$cookies
 34+if(!$cookies["commonswikiUserName"] OR !$cookies["commonswikiUserID"])
 35+{
 36+ $username = "Rotatebot";
 37+ $password = "**removed**";
 38+ logfile("Login to $project!\n");
 39+ wikilogin($username,$password,$project,$useragent);
 40+ logfile("logged in to $project!\n");
 41+ print_r($cookies);
 42+}
 43+else
 44+{
 45+ logfile("already logged in to $project!\n");
 46+}
 47+
 48+
 49+
 50+
 51+//echo $header."\n\n";
 52+
 53+// Response Body auslesen
 54+/*while (!feof($fp)) {
 55+$linew=fgets($fp,255);
 56+$bodyw.=$linew;
 57+}
 58+echo $bodyw;*/
 59+$header = "";
 60+
 61+
 62+//Angemeldet, Cookies ausgelesen, editieren kann beginnen**************
 63+$fpb = fsockopen ($project, 80, $errno, $errstr, 30);
 64+
 65+//Bearbeiten-Seite aufrufen, um wpEditToken & cookie zu erhalten ***************
 66+$getrequest = "/w/index.php?title=".urlencode($page)."&action=edit";
 67+fputs($fpb, "GET $getrequest HTTP/1.1\n");
 68+fputs($fpb, "Host: $project\n");
 69+fputs($fpb, "User-Agent: $useragent\n");
 70+fputs($fpb, "Accept: $accept\n");
 71+fputs($fpb, "Accept-Language: de\n");
 72+
 73+foreach ($cookies as $key=>$value)
 74+{
 75+ $cookie .= trim($value).";";
 76+}
 77+$cookie = substr($cookie,0,-1);
 78+
 79+
 80+
 81+logfile("Lade Seite; Cookies: $cookie\n");
 82+
 83+fputs($fpb, "Cookie: ".$cookie."\n");
 84+
 85+fputs($fpb, "Connection: close\n");
 86+fputs($fpb, "\n");
 87+
 88+
 89+//Response Header auslesen forallem cooke********************
 90+do {
 91+$linex=fgets($fpb,255);
 92+$headerrx.=$linex;
 93+
 94+//auf cookie prüfen
 95+if(substr($linex,0,11) == "Set-Cookie:")
 96+{
 97+$rawcookie = substr($line,11,strpos($line,";")-11); //Format: session=DFJ3ASD2S
 98+ $cookiename = trim(substr($rawcookie,0,strpos($rawcookie,"=")));
 99+$cookies[$cookiename] = $rawcookie;
 100+}
 101+
 102+} while (trim($linex)!="");
 103+
 104+//cookie-header erneut generieren
 105+$cookie = "";
 106+foreach ($cookies as $key=>$value)
 107+{
 108+ $cookie .= trim($value).";";
 109+}
 110+$cookie = substr($cookie,0,-1);
 111+
 112+
 113+logfile("Neue Cookies: $cookie\n");
 114+
 115+//echo $headerrx."\n\n";
 116+// Response Body auslesen**********************
 117+while (!feof($fpb)) {
 118+$line=fgets($fpb,255);
 119+$bodyy.=$line;
 120+//Die verschiedenen form-data's auslesen
 121+if(strstr($line, "wpStarttime"))
 122+{
 123+$formdata['wpStarttime'] = $line;
 124+}
 125+if(strstr($line, "wpEdittime"))
 126+{
 127+$formdata['wpEdittime'] = $line;
 128+}
 129+if(strstr($line, "wpScrolltop"))
 130+{
 131+$formdata['wpScrolltop'] = $line;
 132+}
 133+if(strstr($line, "wpEditToken"))
 134+{
 135+$formdata['wpEditToken'] = $line;
 136+}
 137+if(strstr($line, "wpAutoSummary"))
 138+{
 139+$formdata['wpAutoSummary'] = $line;
 140+}
 141+if(strstr($line, "wpSave"))
 142+{
 143+$formdata['wpSave'] = $line;
 144+}
 145+}
 146+logfile("Seite geladen, Anmeldung prüfen.");
 147+
 148+if(strstr($bodyy,'"wgUserName": "Rotatebot",'))
 149+{
 150+logfile("Anmeldung erfolgreich!");
 151+
 152+//ende auslesen, verbindung schliessen
 153+fclose($fpb);
 154+
 155+//aus formdatas nur values nehmen
 156+
 157+foreach($formdata as $type => $formcontent)
 158+{
 159+
 160+$t1 = strstr($formcontent,'value="');
 161+$t2 = strpos($t1,'"',7);
 162+$t1 = substr($t1,7,$t2-7);
 163+
 164+$formdata["$type"] = $t1;
 165+}
 166+
 167+
 168+// ########################### POST-CONTENT VORBEREITEN #####################
 169+
 170+//content vorbereiten
 171+$content = "wpSection=&wpStarttime=".urlencode($formdata['wpStarttime'])."&wpEdittime=".urlencode($formdata['wpEdittime'])."&wpScrolltop=".urlencode($formdata['wpScrolltop'])."&wpTextbox1=".urlencode($newtext)."&wpSummary=".urlencode($description)."&wpMinoredit=".urlencode($minor)."&wpWatchthis=1&wpSave=".$formdata['wpSave']."&wpEditToken=".urlencode($formdata['wpEditToken'])."&wpAutoSummary=".urlencode($formdata['wpAutoSummary']);
 172+
 173+
 174+
 175+logfile("Content (".strlen($content)." Zeichen) vorbereitet, verbinde zum Speichern!");
 176+
 177+//######## POST-Content vorbereitet, verbinden & POST-header senden #########
 178+
 179+//zum speichern verbinden
 180+$fpc = fsockopen ($project, 80, $errno, $errstr, 30);
 181+//Speichern per Post.. ***************
 182+
 183+$referer = "http://$project/w/index.php?title=".urlencode($page)."&action=edit";
 184+
 185+fputs($fpc, "POST /w/index.php?title=".urlencode($page)."&action=submit HTTP/1.1\n");
 186+fputs($fpc, "Host: $project\n");
 187+fputs($fpc, "User-Agent: $useragent\n");
 188+fputs($fpc, "Accept: $accept\n");
 189+fputs($fpc, "Accept-Language: de\n");
 190+//fputs($fpc, "Accept-Encoding: gzip,deflate\n"); //gzip --> seite komprimiert!
 191+fputs($fpc, "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n");
 192+fputs($fpc, "Keep-Alive: 300\n");
 193+fputs($fpc, "Connection: keep-alive\n");
 194+fputs($fpc, "Referer: $referer\n");
 195+fputs($fpc, "Cookie: ".$cookie."\n");
 196+fputs($fpc, "Content-Type: application/x-www-form-urlencoded\n");
 197+fputs($fpc, "Content-Length: ".strlen($content)."\n");
 198+fputs($fpc, "\n");
 199+fputs($fpc, $content);
 200+logfile("Header gesendet.");
 201+
 202+//Response Header auslesen vorallem cooke********************
 203+$xxx = 0;
 204+do {
 205+$linex=fgets($fpc,255);
 206+if($xxx == 0)
 207+{
 208+ $linexx = $linex;
 209+}
 210+$xxx += 1;
 211+
 212+$headerrx.=$linex;
 213+
 214+//auf cookie prüfen
 215+if(substr($linex,0,11) == "Set-Cookie:")
 216+{
 217+$rawcookie = substr($line,11,strpos($line,";")-11); //Format: session=DFJ3ASD2S
 218+ $cookiename = trim(substr($rawcookie,0,strpos($rawcookie,"=")));
 219+$cookies[$cookiename] = $rawcookie;
 220+}
 221+
 222+} while (trim($linex)!="");
 223+
 224+
 225+
 226+
 227+if(strstr($linexx,"Moved Temporarily"))
 228+{
 229+logfile("Bearbeitung Erfolgreich.");
 230+return true;
 231+}
 232+else
 233+{
 234+logfile("BEARBEITUNG FEHLGESCHLAGEN!.\nFehler-Header: $line");
 235+return false;
 236+}
 237+
 238+
 239+
 240+
 241+/*
 242+while (!feof($fpc)) {
 243+$linew=fgets($fpc,255);
 244+$bodyw.=$linew;
 245+}
 246+logfile("-------\n".$bodyw."----------\n"); */
 247+fclose($fpc);
 248+
 249+echo"ende.";
 250+}
 251+else
 252+{
 253+logfile("ANMELDUNG FEHLGESCHLAGEN, KONNTE NICHT ANMELDEN!\n");
 254+die();
 255+}
 256+
 257+}
 258+
 259+function wikilogin($username,$password,$project,$useragent)
 260+{
 261+ global $cookies;
 262+
 263+ $getrequest = (substr($project,-1) == "/") ? "w/api.php?action=login" : "/w/api.php?action=login";
 264+ $project = (substr($project,0,7) == "http://") ? $project : "http://".$project;
 265+
 266+ logfile("Login via API to $project as $username...");
 267+
 268+ $postlogin = "lgname=".urlencode($username)."&lgpassword=".urlencode($password)."&format=php";
 269+
 270+ if(!$useragent) { $useragent = "Luxo (Toolserver; php) luxo@ts.wikimedia.org"; }
 271+ $ch = curl_init($project.$getrequest);
 272+ curl_setopt($ch, CURLOPT_POST, TRUE);
 273+ curl_setopt($ch, CURLOPT_POSTFIELDS, $postlogin);
 274+ curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
 275+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 276+ curl_setopt($ch, CURLOPT_COOKIEJAR, "/home/luxo/cks");
 277+
 278+ $rx = curl_exec($ch);
 279+
 280+ $data = unserialize($rx);
 281+
 282+ curl_close($ch);
 283+
 284+ if($data['login']['result'] == "NeedToken")
 285+ {
 286+ $postlogin = "lgname=".urlencode($username)."&lgpassword=".urlencode($password)."&lgtoken=".urlencode($data['login']['token'])."&format=php";
 287+ $ch = curl_init($project.$getrequest);
 288+ curl_setopt($ch, CURLOPT_POST, TRUE);
 289+ curl_setopt($ch, CURLOPT_POSTFIELDS, $postlogin);
 290+ curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
 291+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 292+ curl_setopt($ch, CURLOPT_COOKIEFILE, "/home/luxo/cks");
 293+ curl_setopt($ch, CURLOPT_COOKIEJAR, "/home/luxo/cks");
 294+ $ry = curl_exec($ch);
 295+ $data = unserialize($ry);
 296+
 297+ }
 298+
 299+ if($data['login']['result'] == "Success")
 300+ {
 301+ logfile("Login erfolgreich");
 302+
 303+ //Cookie aufbauen
 304+ $cookies = array($data['login']['cookieprefix']."_session" => $data['login']['cookieprefix']."_session=".$data['login']['sessionid'],
 305+ $data['login']['cookieprefix']."UserID" => $data['login']['cookieprefix']."UserID=".$data['login']['lguserid'], // [commonswikiUserID] => commonswikiUserID=205395
 306+ $data['login']['cookieprefix']."UserName" => $data['login']['cookieprefix']."UserName=".$data['login']['lgusername'],
 307+ $data['login']['cookieprefix']."Token" => $data['login']['cookieprefix']."Token=".$data['login']['lgtoken']);
 308+ } else {
 309+ die("Login nicht erfolgreich! (".$data['login']['result'].")");
 310+ }
 311+
 312+ curl_close($ch);
 313+ return $cookies;
 314+}
 315+
 316+
 317+
 318+?>
Property changes on: trunk/tools/rotatebot/login.php
___________________________________________________________________
Added: svn:eol-style
1319 + native

Comments

#Comment by Nikerabbit (talk | contribs)   22:47, 14 December 2011

This somehow reminds me of OpenOffice.

Status & tagging log