Bernhard Häussner
Tags: Artikel mit dem Tag «Codesnippets» durchstöbern

Servicemenüs für Dolphin (neu)

15.01.2010, 18:44

Wenn man häufig ein paar einfache Scripte über verschiedene Dateien laufen lassen will, kann man die ensprechenden Befehle mit Dolphin über ein frei einstellbares Servicemenü aufrufen. Man benötigt lediglich eine besonders formatierte .desktop-Datei und dann kann man das Skript in Zukunft über das Kontextmenü aufrufen.

Die Datei sieht z.B. so aus:

[Desktop Entry]
Encoding=UTF-8
Type=Service
ServiceTypes=KonqPopupMenu/Plugin,all/allfiles
Actions=timeBu

[Desktop Action timeBu]
Name=Create backup
Name[de]=Backup erstellen
Icon=document-revert
Exec=cp %U %U.`date +%%Y-%%m-%%d.%%H-%%M-%%S` && kdialog --title "Backup" --passivepopup "Backup of `basename %U` created. " 5

Unter ServiceTypes kann man die mine-typen angeben, bei denen das Script im Aktionen-Menü angezeigt werden soll, unter Name steht der Text, der dann angezeigt wird. Man kann Übersetzungen anbieten. Das Icon ist am besten eines der KDE-Icons. Nach Exec steht dann der Code, der ausgeführt werden soll. Mit %U lässt sich der Dateiname der ausgewählten Datei referenzieren, %% wird zu % umgewandelt. Diese Datei kommt dann in den Ordner:

~/.kde4/share/kde4/services/ServiceMenus

Neben dem Beispiel habe ich auch noch ein Menüeintrag erstellt, um optipng auszuführen:

auf ähnliche weise lassen sich auch andere praktische Sachen verwirklichen. Ich habe z.B. noch Servicemenüs für Konqueror erstellt, die sich mit einem Skript konvertieren lassen. Eine paar duzend Servicemenüs finden sich auch auf kde-apps.org.

Kommentare: keine

Javascript Regular Expressions Beispiele

03.11.2009, 18:18

Viele Javascript-Tutorials zum RegExp-Objekt benutzen die RegExp.$1-Notation und andere unschöne Dinge. Außerdem gibt es mehrere nahezu äquivalente Funktionen, was Reguläre Ausdrücke angeht. Darum habe ich ein Bisschen herumgespielt mit den Funktionen S.match(R), R.exec(S), R.test(S), S.split(R), S.replace(R) und S.search(R). Hier ist die kleine Referenz mit viel Beispiel, mit der ich hoffe arbeiten zu können:

RegExp-Objekte erstellen

// short constructor
var regexp=/a(b?c)/i

// long constructor
var regexp=new RegExp("a(b?c)","i"):
// -> allows runtime configuration
var char="a";
var regexp=new RegExp(char+"(b?c)",'i');

In der Praxis wird man fast immer den kurzen Konstruktor verwenden. Manchmal lässt sich ein dynamisches Erstellen des RegExps vermeiden, indem man den Treffer überprüft.

Finden mit String.match(RegExp) und RegExp.exec(String)

// match: basic usage
"a".match(regexp);   //  null
"abc".match(regexp); // ["abc", "bc"]
// -> "i"-flag: caseinsensitive
"Ac".match(regexp));  // ["Ac", "c"]
"acb".match(regexp); // ["ac", "c"]

// exec: same but method of regexp
regexp.exec("a");   //  null
regexp.exec("abc"); // ["abc", "bc"]
regexp.exec("Ac");  // ["Ac", "c"]
regexp.exec("acb"); // ["ac", "c"]

Bis auf wenige Ausnahmen (siehe unten) sind die beiden Funktionen gleich. Zurückgegeben wird ein Array mit dem gesamten passenden Teil und den im regulären Ausdruck eingeklammerten Teilen.

Prüfen mit RegExp.test(String)

