Benutzer:Summer ... hier!/wiki-upload.cli.php
Erscheinungsbild
#!/usr/bin/php -f
<?php
// Wichtigste Quelle:
// https://www.mediawiki.org/wiki/User:Bcoughlan/Login_with_curl
// über
// https://www.mediawiki.org/wiki/API:Login
// Achtung: hier drunter kommt ein nowdoc, kein heredoc!
// Nowdoc's werden nicht geparst (setzen aber Ver. 5.3 voraus)
// Das nowdoc entspricht dem Text einer Konfig-Datei in die u.a.
// username und password eingetragen werden muss ...
// Siehe nach dem ersten Programmdurchlaus ~/.<Name-dieses-Programms>.config
$default_config =<<<'DEFAULT_CONFIG_NOWDOC'
<?php
$settings['wikiroot'] = "http://de.wikipedia.org";
$settings['user'] = "mein Wikiaccount";
$settings['pass'] = "mein Wikipassword";
$settings['cookiefile'] = "cookies.tmp";
$settings['curl_verbose_file'] = sys_get_temp_dir() . '/' . $settings['my_filename'];
$settings['upload_file_text'] =<<<UPLOAD_FILE_TEXT
{{Information
|Description ={{de|Beschreibung folgt}}
|Source ={{own}}
|Author = ~~~~
|Date = 2014-
|Permission =
|other_versions = {{de|Mit PHP-Script (curl) hochgeladen}}
}}
{{Information
|Beschreibung = Beschreibung folgt
|Quelle = selbst fotografiert
|Urheber = ~~~~
|Datum = 2014
|Genehmigung =
|Andere Versionen =
|Anmerkungen = Mit PHP-Script (curl) hochgeladen}
}}
== {{int:license-header}} ==
{{Bild-CC-by-sa/3.0}}
{{self|cc-by-sa-3.0}}
UPLOAD_FILE_TEXT;
?>
DEFAULT_CONFIG_NOWDOC;
function check_uploadfile()
{
// Die hochzuladende Datei prüfen (hier wird z.Zt. nur auf
// die Existenz gefprüft)
// Das Array $settings global benutzen.
global $settings;
// Der Name der Upload-Datei ist der erste Programmparameter
$settings['upload_file_name'] = $GLOBALS['argv'][1];
if (!file_exists($settings['upload_file_name']))
{
throw new Exception("upolaodfile don't exist - check the first parameter of this porgramm");
}
}
function read_configfile()
{
// Das Array $settings global benutzen.
global $settings;
// Name dieses Programms ohne Pfadangabe der Variablen
// $settings;['base___FILE__'] zuweisen.
$settings['my_filename'] = basename( __FILE__ );
// Anmerkung: da diese Var. zur Benennung der Konfig-Dateien benutzt
// wird, wirken sich Namensänderungen dieses Programms auch automatisch
// auf die Namen der Konfig-Dateien aus.
// Home Verz. ermitteln (kann in $_SERVER und mal in $_ENV stehen)
if (isset($_SERVER['HOME'])) {$settings['my_HOME'] = $_SERVER['HOME'];};
if (isset( $_ENV['HOME'])) {$settings['my_HOME'] = $_ENV['HOME'];};
if (empty($settings['my_HOME']))
{
throw new Exception("Error getting enviroment var. HOME \n");
}
// den Dateinamen für die Konfig-Datei im Home-Verz. festlegen.
$settings['home_configfilename'] = "${settings['my_HOME']}/.${settings['my_filename']}.config";
// Falls die Konfig-Datei im Home-Verz. nicht existiert ...
if (!file_exists($settings['home_configfilename']))
{
// Anlegen der Datei ...
file_put_contents($settings['home_configfilename'], $GLOBALS['default_config']);
if (file_exists($settings['home_configfilename']))
{
throw new Exception("${settings['home_configfilename']} created - pleas edit the file");
}
// ... und falls sie nicht angelegt werden konnte:
else
{
throw new Exception("can't create configfile ${settings['home_configfilename']}");
}
}
# Nun Inlcuden wir die Konfig-Datei
require($settings['home_configfilename']);
# Testen ob der include funktioniert hat:
if (empty($settings['wikiroot']))
{
throw new Exception("${settings['home_configfilename']} not includet");
}
# Falls direkt neben der Programmdatei auch eine Konfig-Datei liegt
# wird diese ebenfalls eingelesen.
if (file_exists(__FILE__ . ".config"))
{
require(__FILE__ . ".config");
}
}
function httpRequest($url, $post="")
{
// Ueber diese Funktion findet die Kommunikation zum WIKI-Server statt.
// Die oben definieten Variablen hier nutzen
global $settings;
$ch = curl_init();
// Allgemeine Werte für die Kommunikation festlegen.
curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9');
curl_setopt ($ch, CURLOPT_URL, ($url));
curl_setopt ($ch, CURLOPT_ENCODING, "UTF-8" );
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_COOKIEFILE, $settings['cookiefile']);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $settings['cookiefile']);
// Hier kommen die Post-Daten hinzu
if (!empty($post)) curl_setopt($ch,CURLOPT_POSTFIELDS,$post);
// Geschwätziges Protokoll in $settings['curl_verbose_file'] ausgeben.
// Achtung: auf Rechnern mit mehreren Benutzern koennen diese die
// Protokolldaten u.u. einsehen (nebst Passwörter etc.).
if (!@isset($settings['curl_log']))
{
// Keine Ahnung warum, aber mit "fopen(handle,'w')" schreibt curl
// nicht alle Daten ins Logfile ... Option 'a' in Kombination mit
// "seek()" ist ein Workarount.
// Wer bedenken hat, dass die Daten von einem Mitbenutzer des
// Rechners missbraucht werden solle $curl_verbose_file auf "dev/null"
// seten.
$settings['curl_log'] = fopen($settings['curl_verbose_file'], 'a');
fseek ($settings['curl_log'] , 0);
};
fwrite($settings['curl_log'], "#-POST-#" . print_r($post, true) . "#-POST-#\n");
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $settings['curl_log']);
// curl Anfrage absetzen
$xml = curl_exec($ch);
if (!$xml)
{
throw new Exception("Error getting data from server ($url): " . curl_error($ch));
}
curl_close($ch);
// Ausgabe der Antworten des Wiki-Server
// (bischen hart ... aber man kanns ja rauswerfen ...)
echo "Response of http:Request (Begin)\n";
$dom = new DOMDocument();
$dom->loadXML($xml);
$dom->preserveWhiteSpace = FALSE;
$dom->formatOutput = TRUE;
$x=$dom->saveXML();
// echo htmlspecialchars($x);
echo $x;
echo "(End)\n";
// Rueckgabe
return $xml;
}
function login ($user, $pass, $token='')
// Diese Funktion hat zwei Aufgaben: wird sie nur mit $user und $pass
// aufgerufen, so holt sie nur einen Token zum Login beim Wikiserver.
// Erst beim zweiten Aufruf dieser Funktion mit $token logt man sich
// beim Wikiserver ein.
// ACHTUNG: beim zweiten Aufruf enthält das Ergebnis einen lgtoken.
{
// ganz oben definiertes Array §settings hier nutzen
global $settings;
// an den Servernamen den Pfad dranhaengen
$url = $settings['wikiroot'] . "/w/api.php";
// Parameter fuer Aufruf zusammenbauen
$params = "action=login";
$params .= "&lgname=$user";
$params .= "&lgpassword=$pass";
$params .= "&format=xml";
// Falls dieser Funktion der Paramter $token übergeben wurde uebergeben
// wir ihn als Parameter (beim Aufruf des Wikiservers ohne Token erhalten
// wir einen solchen).
if (!empty($token))
{
$params .= "&lgtoken=$token";
}
// den Wikiserveraufruf absetzen
$xml_str = httpRequest($url, $params);
// Wenn der Aufruf absolut keine Antwort ergab geben wir eine Meldung raus.
if (empty($xml_str))
{
throw new Exception("No data received from server. Check that API is enabled.");
}
// Die XML-Antwort in ein Array umwandeln.
$xml_obj = simplexml_load_string($xml_str);
if (!empty($token))
{
//Check for successful login
$expr = "/api/login[@result='Success']";
$result = $xml_obj->xpath($expr);
if(!count($result))
{
throw new Exception("Login failed");
}
}
else
{
$expr = "/api/login[@token]";
$result = $xml_obj->xpath($expr);
if(!count($result))
{
throw new Exception("Login token not found in XML");
}
}
return $result[0]->attributes()->token;
}
function logout ()
{
// ganz oben definiertes Array §settings hier nutzen
global $settings;
// an den Servernamen den Pfad dranhaengen
$url = $settings['wikiroot'] . "/w/api.php";
// Parameter fuer Aufruf zusammenbauen
$params = "action=logout";
$params .= "&format=xml";
// Falls dieser Funktion der Paramter $token übergeben wurde uebergeben
// wir ihn als Parameter (beim Aufruf des Wikiservers ohne Token erhalten
// wir einen solchen).
// den Wikiserveraufruf absetzen
$xml_str = httpRequest($url, $params);
}
function get_edittoken()
{
/* Habe urspruenglich wie in https://www.mediawiki.org/wiki/API:Tokens
beschrieben mir einen edit-Token mit "action=token" etc. geholt.
Das funktinierte zwar, habe aber immer die Warnung "action=tokens
has been deprecated. Please use action=query&meta=tokens instead."
erhalten. Habe daher auf action/meta umgestellt. Bei der Serverantw.
heisst der Token nun auch "csrftoken" statt "token" (csrf steht fuer
"Cross-Site-Request-Forgery". */
// ganz oben definiertes Array §settings hier nutzen
global $settings;
// an den Servernamen den Pfad dranhaengen
$url = $settings['wikiroot'] . "/w/api.php";
// Parameter fuer Aufruf zusammenbauen
$params = "action=query";
$params .= "&meta=tokens";
//$params .= "&type=edit";
$params .= "&format=xml";
// den Wikiserveraufruf absetzen
$xml_str = httpRequest($url, $params);
// Wenn der Aufruf absolut keine Antwort ergab geben wir eine Meldung raus.
if (empty($xml_str))
{
throw new Exception("No data received from server. Check that API is enabled.");
}
// Die XML-Antwort in ein Array umwandeln.
$xml_obj = simplexml_load_string($xml_str);
// Ermitteln des Token
$expr = "/api/query/tokens[@csrftoken]";
$result = $xml_obj->xpath($expr);
if(!count($result))
{
throw new Exception("Login token not found in XML");
}
// Rueckgabe des Token
return $result[0]->attributes()->csrftoken;
}
function upload($token)
{
echo $token;
// ganz oben definiertes Array §settings hier nutzen
global $settings;
// an den Servernamen den Pfad dranhaengen
$url = $settings['wikiroot'] . "/w/api.php";
// Parameter fuer Aufruf zusammenbauen
$params = array('action' => "upload",
'comment' => "uploaded by script",
'text' => "${settings['upload_file_text']}",
'filename' => "Maus_auf_Kombizange_4.JPG",
'file' => "@${settings['upload_file_name']}",
'token' => "$token",
'format' => "xml");
// den Wikiserveraufruf absetzen
$xml_str = httpRequest($url, $params);
// Wenn der Aufruf absolut keine Antwort ergab geben wir eine Meldung raus.
if (empty($xml_str))
{
throw new Exception("No data received from server. Check that API is enabled.");
}
// Die XML-Antwort in ein Array umwandeln.
$xml_obj = simplexml_load_string($xml_str);
return ;
}
try
{
global $settings;
echo "########### call function check_uploadfile() - Uploadfile pruefen\n";
check_uploadfile();
echo "########### call function read_configfile() - Konfig-Datei(en) einlesen\n";
read_configfile();
echo "########### call function login() - Token holen\n";
$token = login($settings['user'], $settings['pass']);
echo "########### call funktion login() - jetzt wird eingelogt\n";
$null = login($settings['user'], $settings['pass'], $token);
echo "########### call function get_edittoken() - Token zum Editiren holen\n";
$edittoken = get_edittoken();
echo "value of the token: $edittoken \n";
echo "########### call function upload() - raus die Maus\n";
$null = upload($edittoken);
echo "########### call function logout() \n";
$null = logout();
}
catch (Exception $e)
{
fwrite(STDERR, "FAILED: " . $e->getMessage() . "\n");
if (@file_exists($settings['curl_verbose_file']))
{
fwrite(STDERR, "see also ${settings['curl_verbose_file']} \n");
};
die();
}
# Sterben ist bei CLI immer gut.
die();
?>
Nun sind wir tot und haben nicht einmal Tschüss gesagt ...