Archiv ‘Web’

Samstag, 21. Dezember 2024

Google Drive: Objekte suchen, welche mit einer bestimmten Person geteilt wurden

Google Drive verfügt über eine mächtige, aber den wenigsten Leuten bekannte Such-Syntax.

Anwendungsbeispiel: Kürzlich wollte ich alle Objekte, die ich mit einem bestimmten Benutzer geteilt habe, finden, und danach den Zugriff entfernen.

Nichts leichter als das:

sharedwith:user@gmail.com

Google Drive kennt viele andere Suchattribute: Search & find a file in Google Drive: Use advanced search

Tags: ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 15. Dezember 2024

Countdown Web-Seite leicht gemacht

Steht ein wichtiger Termin bevor, und will man die Vorfreude darauf mit jemandem teilen? Nichts leichter als das — dafür gibt es eine kostenlose (Web-)App:

countingdownto.com

Genial: Es ist nicht nur möglich ein Datum und eine Uhrzeit auszuwählen, sondern auch die Zeitzone festzulegen. Beispielsweise, wenn man für die Landung eines Flugs in Übersee einen Countdown erstellen möchte.

Gebookmarkt, und wird von mir ab sofort gelegentlich genutzt.

Tags: , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Montag, 5. Februar 2024

Pro Senectute: Web-Formular lässt keine HTML Spezialzeichen zu

Tags: ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 31. Januar 2024

Firefox nervt mit Übersetzungs-Pop-Up

Man öffne about.config und wechsle browser.translations.automaticallyPopup auf false, um dem Spuk ein Ende zu bereiten.

Tags: , ,
Labels: IT, Web

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 5. November 2023

CSS: Nummern in Einheitsbreite

Wow. Auch nach ca. 23 Jahren mit CSS rumwursteln kann man immer wieder neues lernen …

.numbers {font-variant: tabular-nums;}

Tags: , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Samstag, 11. Februar 2023

PHP Race Condition beim Schreiben einer Datei

Mit monit überwache ich die Grösse der Datei /var/log/php.log auf meinen Web-Servern und alarmiere mich, wenn die Datei die Grösse von 1 MB überschreitet. Das geht natürlich nur, wenn man mit logrotate sicherstellt, dass die Datei täglich rotiert wird. Und wenn man so (defensiv) in PHP programmiert, dass das Log nicht infos, notices, warnings und errors vollgepflastert wird. Um es noch schwieriger zu machen: Ich habe in php.ini error_reporting = E_ALL aktiviert, denn das motiviert Web-Entwickler (mich), ihren Code sauber zu halten.

Vor einigen Tagen machte ich mich daran, ein immer wiederkehrendes Problem zu lösen, welches das Log füllte: Ich greife die Werte meiner ZigBee Temperatur-Sensoren ab und speichere sie auf einem Server in eine Datenbank. Gleichzeitig cache ich den aktuellsten Wert eines Sensors als JSON auch unter dem Web-Root eines Virtualhosts, damit ich den aktuellen Wert rasch und umkompliziert per HTTP abfragen kann.

Immer wieder kam dabei vor, dass beim Dekodieren solcher JSON-Dateien ein Fehler auftrat. Schlussendlich programmierte ich eine Routine, die solche JSONs mit falscher Syntax entdeckte und kurzerhand löschte. Dementsprechend führten Anfragen für die Cache-Dateien bestimmter Sensoren anschliessend zu dutzenden Einträgen in php.log, weil die Cache-Datei nicht mehr gefunden werden konnte:

[08-Feb-2023 19:06:34 Europe/Zurich] E - json_decode() returned null for path "/var/www/app/cache/BathroomWindow.json" but payload is 128 bytes. JSON error: "Syntax error". Unlinking file assuming it is malformed. in /var/www/app/class.php:258 for URI  (Referer: unknown) from IP 10.1.2.3 with User Agent "Mozilla/4.0 (compatible; cron/SERVER/USER/cron.sh)"
...
[08-Feb-2023 19:07:19 Europe/Zurich] E - Path "/var/www/app/cache/BathroomWindow.json" not found in /var/www/app/class.php:247 for URI  (Referer: unknown) from IP 10.1.2.3 with User Agent "Mozilla/4.0 (compatible; cron/SERVER/USER/cron.sh)"

Erst wenn der Sensor wieder ein Lebenszeichen sendete, konnte das Cache-File neu erstellt werden, und die Fehlermeldungen hörten auf.

Doch wieso war die JSON-Syntax zerschossen? Um dem auf den Grund zu gehen, baute ich in die Subroutine, welche die Syntaxprüfung durchführt, noch eine zusätzliche Zeile hinzu, welches den Inhalt der kaputten JSON-Datei in das Log schrieb. Hier ein Beispielresultat:

[09-Feb-2023 20:06:29 Europe/Zurich] E - JSON payload: "{"utime":1675969548,"sid":"158d000XXXXXXX","deviceName":"Office Mario Door","open":true,"deviceType":"magnet","battery":100}":100}" in /var/www/app/class.php:259 for URI  (Referer: unknown) from IP 10.1.2.3 with User Agent "Mozilla/4.0 (compatible; cron/SERVER/USER/cron.sh)"