// test: just booleans
/^abc$/.test("abc"); // true
/^abc$/i.test("AbC"); // true
/^abc$/.test("abcd"); // false

Diese Funktion ist zum Validieren von Eingaben recht praktisch, wenn es nicht auf den Inhalt des Strings ankommt.

Teilen mit String.split(RegExp)

// split: arrayify stings
"a,b,c.d".split(/\.|,/) // ["a", "b", "c", "d"]
"a,.b- c .d_e".split(/[.,-_]/) // ["a", "", "b", " c ", "d", "e"]
"a,.b- c .d_e".split(/[.,-_\s]*/) // ["a", "b", "c", "d", "e"]

Das Teilen kann auch mit einem normalen String geschehen, aber mit einem RegExp lassen sich, wie in diesem Beispiel demonstriert erweitere Funktionen implementieren, wie mehrere mögliche Trennzeichen oder das kürzen von Whitespace und leeren Elementen.

Lokalisieren mit String.search(RegExp) und RegExpResult.index

// search: match position
"0123b56b".search(/b/g); // 4
"0123b56b".search(/x/g); // -1

// index: match position, too
/b/.exec("0123b56").index; // 4
"0123b56".match(/b/).index; // 4
// -> "g"-flag:global
/b/g.exec("0123b56b").index; // 4
"0123b56b".match(/b/g).index; // undefined

Interessant ist, dass match und global sich nicht vertragen. Irgenwie ist es schon eine rechte Eigenart dass sich gobale und nicht-globale Ausdrücke so startk unterscheiden, daher würde ich RegExp-Objekte nicht zu weit durch Methodenaufrufe schicken.

Ersetzen mit String.replace(RegExp,replacement)

// replace
var string="ab-ghi-abc-hl-ac"
string.match(regexp); // ["abc", "bc"]
string.replace(regexp,"#")); // "ab-ghi-#-hl-ac"

Globales Finden und Ersetzen

// more global
var regexp2=new RegExp(regexp.source,'g')
string.replace(regexp2,"#"); // "ab-ghi-#-hl-#"
string.match(regexp2); // ["abc", "ac"]
// loop like that:
regexp2.exec(string); // ["abc", "bc"]
regexp2.exec(string); // ["ac", "c"]]
regexp2.exec(string); // null
regexp2.exec(string); // ["abc", "bc"]

Hier unterscheiden sich match() und exec()! Während match() ein Array der allen Treffern aus den kompletten Trefferstellen liefert, liefert exec(), wie beim nicht-globalen, pro Fundstelle je ein Array inclusive Klammerstellen. Um mit exec() alle Treffer zu erhalten, kann man z.B. eine while-Schleife verwenden.

Backreferences

// backreferences
/([ab])c\1/.test("aca"); // true
/([ab])c\1/.test("bcb"); // true
/([ab])c\1/.test("bca"); // false

// replacement backreference
// notice 1-9 limitation
"ll mm kk kx a Bb lL".replace(/([lkb])\1/gi,"$12")
"l2 mm k2 kx a B2 l2"
// beyond 1-9
"abcdefghijklmnopqrst".replace(/(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)/i,"$13-$1-$13+++") // "m-a-m+++qrst"
"abcdefghijklmnopqrst".replace(/(.)(?:.)(?:.)(?:.)(?:.)(?:.)(?:.)(?:.)(?:.)(?:.)(?:.)(?:.)(.)(?:.)(?:.)(?:.)/i,"$2-$1-$13+++") // "m-a-a3+++qrst"
// get a $
"ab".replace(/(.)/,"$$1") // $1b
"ab".replace(/(.)/g,"$$1") // $1$1
// special backrefs:
"abcdefg".replace(/(d)e/,"[ $`-$1-$' (inst $&) ]") // "abc[ abc-d-fg (inst de) ]fg"

