'.$text."
\n"; print "Dieser Fehler wäre nicht aufgetreten, hätten sie das Formular benutzt.
"; exit; } // das große Fehlerarray. $errors = array(); // das nicht-tödliche Warnungsarray $warnings = array(); // mit allen Fehlern beenden function exit_errors() { global $ajax,$errors,$warnings; print "'.$error."
\n"; } foreach($errors as $error) { print ''.$error."
\n"; } if($ajax) { print "Gehen sie zurück zum Formular und korrigieren sie ihre Fehleingaben. Klicken sie dann nochmals auf Generieren.
"; print ''; } exit; } // Schritt 1: Eingaben entgegennehmen und validieren // 1/6: Punch-Daten $input_source = get('data-src'); switch($input_source) { case 'file': // Dateiupload. Tja. Datei direkt dem Programm übergeben. Vorher // Größe checken. Also mal los: if($ajax) { // wenn Ajax benutzt wird, wird die Datei noch nicht hochgeladen. break; // also erst anschließend machbar. } if(!isset($_FILES['data-file'])) { $errors[] = "Keine Datei hochgeladen, obwohl Dateiupload als Datenquelle ausgewählt war!"; } elseif($_FILES['data-file']['size'] > 500*1024) { $errors[] = "Die hochgeladene Datei ist größer als ein 500kb. Derart große Lochstreifen sind aus Perfomancegründen nicht erlaubt. Laden sie sich das Visualisierungsprogramm runter und erstellen sie lokal ihre Mammutlochstreifen."; } elseif($_FILES['data-file']['size'] == 0) { $warnings[] = "Die hochgeladene Datei ist leer (0 Bytes Inhalt). Das gibt keinen sonderlich spannenden Lochstreifen..."; } $original_filename = $_FILES['data-file']['name']; // fuer den Report weiter unten $input_filename = $_FILES['data-file']['tmp_name']; // usw. break; case 'input': // Daten direkt eingetippt. Na dann... $text = get('data-input'); $form = get('data-form'); $input_binary = 'abc'; $parts = preg_split("/\s+|\n+/", $text); foreach($parts as $x => $byte) { if(!strlen($byte)) continue; // nur whitespace, Abfall durch das preg_split. // Alle Formen zu dezimal umwandeln. if($form == 'bin') $byte = bindec($byte); elseif($form == 'hex') $byte = hexdec($byte); elseif($form == 'oct') $byte = octdec($byte); elseif($form == 'hex0') $byte = hexdec(substr($byte,2)); // 0x wegschneiden. elseif($form != 'dec') { $errors[] = "Fehler: Ungültige Datenform $form!"; break; } if(!is_numeric($byte)) { $errors[] = "Fehler: Byte $x mit dem Wert $byte ist keine entsprechende Zahl des Types $form. Vielleicht haben sie nicht das passende Format eingestellt, in dem sie ihre Daten eingegeben haben?"; break; } $input_binary .= chr($byte); // <- the PHP way | the Perl way -> pack('C', $byte); } // foreach if(strlen($input_binary) > 1024*1024) { $errors[] = 'Sie haben über eine Millionen Bytes eingetippt! Derart große Lochstreifen sind aus Perfomancegründen nicht erlaubt. Laden sie sich das Visualisieurngsprogramm runter und erstellen sie ihren Monsterstreifen lokal.'; break; } elseif(strlen($input_binary) == 0) { $errors[] = 'Sie haben keine Daten eingegeben, obwohl direkte Byteeingabe als Datenquelle ausgewählt wurde!'; break; } // so, jetzt liegts als $input_binary vor. break; case 'font': // Text, der gepuncht werden soll $text = get('data-text'); if(!preg_match('/^[a-zA-Z0-9 ]+$/', $text)) { $warnings[] = 'Im Text befinden sich nichtdruckbare Zeichen. Nur Buchstaben und Zahlen können dargestellt werden, keine anderen Zeichen.'; } if(strlen($text) == 0) { $errors[] = 'Sie haben keinen Text eingegeben, obwohl Textgenerierung als Datenquelle ausgewählt wurde!'; } if(strlen($text) > 1000) { $errors[] = 'Der Text ist mit über 1000 Zeichen eindeutig zu lang. Aus Perfomancegründen ist das nicht erlaubt. Laden sie sich die entsprechenden Programme runter und erstellen sie ihren Streifen lokal.'; } // irgendwas mit dem Text machen. // und als $input_binary fertig machen. $input_binary = 'abc'; break; default: $errors[] = "Ungültige Datenquelle! Es konnten keine Daten entgegengenommen werden!"; } // 2/6: Formatfragen. $format = strtolower(get('format')); if($format != 'png' && $format != 'svg') { $errors[] = "Ungültiges Ausgabeformat $format! Erlaubt sind nur PNG und SVG!"; } // 3/6: Dimensionen $dsrc = get('dimension-src'); if($dsrc == 'width' || $dsrc == 'height' || $dsrc == 'diameter') { $size = get("dimension-$dsrc"); if(!my_ctype_digit($size)) { $errors[] = "Die Größenangabe zu den Dimensionen, die der Lochstreifen annehmen soll, ist fehlerhaft: $size ist keine positive ganze Dezimazahl!"; } elseif($dsrc == 'diameter' && $size > 100) { $errors[] = "Der Durchmesser eines Loches ist mit 100 pxieln zu groß, ein so großes Bild darf aus Perfomancegründen nicht generiert werden. Bitte kleineren Wert einstellen."; } elseif($size > 1000*100) { $errors[] = "Die Größenangabe von über 100.000 Pixel ist viel zu groß. Bitte kleineren Wert einstellen."; } // alles klar. $size und $dsrc } else $errors[] = "Es wurde keine Größenangabe zum Lochstreifen gemacht!"; // 4/6: Ausrichtung des Lochstreifens $alignment = get('alignment'); if(preg_match('/^(hor)-(rtl|ltr)-([ou])$|^(ver)-(btt|ttb)-([lr])$/', $alignment, $m)) { // so, jetzt mal zusammenpuzzeln... } else $errors[] = "Ungültige Ausrichtung des Lochstreifens: $alignment war nicht in der Auswahl!"; // 5/6: Den ganzen komponentenweiten Kram $comp = array('imagebg', 'tapebg', 'punched', 'notpunched', 'feedholes'); $comp_visibility = array(); $comp_color = array(); $comp_translation = array('Bildhintergrund', 'Lochstreifen', 'Löcher', 'Nicht-Löcher', 'Führungslöcher'); foreach($comp as $x => $component) { $comp_visibility[$x] = get("show-$component") ? 1 : 0; $color = substr(get("color-$component"), 1); // das "#" wegstrippen $lucency = get("lucency-$component"); if(!preg_match('/^[0-9a-fA-F]{6}$/', $color)) { $errors[] = "Die Farbangabe $color für den Komponenten $component ist keine korrekte Hexadezimalfarbangabe."; continue; } elseif(!preg_match('/^[0-9a-fA-F]{2}$/', $lucency)) { $errors[] = "Die Transparenzangabe $lucency für den Komponenten $component ist nicht korrekt."; continue; } $comp_color[$x] = "#${color}${lucency}"; } // 6/6: Empty-start, Empty-End $empty_start = get('empty-start'); $empty_end = get('empty-end'); if(!my_ctype_digit($empty_start)) $errors[] = "Die Anzahl leerer Startbytes ist keine positive ganze Zahl ($empty_start)"; if(!my_ctype_digit($empty_end)) $errors[] = "Die Anzahl leerer Endbytes ist keine positive ganze Zahl ($empty_end)"; // fertig. // Fehler ausgeben und beenden. if(!empty($errors)) { exit_errors(); } // keine Fehler aufgetreten und in Ajax-Mode: "ok" zurückgeben if($ajax) { echo "ok"; exit; } // Wenn wir hier sind, gehts schon mal weiter. echo 'Es sind Probleme aufgetaucht, die allerdings nicht wirklich schlimm sind, der Lochstreifen wurde trotzdem generiert:
'; foreach($warnings as $error) { print ''.$error."
\n"; } } // so, Parameter zusammenfummeln. $exec_params = ''; // 2/6: Format: $exec_params .= "-f$format "; // 6/6 Empty Bytes: if($empty_start) $exec_params .= "--empty-start=$empty_start "; if($empty_end) $exec_params .= "--empty-end=$empty_end "; // 5/6 Komponenten foreach($comp as $x => $component) { if($comp_visibility[$x]) { $exec_params .= "--color-$component=".$comp_color[$x].' '; } else { $exec_params .= "--hide-$component "; } } // 3/6 Dimensionen $exec_params .= "--$dsrc=$size"; // 4/6 Transformations and Rotations $exec_params .= $transformation_string.' '; // Output Filename erstellen $source_range = array_merge(range('a','z'), range('0', '9')); $output_hash = ''; foreach(array_rand($source_range, 10) as $x) { $output_hash .= $source_range[$x]; } /* //alternativ sowas wie: $tmpx = mt_rand(0,32); // tempoaer fuer nen kurzen hash if($tmpx-32 < 10) $tmpx *= -1; $output_hash = substr(md5(rand() * time()), $tmpx, $tmpx+10);*/ $image_filename = $output_dir.'/'.$output_hash.'.'.$format; $exec_params .= "--output=$image_filename"; // 1/6 Input Data if($input_source == 'file') { $exec_params .= " '".$input_filename."'"; } else { // Binäre Daten liegen als $input_binary vor und wollen // per STDIN eingefüttert werden. } print "Der Lochstreifen wird nun generiert...\n"; flush(); // damit er das wenigstens sieht... if($verbose) { print "
Alles zusammengepanscht ergibt:
"; print "$draw_program $exec_params"; print "Rufe auf...\n";
}
// in PHP brauchts nen mörderischen Aufwand, um jetzt dieses
// Programm anzuschmeißen:
$proc_ressource = proc_open("time $draw_program ".($verbose?'--verbose ':' ').$exec_params, array(
// descriptor array (0=stdin, 1=stdout, 2=stderr, like sh)
0 => array('pipe', 'r'), // Programm wird von STDIN lesen
1 => array('pipe', 'w'), // und zu STDOUT schreiben
2 => array('pipe', 'w'), // und zu STDERR auch schreiben
), $pipes, NULL , NULL );
if(is_resource($proc_ressource)) {
if($input_source != 'file') {
// Daten reinschreiben
fwrite($pipes[0], $input_binary);
}
fclose($pipes[0]); // nichts mehr zu schreiben
// STDOUT/STDERR lesen
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]); // fuer Speicherung der Fehler: Generator wurde nicht ordnungsgemäß ausgeführt, das
Programm beendete mit Statuscode $return_value. Folgende Ausgaben wurden zwecks Fehlersuche abgefangen: Aufruf: $draw_program $exec_params";
}
print " Gewünschtes Bild konnte nicht erstellt werden! Konnte Generatorprozess nicht starten! Der folgende Lochstreifen wurde am ".date('m.d.Y')." um ".date('H:i:s')." Uhr von dem
Besucher mit der IP-Adresse $_SERVER[REMOTE_ADDR] generiert. Die erstellte Datei vom
Typ ".strtoupper($format)." ist $filesize groß";
if($format == 'png') {
$imagesize = GetImageSize($image_filename);
$report .= ", sie hat die Ausmaße von $imagesize[0] x $imagesize[1] Pixel. Das Bild wurde gespeichert unter der Adresse $image_url
und kann z.B. zur Weiterverwendung runtergeladen werden. Es sieht so aus:";
print "STDOUT:\n";
echo $stdout;
print "\nSTDERR:\n";
echo $stderr;
print "
";
print "\nReturn Value $return_value\n";
}
// checken ob was gemacht wurde.
if(!is_file($image_filename)) {
print "
Das Bild wurde unter der Adresse $image_url gespeichert. Mit einem modernen Browser (Nicht Internet Explorer) können sie sich die SVG-Datei durch Anklicken des Linkes anschauen. Laden sie sich (ansonten) die Datei runter und öffnen sie es mit einem Vektorgrafikprogramm, z.B. mit dem frei erhältlichen Inkscape.
"; } // Discmailer ;-) $report .= "Bitte beachten sie: Die Verfügbarkeit des Bildes auf diesem Server gehört nicht in den \"Dienstleistungsumfang\" des Generierungsprogramms. Das heißt, dass sie durch Eingeben ihrer Daten zugestimmt haben, dass diese mit dem Bild nach freiem Ermessen des Administrators gespeichert werden und willkürlich gelöscht werden können. Es besteht kein Anspruch auf selbst zeitlich begrenztes Hosting! Wenn sie das Bild im Internet verfügbar machen wollen, können sie es z.B. auf kostenlosen Bilderhostern hochladen. Suchen sie dazu mit der Suchmaschine ihres Vertrauens nach so etwas wie z.B. \"image hosting\"
"; $report .= "Die Daten, die dem generierten Lochstreifen zugrundeliegen, wurden vom Benutzer $report_input_source[$input_source]. Im folgenden wird ein Hexdump der ".strlen($input_binary)." Bytes angegeben, mit denen letztendlich der Lochstreifen generiert wurde. Mit geeigneten Hilfmitteln (z.B. einem Hexeditor) können sie aus den Daten eine Binärdatei erstellen."; $report .= "
"; for($x=0; $x$c) { $report .= " $comp_translation[$x] ($c): ". ($comp_visibility[$x] ? "sichtbar, und zwar mit der Farbe $comp_color[$x] (Format #RRGGBBAA)" : "nicht sichtbar (deaktiviert)"); } $report .= ""; $report .= " Außerdem wurden $empty_start leere Startbytes und $empty_end leere Endbytes eingestellt. Die eingestellte Rotation des Lochstreifens wird durch das folgende Bild verdeutlicht:
Die Größe des Lochstreifens wurde von der Dimension $dsrc abhängig gemacht und auf $size eingestellt.
"; $report .= "Generierung
"; $report .= "Mit dem Kommandozeilentool führ(t)en folgende Parameter zu der Generierung eines derart gewünschten Lochstreifens:
"; $report .= ""; // debugging... $report .= "
$exec_params
Durch Eingabe dieser Parameter mit den oben angezeigten Eingabedaten müsste jederzeit das gleiche Bild reproduzierbar sein.Das Generieren des Lochstreifens nahm die folgende Zeit in Anspruch:
$stderrDabei steht real für die wirklich vergangene Zeit, die der Benutzer warten musste, bevor er seinen Lochstreifen bekam, user für die tatsächliche Zeit, die das Programm aktiv war (Abweichungen zu real können dadurch begründet sein, dass der Server noch andere Sachen gleichzeit machte) und system für die Zeit, in der der Server wirklich ernsthaft über den Lochstreifen nachgedacht hat ;-)
"; //// REPORT zuende. Jetzt erst mal ausdrucken. if(!$verbose) echo "fertig\n"; // als Antwort auf die "wird nun generiert..."-Ausgaben weit oben. echo "Mit dem generierten Bild wurde eine Urkunde erstellt, in der alle Parameter, Daten und sonstige interessante Dinge festgehalten sind. Es folgt nur dessen Inhalt:
"; echo ""; // ;) echo $report; echo ""; echo "Diese \"Urkunde\" wurde mit dem Bild zusammen gespeichert. Sie ist unter einer ähnlichen Adresse wie das Bild erreichbar, und zwar unter $report_url.
"; echo "Möchten sie noch etwas stanzen? Erneut zum Stanzereingabeformular
"; // und jetzt abspeichern! $fh = fopen($report_file, 'w'); if(!$fh) { print 'Fehler: Konnte Report-File '.$report_file.' nicht zum Schreiben öffnen!
'; exit; // weil gibts ja nichts mehr zu tun. } fwrite($fh, makeHeader("Lochstreifen $output_hash -- Erstellungsbericht")); fwrite($fh, "Lochstreifen $output_hash
"); fwrite($fh, $report); fwrite($fh, "