Das letzte ":100} sollte wirklich nicht dort stehen und machte keinen Sinn. Es sah so aus, als ob die Datei zwei Mal geschrieben wurde: Zuerst mit einem längeren String, und gleich darauf mit einem kürzeren String. In der Tat ist es so, dass die ZigBee-Sensore manchmal innert Sekunden zwei oder mehrere Male Werte absenden. Könnte ich also einer Race Condition beim Schreiben von Dateie aufgesessen sein?

Wie man das löst? Wenn Prozess A die Cache-Datei schreibt, muss sie für andere Prozesse gesperrt werden. Tatsächlich kennt PHP das Flag LOCK_EX für file_put_contents(), und seit ich dieses mitgebe, hat sich das Problem (zumindest in den letzten 48 Stunden) nicht mehr wiederholt:

...
$res = file_put_contents($filename, $jsonOut, LOCK_EX);
...

Tags: , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 6. Juni 2021

PHP-Scripts mit Xdebug profilen

Einleitung: Xdebug: Documentation » Profiling

Hierzu muss man PHP Xdebug auf seinem System installiert haben. Anschliessend lässt man ein PHP-Script folgendermassen laufen:

$ php -d xdebug.profiler_enable=On index.php

Nachdem das Script durchgelaufen ist, findet sich unter /tmp eine Datei im Namensformat cachegrind.out.%ZUFALLSNUMMER%. Bei mir war die Datei satte 140MB gross.

Doch was man nun damit? Zuerst einmal auf den Mac kopiert, dann mit qcachegrind (eigentlich: kcachegrind) analysiert. Dieses installiert man sich mit MacPorts:

# port install qcachegrind

Mittels Spotlight sucht man nach „qcachegrind“ und startet die präsentierte App. Man wählt cachegrind.out.%ZUFALLSNUMMER% und erhält folgendes zu Gesicht:

Tags: , , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 3. Dezember 2020

PHPs session_start() meldet „Permission denied (13)“

Ein kürzlich live gegangenes Web-Projekt, welches bei Hostpoint gehostet wird, füllt mir das PHP Error Log mit folgendem Müll:

...
[03-Dec-2020 13:32:32 Europe/Zurich] PHP Notice:  session_start() [function.session-start.php]: ps_files_cleanup_dir: opendir(/var/cache/php-sessions) failed: Permission denied (13) in /home/tenant/file.php on line 14
...

Die Lösung liegt darin, in der Datei .user.ini im Web-Root des Projekts mit dem Parameter session.save_path zu ergänzen und diesen Eintrag auf ein Verzeichnis im eigenen Tenant zeigen zu lassen. Ich empfehle, das Verzeichnis nur für den Besitzer les- und schreibbar zu machen, d.h. auf linuxisch chmod 700 anzuwenden, damit die Berechtigungsmaske drwx------ lautet.

...
[PHP]
error_reporting = E_ALL
display_errors = Off
error_log = /home/tenant/var/log/domain.php.err
session.save_path = /home/tenant/tmp

Tags: , , , , ,
Labels: Linux, Web

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 14. Oktober 2020

Credit Suisse Direct: Keine Textsuche möglich

Es ist 2020, aber die Entwickler der Schweizerischen Grossbank schaffen es nicht, Buchungen ausschliesslich nach einem bestimmten Text zu durchsuchen. Ich muss zwingend noch weitere Suchkriterien angeben (bspw. Mindest- und Maximalbetrag), sonst kann ich das Suchformular nicht absenden:

Tags: , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 14. Oktober 2020

Gegenstände auf Bildern vermessen

Kürzlich, beim Stöbern auf IKEA entdeckt: GRUNDVATTNET
Durchschlag, grau
für 4.95 CHF. Interessant! Könnte das auch etwas für unser Spülbecken in der Küche sein?

Die Masse des Hilfsmittels sind auf der Artikelseite angegeben, doch mir fehlt als Angabe die Länge der verkürzten Unterseite. Passt das Ding in unser Spülbecken oder nicht?

Ich lade mir eine Kopie des hochauflösenden Bildes herunter und mache mich auf die Suche nach einer Web-Seite, mit welcher man Gegenstände auf Bildern vermessen kann. Denn die Länge an der Oberseite des Gegenstandes kenne ich ja: 47 Zentimeter.

Ich werde bald fündig: Measure in Photo Online

Ich lade das Photo hoch, erstelle eine Linie über die Länge des Gegenstandes und gebe die Referenzlänge dieser Linie ein. Danach zeichne ich einige andere Linien, und sofort zeigt mir das Tool die reale Länge dieser Linien an:

Fazit: Mittlerweile habe ich den Gegenstand gekauft. Und ja, das Ding passt mit 35 Zentimeter Länge tatsächlich haargenau in unser Spülbecken. Das lässt mich vermuten, dass Spülbecken in Europe offenbar normiert sind.

Tags: , , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen