Categories
Allgemein MacOS Programmierung

MacOS Photos and AppleScript

Just about to move from Adobe Lightroom (CC) to native Apple Photo App/iCloud (but thats another story).

Unfortunately most of the old AVI videos got a wrong date during the import (not the file-creation date but the date of import). Not helpful. Fortunately Lightroom had set the date/time into the filename, so I should be able to set it from there.

In the end I spent my first night with with AppleScript – thats the outcome:

tell application "Photos"
  activate
  set imageSel to (get selection)
  if imageSel is {} then
    error "Please select some images."
  else
    repeat with im in imageSel
      tell im
        set imageFilename to filename of im as string
        set d to current date

        -- filename format: 20030316_160816_03498.avi
        set the year of d to text 1 thru 4 of imageFilename
        set the month of d to text 5 thru 6 of imageFilename
        set the day of d to text 7 thru 8 of imageFilename
        set the hours of d to text 10 thru 11 of imageFilename
        set the minutes of d to text 12 thru 13 of imageFilename
        set the seconds of d to text 14 thru 15 of imageFilename

        set the date of im to d
      end tell
    end repeat
  end if
end tell
return input
Categories
Programmierung Software

My GitHub Profile

Mein GitHub Profil: https://github.com/otto802/.

Reichlich spät, aber besser spät als nie ;-).

Categories
Linux Programmierung Trivial

PHP: error_reporting setting in apache config

Schöner Denkfehler.

In der php.ini setzt man die error_reporting Stufen mittels Bitverknüpfung über Konstanten (Liste):

php_admin_value error_reporting E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED

Um für einen bestimmten vhost im Apache abweichende Werte zu setzen, gibt es die Settings “php_admin_value” und “php_admin_flag”. Kommt man jedoch (wie ich) auf die Idee es wie in der php.ini üblich einzutragen, erhält man nicht das gewünschte Ergebnis. Grund ist, dass PHP an dieser Stelle die Konstanten nicht auswerten kann.

# falsch
php_admin_value error_reporting E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED

#richtig
php_admin_value error_reporting 22519
Categories
Programmierung

Google Maps: direction of a polyline

JavaScript-Schnipsel um mit Google Maps API die Himmelsrichtung einer Linie aus einem Polygon zu bestimmen, lässt sich auch noch einfach erweitern um auch noch die Nord/Süd Richtung zu bekommen (“lat()”) – ich brauchte aber nur West/Ost ;) :

var p1 = polyline.getVertex(0);
var p2 = polyline.getVertex(1);
var direction = false;

if (p1.lng() < p2.lng()) {
    direction = "east";
} else if (p1.lng() > p2.lng()) {
    direction = "west";
}
Categories
Linux Programmierung

PHP/bash: Konsolenausgabe positionieren

Kürzlich benötigte ich für eine PHP Konsolenanwendung die Ausgabe einer Statuszeile. Die ausgegebene Zeile sollte jedoch nicht (wie sonst üblich) jeweils in einer neuen Zeile landen, sondern immer in der selben Zeile – so dass man einen schnellen Überblick über den Scriptstatus bekommt. Wie auch immer – ich habe mich dann etwas durch die Terminal ANSI Escape Sequenzen gekämpft und das ganze mit meinem PHP Script kombiniert. Folgend die entsprechende Funktion für die Ausgabe:

function echoFixedLine($string) {
     echo "\033[K" . $string . "\033[" . strlen ($string) . "D";
}

echo "TEST:";

for ($i=0; $i<=100; $i++) {
    echoFixedLine("Number: " . $i);
    sleep(1);
}

// Ausgabe nach ca. 101 Sekunden:
TEST:
Number: 100

Die Funktion löscht immer zunächst die ganze Zeile, schreibt dann den gewünschten String und positioniert anschließend den Cursor wieder an den Anfang für die eventuelle nächste Zeile. Denkbar wären damit z.B. auch "grafische" Fortschrittsanzeigen...

Hier ein paar weiter Informationen zu den Escape-Sequenzen - eine komplette Referenz haben ich leider noch nicht gefunden.

Categories
Programmierung

PHP: IP ranges überprüfen

Quick and dirty PHP-Script zum überprüfen ob eine IP-Adresse in einem angegebenen IP-Range ist.


$ranges = array(
    "10.10.10.2-4",
    "192.168.0-255.0-255",
    "10.20.0.1",
    );

if (inIpRange("10.10.10.3", $ranges)) {
    echo "bingo!";
}

function inIpRange($needle, $haystack) {

    if (!is_array($haystack)) {
        $haystack = array($haystack);
    }

    foreach ($haystack as $ip) {

        $d = explode('.', $ip);
        $r = explode('.', $needle);

        foreach ($d as $key => $num) {

            if (strpos($num, '-') !== false) {
                $range = explode('-', $num);

                if ($r[$key] < $range[0] || $r[$key] > $range[1]) {
                    continue 2;
                }
            } elseif ($num != $r[$key]) {
                continue 2;
            }
        }

        return true;
    }

    return false;
}
Categories
Linux Programmierung

Netbeans: Scanning for external changes

Vor einiger Zeit bin ich von PHPEd auf Netbeans PHP umgestiegen. Mir gefällt z.B. das Projekthandling, die eingebaute Versionierungsanbindung und speziell die Plattformunabhängigkeit. PHPEd ist zwar klasse unter Windows aber da ich meist unter Linux unterwegs bin und die Wine-Unterstützung für PHPEd nicht so gut ist (Geschwindigkeit) bin ich letztendlich zu Netbeans gewechselt. Dies nur am Rande.

Netbeans nervt aber ab und an mit seiner ewigen Scannerrei nach Änderungen im Code. Mitunter wechselt man den Fokus und Netbeans scannt (auch den Server) nach Änderungen (“Scanning for external Changes”).

Unter folgendem Link ist ein Plugin beschrieben mit welchem man das Verhalten normalisiert: ScanOnDemand.

Categories
Programmierung

Debug-Modus per Cookie

Jeder Entwickler baut sich wohl seinen eigenen Debug-Modus für seine Anwendungen. Bisher habe ich bei Webanwendungen meist GET Parameter verarbeitet. Mit den prinzipbedingten Nachteilen – z.B. Tracking über mehrere Seiten. Andere Variante ist per Config-Variable den Debugmodus einzuschalten. Oder abhängig von der Source-IP. Oder wie auch immer.

Eine andere Methode habe ich mir von Google abgeschaut: Setzen von Spezialmodi per Cookie über die Adressleiste des Browsers. Google hat schon des öfteren neue Funktionen zunächst nur für einen “eingeweihten” Nutzerkreis zugänglich gemacht. Eingeschaltet wurde die Funktion dann über ein spezielles Cookie. Gesetzt wurde dieses einfach über die Adressleiste des Browsers. So hat z.B. die folgende Eingabe in der Adressleiste auf google.com das “suggest” Feature eingeschaltet:

javascript:document.cookie= "PREF=ID=175eb54605c0202d:U=a14f58424228a2a5:LD=en:
NR=10:CR=2:TM=1240146048:LM=1242596928:DV=AA:GM=1:IG=1:S=zW53HscJwnEL89bQ;
path=/;domain=.google.com";void(0);

Mittlerweile verwende ich auch immer öfter dieses Verfahren:

javascript:document.cookie="xyz_debug=1";window.location.reload();

Das so gesetzte Cookie mit dem Namen “xyz_debug” kann man dann einfach mit bekannten Funktionen serverseitig auswerten (hier PHP):

if ($_COOKIE["xyz_debug"]) {
    var_dump($_POST);
}

Natürlich sollte das verwendete Cookie nicht leicht zu erraten sein. Ich wüste gerne wie viele Debugausgaben in den weiten des Internets darauf warten über versteckte Zugänge, Parameter etc. abgerufen zu werden ;)

Categories
Programmierung

PHP: strpos mit Integern

Wieder 2 Stunden bei der Fehlersuche verplempert…

$string = "X20";
echo (strpos("XYX20", $string) !== false) ? "JA" : "NEIN";

$string = 20;
echo (strpos("XYX20", $string) !== false) ? "JA" : "NEIN";

Output:

JA
NEIN

Erwartet hätte ich 2x “JA”. Leider habe ich nicht in die Doku zu strpos geschaut – hätte mir einiges an Zeit für die Fehlersuche erspart. Es ist aber immer so: Die Funktion strpos habe ich schon 1000 Mal verwendet und den Fehler definitiv nicht dort vermutet.

So geht’s:

$string = 20;
echo (strpos("XYX20", (string)$string) !== false) ? "JA" : "NEIN";

Merke: gerade die viel gelobte/gehasste vermeintlich dynamische Typumwandlung von PHP stellt einem oft ein Bein.

Categories
Networking Programmierung

DNS: Wildcard Records

Eine Sache die mir beim DNS gar nicht so bewusst war: Wildcard Records. Bei Webanwendungen arbeite ich gerne mit einem Default-Hosting und lasse die Anwendung bestimmen was bei welchem Hostnamen passiert (über den HTTP1.1 Header). In letzter Konsequenz fehlte mir eigentlich nur noch, dass ich die Hostnamen nicht mehr in die DNS-Zone eintragen muss.

Logische Folgerung (Auszug auf dem Bind-Zonenfile):

*.sub.bergercity.de.     IN A    88.151.66.11