Richtig interessante Dinge lassen sich machen mit Backreferences. Grundsätzlich können doppelte Vorkommen von passenden Teilen geprüft werden. Beim Ersetzen sind sie essenziell für Umformatierungen.

Spezialitäten

// special firefox shortcut:
/a/("cba") // a
/a(.)/("acbab") // ["ac", "c"]
// Ein Bonbon:
/\\/("\\")//["\"]
// Noch eines:
function _(é) {var ì=Array,í=RegExp,è=["join","length","replace"],î=[],_
="\x31",_=_*_,ë=_+_+_*_;for (var i=ë;i>=_;i--) {î[î[è[_]]]=("((\\\x64)"+
(new ì(i)[è[_-_]]("\\"+(ë-i+_)*(_+_)))+")");}var î=new í(î[è[_-_]]("|"),
"\x67"),ï=function(){var I=arguments;for(var i=ë;i>=_;i--){var j=(_+_)*(
ë+_-i);if(I[j]) {return i+I[j];}}},ì="",í=_+ì;for (i=_-_;i<é;i++) {ì+=(i
+"\x20"+í+"\n");í=í[è[_+_]](î,ï);}return ì;}alert(_(9));

Der Firefox-Shortcut könnte zwar praktisch sein, wird aber nicht von vielen Browsern unterstützt, und ist auch ein bisschen zu abstrakt.

Letztere Funktion benutzt Backreferences sowohl im RegExp als auch im Ersetzungstext, zudem ersetzt sie Rekursiv und baut das RegExp dynamisch. Außerdem habe ich sie ein bisschen verschlüsselt, da die Berechnung der ausgegebenen Zahlenreihe eigentlich ein Rätsel ist. Wenn man allerdings weiß, dass ich RegExp verwende, fällt die Lösung leichter, und wenn man es gelöst hat, weiß man vielleicht auch warum es ein perfekter Vorwand ist, um sich etwas mit Regulären Ausdrücken zu beschäftigen.

Such-Wiki zu „javascript regexp“

Kommentare: 2 Einträge

Firefox-Tricks für Webentwickler

30.10.2009, 10:12
userContent.css

userContent.css

Der populäre Webbrowser Mozilla Firefox zeichnet sich unter anderem durch viele Add-Ons aus. Jedoch wird nicht jede persönliche Vorliebe durch ein Add-On abgedeckt. Doch wer sich etwas mit Javascript und CSS auskennt, kann auch selbst kleine Einstellungen machen, ohne viel Aufwand. Dazu gibt es mindestens diese vier Möglichkeiten:

Anpassen von userContent.css und userChrome.css

Diese beiden Dateien befinden sich im Unterordner chrome des Firefox-Profilordners und müssen meistens angelegt werden. Sie sind (fast) ganz normale CSS-Stylesheets; Die userChrome.css enthält CSS-Regeln, die auf das XUL-Interface des Browsers, also alle Menüs, Toolbars etc. angewendet werden. So ist es leicht, z.B. die Schriftgröße der Bedienelemente zu vergrößern, oder der Adressleiste eine Monospace-Schriftart zu verpassen. Auf mozilla.org gibt es weitere Beispiele für userChrome.css.

Die Datei userContent.css enthält CSS-Regeln, die auf die angezeigten Webseiten angewendet werden. Ich benutze die Datei, um mich vor gewissen Links zu warnen: Zum Beispiel mag ich es nicht von Google immer auf experts-exchange.com zu klicken. Darum habe ich diese kleine Regel eingebaut, die mittels CSS3-Attribut-Selektor alle Links zu dieser Seite durchstreicht und verblasst:

a[href^="http://www.experts-exchange.com/"] {opacity:0.3 !important; text-decoration: line-through ! important;  }

Das !important bewirkt, dass die Regel die bereits vom Webseitengestalter gesetzten Regeln überschreibt.

Die Regeln lassen sich glücklicherweise auf bestimmte Seiten beschränken, so wie hier:

@-moz-document url(http://twitter.com/), url(http://twitter.com/home)
{
.latest-status {background-color:#FFFFC9;}
}

Diese Regel hinterlegt z.B. die letzte selbst geschriebene Nachricht im Stream von twitter.com mit einem leichten Gelb. Das erleichtert zu sehen, was wann passiert ist.

Eigene Sidebars

Wer Plattform-übergreifende Widgets basteln will, kann auf die Firefox-Sidebar zurückgreifen. In dieser lassen sich beliebige Webseiten anzeigen. Dazu muss man lediglich ein besonderes Lesezeichen erstellen, dass dann immer in der Sidebar geöffnet wird:

Sidebar Lesezeichen

Sidebar Lesezeichen

Man kann also wenn man etwas Bildschirmplatz opfern will, selbst gemachte Widgets anzeigen lassen. Der Link im Screenshot verweist auf eine Seite, die nur ein Textfeld enthält, um schnell Notizen zu machen oder als erweiterte Zwischenablage. Doch die Möglichkeiten sind nahezu unbegrenzt (Monitoring, Feeds, ...?).

Bookmarklets

Bookmarklets führen auf Knopfdruck bestimmte Javascript-Schnippsel auf einer Webseite aus, und funktionieren dabei nicht nur im Firefox. Dazu muss man den JS-Code von Zeilenumbrüchen befreien, alle Leerzeichen mit %20 kodieren und das Ganze dann umschließen mit:

javascript:(function(){/*here goes the code*/})();

So wird das Script zu einem Javascript-Link, der dann als Lesezeichen gespeichert werden kann. Ich habe mir z.B. ein Twitter Bookmarklet gebastelt. Außerdem einen DOM-Performance-Tester:

javascript:(function(){var%20d=0,l=500,n=document.getElementsByTagName('*').length;for(var%20i=0;i<l;i++){document.body.style.display='none';var%20s=Number(new%20Date());document.body.style.display='';var%20h=document.body.clientHeight;d+=Number(new%20Date())-s;}alert('Reflow:%20'+(d/l)+'%20ms%20('+Math.round(1000/(d/l))+'%20fps)\nDOM-Nodes:%20'+n+'\nRewlow%20per%20node:'+Math.round(1000000*d/(l*n))+'%20ns');})()

DOM-Benchmark

Das Kurze Script ermittelt, wie lange der Browser für einen Seitenaufbau braucht und wie viele DOM-Knoten das Dokument enthält. Es ist praktisch, wenn man komplexere Javascript-Animationen oder ähnliches erstellt, die langsam wirken. Dann offenbart der Test, ob nicht zu viele DOM-Knoten oder komplizierte CSS-Regeln die Seite verlangsamen.

Faustregel: Je weiter hinten ein Selektor steht, desto weniger Elemente sollten auf ihn passen, also li #id ist schneller als #id li, wobei sich das besonders in Verbindung mit CSS-Expressions bemerkbar macht.

Greasemonkey

Um auf bestimmten Seiten JS-Code auszuführen, gibt es das Firefox-Plugin Greasemonkey. Zu diesem Add-On gibt es nicht nur ein großes Repositorium existierender sog. Userscripts, sondern man kann auch schnell ein eigenes Script erstellen, um auf bestimmten Webseite irgendetwas anzupassen. Außerdem kann man jQuery benutzen mit folgender Zeile im Header:

// @require http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js

Ich habe z.B. ein Quick Search-Userscript gebastelt, welches beim Auswählen von Text ein kleines Menü öffnet, sodass ich den Text z.B. googlen, übersetzen oder twittern kann.

Es gibt also mehr effektive Möglichkeiten Firefox anzupassen, als das installieren von Add-Ons.

Kommentare: keine

Howto: PHP5.3 parallel zu PHP5 installieren

27.10.2009, 17:49

Wenn man die neuen PHP-5.3-Funktionen testen will, aber trotzdem für die meisten Projekte aus Kompatibilitätsgründen eine ältere PHP(5)-Version benutzen will, kann man PHP 5.3 parallel als CGI-Modul installieren. Dazu sind folgende Schritte möglich:

Zunächst benötigt man den Quelltext (Sourcecode) der aktuellen php5.3-stable Version. Er ist zu finden auf der PHP-Download-Seite bzw. Version 5.3.0 kann so direkt heruntergeladen werden:

wget http://de2.php.net/get/php-5.3.0.tar.gz/from/this/mirror
tar xzfv php-5.3.0.tar.gz
cd php-5.3.0/

Dann muss die PHP-Installation konfiguriert werden. Dazu benutzt man zunächst in der Ausgabe von phpinfo() das "Configure Command" als Basis. In diesem ändert man dann in den Dateipfaden php5 zu php53 und man setzt --bindir=/usr/bin/php53, um Konflikte mit anderen php5-Binaries zu vermeiden. Das sieht z.B. so aus:

./configure --prefix=/usr/share/php53\
 --datadir=/usr/share/php53\
 --mandir=/usr/share/man\
 --bindir=/usr/bin/php53\
 --with-libdir=lib64\
 --includedir=/usr/include\
 --sysconfdir=/etc/php53/apache2\
 --with-config-file-path=/etc/php53/apache2\
 --with-config-file-scan-dir=/etc/php53/conf.d\
 --enable-libxml\
 --enable-session\
 --with-pcre-regex=/usr\
 --enable-xml\
 --enable-simplexml\
 --enable-filter\
 --disable-debug\
 --enable-inline-optimization\
 --disable-rpath\
 --disable-static\
 --enable-shared\
 --with-pic\
 --with-gnu-ld

Eine Liste mit allen Optionen zeigt ./configure --help. Das Konfigurieren überprüft alle Einstellungen und wird eine Weile laufen - und meistens nicht beim ersten Mal klappen, was meistens bedeutet, dass --with-xyz verwendet wurde, ohne dass die entsprechenden Libraries gefunden wurden. Dann muss man das Modul deaktivieren oder nach einer Lösung googeln/bingen. Manchmal fehlen auch Header, welche, je nach Distribution, in einem Paket ähnlich wie [lib]xyz-dev[el] zu finden sind.

Als nächstes wird das ganze kompiliert und (als root/superuser) die neue PHP-Version installiert:

make
# optional, dauert, findet aber Fehler:
make test
# bringt die Dateien an ihren Platz: 
sudo make install

Jetzt muss noch Apache über das neue CGI-Modul informiert werden. Dazu müssen die folgenden Konfigurationen gesetzt werden (z.B. elegant in einer neuen Datei /etc/apache2/conf.d/php53cgi.conf):

# Damit mod_mime die neue Dateierweiterung erkennt:
AddHandler php53-cgi .php53
# Damit die Binaries aufgerufen, nicht versendet, werden:
ScriptAlias /bin-php53 /usr/bin/php53/
# Was eigentlich passieren soll:
Action php53-cgi /bin-php53/php-cgi
# Und noch ein paar Einstellungen für die Binaries:
<Directory /usr/bin/php53>
    # Kein .htaccess:
    AllowOverride None
    # CGI aktivieren, softlinks folgen
    Options +ExecCGI +FollowSymLinks
    # normalerweise ist der Zugriff auf alle „sonstigen“ Dateien gesperrt, 
    # daher hier wieder freigeben: 
    Order allow,deny
    Allow from all
</Directory>

Zum Testen kann man z.B. eine phpinfo.php53-Datei anlegen und man sollte die neue PHP-Verion angezeigt bekommen. Auf dieser Info-Seite kann man dann prüfen, ob alle Module verwendbar sind, die Zeitzone gesetzt ist und anderen potentielle Konfigurationsfehler auf die Schliche kommen. PHP 5.3 wird auch seine eigene php.ini in /etc/php53/apache2/php.ini verwenden, wohin man vielleicht zunächst die alte Konfigurationsdatei kopieren will.

# php.ini replazieren:
sudo cp /etc/php5/apache2/php.ini /etc/php53/apache2/php.ini
# im Webroot phpinfo mit namespace-Spielerei anlegen :)
echo "<?php namespace YEEES; phpinfo();" > phpinfo.php53

Nach den Schritten dieses Tutorials dürfte dann PHP 5.3 mehr oder weniger optimal laufen, ohne dass die Funktion alter Scripte eingeschränkt werden muss, und es lässt sich einfach die Interkompatibilität zwischen den Versionen testen.

Keine Garantie, Verwenden auf eigenes Risiko.

Edit 2009-10-28: On-the-fly zu PHP5.3 Wechseln

Das ständige Umbenennen von Dateien kann natürlich sehr mühsam sein. Leicht wechselt man ganze Verzeichnisse zu PHP5.3 indem man folgendes in ihrer .htaccess-Datei einfügt:

AddHandler php53-cgi .php

So kann man dann auch zum Testen schnell den ganzen Server zwischen den Versionen wechseln.

Kommentare: 7 Einträge

VNC mit openSUSE oder Debian Linux (Howto)

22.10.2009, 09:13

Die Verwendungsmöglichkeiten einer Remote-Desktop-Lösung reichen von Fernadministration bis Support. VNC erlaubt den Fernzugriff auf graphische Benutzeroberflächen. Eine Kurzanleitung zur Installation von VNC-Server und -Client unter openSUSE und/oder Debian:

Server

Zunächst benötigt man auf dem Server (der Computer dessen Bildschirm übertragen werden soll) einen VNC-Server, wie z.B. x11vnc:

sudo zypper install x11vnc
#oder Debian:
sudo aptitude install x11vnc

Als nächstes legt man eine Passwort-Datei an, in der das Passwort für den Fernzugriff gespeichert wird:

mkdir ~/.vnc
x11vnc -storepasswd ~/.vnc/passwd
#(fragt nach einem neuen Passowrt)
chmod 0600 ~/.vnc/passwd

Da die Firewall den benutzen Port 5900 blockieren sollte, wird das Passwort nur gebraucht, da sich nicht jeder Benutzer des Server-Computers in den Desktop einklinken können soll. Nun könnte auf dem Server schon der VNC-Server gestartet werden, doch das mache ich dann vom Client:

Client

Zunächst stellen wir sicher, dass es ein VNC-Client installiert ist:

sudo zypper install tightvnc
#oder Debian:
sudo aptitude install xtightvncviewer

Da die Verbindung sicher sein soll und Firewalls umgehen soll, wird das ganze über SSH getunnelt (Mehr zum SSH-Tunnel am Beispiel MySQL), und der Server gleich mit gestartet, durch dieses kleine Script: (Es setzt eine konfigurierte OpenSSH Public Key Authentication voraus)

#!/bin/bash
SSHLOGIN=user@vncserver
ssh -L 5900:localhost:5900 $SSHLOGIN "x11vnc -localhost -display :0 -rfbauth ~/.vnc/passwd" &
sleep 3
vncviewer localhost

Optional kann man auch die SSH-Option -C angeben, die bei Netzwerkverbindungen mit geringer Bandbreite (Internet) die Daten komprimiert und somit alles schneller läuft. Theoretisch.

Arbeitet man auf verschiedenen remote Desktops kann man $SSHLOGIN durch $1 ersetzen und dann das Script mit der passenden User/Server-Kombination für SSH starten.

Das Script verlangt die Eingabe des des oben gesetzten VNC-Passworts, dann müsste der Remote Desktop zu sehen sein.

Kommentare: 5 Einträge
 
Χρόνογραφ
© 2008-2017 by Bernhard Häussner - Impressum - Login
Kurz-Link zur Homepage: http://1.co.de/