Stop the big brother state
10th of March 2007
Exzellente Animation, die das Dilemma des fragwürdigen Umgangs mit dem Datenschutz behandelt. (Text übernommen, [via])
13 Fragen zum neuen Telemediengesetz
22nd of February 2007
13 Fragen zum neuen Telemediengesetz. [via dobschat]
Box.net - Free Online File Storage
24th of January 2007
Box.net – Free Online File Storage, Internet File Sharing, RSS Sharing, Access Documents & Files Anywhere, Backup Data, Share Files. Das nette ist, dass es auch ein Malkasten-buntes Ajax-Interface gibt und andere nettigkeiten (nicht neu, kannte ich aber noch nicht).
Kennt jemand besseres oder vergleichbares mit evtl. besserer Anbindung in DE?
Scuttle to del.icio.us
06th of July 2006
For some reason, I wanted to convert my scuttle based bookmark collection, for which I run a local installation of scuttle 0.5.*, to del.icio.us. Fortunately del.icio.us provides an HTTP based API which is verry easy to use, and thus it was verry easy to transfer all of my collected links to del.icio.us.
The following text, explains the steps, that I used to perform my data.
For some reason, I wanted to convert my scuttle based bookmark collection, for which I run a local installation of scuttle 0.5.*, to del.icio.us. Fortunately del.icio.us provides an HTTP based API which is verry easy to use, and thus it was verry easy to transfer all of my collected links to del.icio.us.
The following text, explains the steps, that I used to perform my data.
The first step was to export scuttle’s data into XML. Since I used a verry old version of scuttle (0.5.*) I used the following link and saved the result to my local machine.
The second step was (unfortunately) a bit tedious. Since the encoding in the output file was br0ken for some reason, I decided to manually fix the file's encoding plus its contents. Of course, it is important to save the result using the proper encoding.
The result was a file employing the following structure:
<?xml version=”1.0” encoding=”iso-8859-1”?>
<posts tag="" user="bwolf">
<post href=”http://ianhenderson.org/megazoomer.html”
description=”ianhenderson.org – megazoomer”
extended=”Megazoomer makes windows full-screen.
Just press Command-Enter, and the front-most window
grows to fill your entire monitor.”
hash=”7f872862e6675407f730b8acdbe7dd54” tag=”mac apple”
time=”2006-07-04T04:07:34Z”/>
...
</posts>
Since the del.icio.us API uses different arguments, as the scuttle export file contains, I decided to pre-process the exported file to match the del.icio.us APIs arguments, using a simple XSLT file (which should be processed using a conforming processor like Saxon):
<?xml version=”1.0” encoding=”UTF-8”?>
<xsl:stylesheet version=”1.0”
xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”>
<xsl:output indent="yes"/>
<xsl:template match="posts">
<posts><xsl:apply-templates/></posts>
</xsl:template>
<xsl:template match="post">
<post url=”{@href}” description=”{@description}”
extended=”{@extended}” tags=”{@tag}”
dt=”{@time}”/>
</xsl:template>
</xsl:stylesheet>
The resulting file, is now ready to be processed using the following python program, which is written in functional style (or at least in a mix of functional and OO programming style, which was forced by the "batteries included in python):
#!/usr/bin/env python
import urllib, sys, time
from urllib import urlencode, urlopen
from xml.dom.minidom import parse, parseString
u = 'https://api.del.icio.us/v1/posts/add'
login, passw = 'del.icio.us-login', 'del.icio.us-passwd'
class Delicious(urllib.FancyURLopener):
version = '%s del.icio.us/0.1' % login
def prompt_user_passwd(self, host, realm):
return (login, passw)
urllib._urlopener = Delicious()
ps = map(lambda p: dict([(a, p.getAttribute(a).encode('utf-8'))
for a in ['url','description','extended','tags','dt']]),
parse(sys.argv[1]).getElementsByTagName("post"))
def upload(p):
print '.'
xml = parseString(urlopen(u, urlencode(p)).read(8192))
assert xml.getElementsByTagName('result')[0].getAttribute('code') == 'done'
time.sleep(1.5)
for p in ps: upload(p);
Finally, the transfer could be performed using the command python-program xml-file. Enjoy ;P
Bürgercert
02nd of March 2006
Tja, da komme ich mal wieder früh genug ins Hotel zurück, um die Nachrichten der ARD zu schauen, und sehe, dass eine neue Informationsstelle des BSI für den “normalen” Bürger aus der Taufe gehoben wurde.
Ok, schauen wir mal. Der erste Eindruck ist leider ernüchternd. Die URL buerger-cert.de führt doch glatt auf eine Seite mit dem Hinweis, dass meine Anfrage nicht bearbeitet werden kann:
»Ihre Anfrage konnte nicht bearbeitet werden!«
Ok, das war jetzt nicht ganz fair von mir. Ich habe die dumme Idee gehabt, einfach Safari für den Besuch der Site zu nutzen. Mit telnet oder FF geht es auch (vielleicht gehört man als telnet/Safari-Kenner aber auch nicht zur prädestinierte Zielgruppe; trotzdem mies).
Sehr schade eigentlich. Solche Dienstleistungen werden von den Medien registriert – was vor einigen Jahren noch undenkbar war (zu kleine Interessengruppe) – und dann das. Sowas nenne ich einen missglückten Start.
Btw: powered by Microsoft-IIS/6.0, ASP.NET, .NET Framework 1.1 – Ist ja nicht so, dass ich Vorurteile hätte ;P (Unsachlichkeit ist hier Absicht)
Update
So langsam scheint es zu funktionionieren :/
Lighttpd and MoinMoin
31st of December 2005
These days a lot of people visit my page about my lighttpd transition where also MoinMoin (a famous wiki software written in python) is mentioned. In order to fullfill the requests (how to run moinmoin with lighttpd) i created this entry.
These days a lot of people visit my page about my lighttpd transition where also MoinMoin (a famous wiki software written in python) is mentioned. In order to fullfill the requests (how to run moinmoin with lighttpd) i created this entry.
Note: Since I run moinmoin in a chrooted environment, the steps necessary to setup your environment may varry. Especially the scripts described later need some work in order to run all the cruft outside a chroot environment.
Idea: Run a standalone fast-cgi server under a special user account and let lighttpd connect to the fast-cgi server via tcp.
- Create a seperate vhost for your wiki
- Create a directory for your wiki that isn't accessible by your webserver (thus not DocumentRoot). That directory is referred in the following text as »target directory«
- Create a user that runs your wiki
- Copy as described in WikiInstanceCreation the »data« and »underlay« directories to the target directory and ensure that the wiki user is able to modifiy those dirs.
- Copy wikiconfig.py (usually distributed in /usr/share/moin/config/wikiconfig.py) to the target directory.
- Customise wikiconfig.py as required.
- Create a file called moin.fcg in the target directory with the content as described in (1).
- Use a startup file for your wiki's fast-cgi server as described in (2)
- Use a shell-script function library, used by your fast-cgi startup file, as described in (3)
- Customise the lighttpd.conf file as described in (4).
- Restart lighty and have fun ;-)
File (1): moin.fcg
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - FastCGI Driver Script
@copyright: 2004-2005 by Oliver Graf <ograf@bitart.de>
@license: GNU GPL, see COPYING for details.
"""
import sys
# Path of the directory where wikiconfig.py is located.
# YOU NEED TO CHANGE THIS TO MATCH YOUR SETUP.
sys.path.insert(0, '/your-path-to-target-directory')
use_threads = 1
from MoinMoin import config
config.use_threads = use_threads
del config
from MoinMoin.request import RequestFastCGI
from MoinMoin.support import thfcgi
def handle_request(req, env, form):
request = RequestFastCGI(req, env, form)
request.run()
if use_threads:
fcg = thfcgi.THFCGI(handle_request, 0, 8888)
else:
fcg = thfcgi.unTHFCGI(handle_request, 0, 8888)
fcg.run()
root@prometheus:-photo.cs.antbear.org/photo#
File (2): your-wiki.sh (the startup script)
#!/bin/sh
set -e
USER=your-wiki-user
HELPER=/your-path-to-script-3.py
CHROOT=/your-path-to-the-chroot
PY_EXEC=/your-path-to-the-fast-cgi-script-named-1
PIDFILE=/var/run/name-of-your-wiki.pid
EXEC_PATH=/bin:/usr/bin:/usr/local/bin
start_moinmoin () {
/usr/bin/env -i PATH=$EXEC_PATH
"$HELPER" -u $USER -c "$CHROOT"
-e "$PY_EXEC" -p "$PIDFILE" &
echo ""
}
stop_moinmoin () {
if [ -e "$PIDFILE" ]; then
kill `cat "$PIDFILE"`
fi
rm -f "$PIDFILE"
}
case "$1" in
start)
start_moinmoin
;;
stop)
stop_moinmoin
;;
restart)
stop_moinmoin
start_moinmoin
;;
*)
echo "Usage: `basename $0` {start|stop|restart}"
exit 64
;;
esac
File (3): script-3.py (called by file (2))
#!/usr/bin/env python
import os, os.path
import pwd, grp
import getopt, sys
def jail_process(user, chroot, verbose=False):
gid = pwd.getpwnam(user)[3]
gidnam = grp.getgrgid(gid)[0]
uid = pwd.getpwnam(user)[2]
os.chroot(chroot)
if verbose:
print "Changed root directory to %s" % chroot
os.chdir('.')
if verbose:
print "Changed directory to %s" % chroot
os.setgid(gid)
if verbose:
print "Changed gid to %s (%u)" % (gidnam, gid)
os.setuid(uid)
if verbose:
print "Changed uid to %s (%u)" % (user, uid)
def daemonise_process(stdin="/dev/null", stdout="/dev/null", stderr="/dev/null",
close_fds=True, newhome="/", pid_fd=None, verbose=False):
"""Daemonises the process. See [Stevens93] p. 418."""
try:
pid = os.fork()
if pid > 0:
sys.exit(0) # parent goes bye-bye
if verbose:
print "Forked process (pid=%d)" % os.getpid()
except OSError, e:
sys.stderr.write("Cannot fork: (%d) %sn" % (e.errno, e.errstr))
# first write the new process id (pid) into the given fd (if valid)
if pid_fd is not None:
print >> pid_fd, "%u" % os.getpid()
pid_fd.close()
pid_fd = None
if verbose:
print "Process ID written to pid-file"
os.setsid() # become session leader
os.chdir(newhome) # change working directory
os.umask(0) # clear our file mode creation mask
if verbose:
print "Changed directory to %s" % newhome
# reopen stdin,stdout,stderr
if stdin is not None:
fin = open(stdin, 'r')
os.dup2(fin.fileno(), sys.stdin.fileno())
if stdout is not None:
fout = open(stdout, 'w')
os.dup2(fout.fileno(), sys.stdout.fileno())
if stderr is not None:
ferr = open(stderr, 'w')
os.dup2(ferr.fileno(), sys.stderr.fileno())
# close remaining fds upon request
if close_fds:
try:
maxfd = os.sysconf('SC_OPEN_MAX')
except:
maxfd = 256
for n in range(3, maxfd):
try:
os.close(n)
except:
pass
def usage():
print >> sys.stderr, '''Usage: %s [-ucepvh]
Options are: -u --user Switch to the given users uid and gid
-c --chroot Chroot to directory
-e --exec Execute given python file in chroot
-p --pidfile File where the pid will be written to
-v --verbose Enable verbose mode
-h --help Show usage (this one)''' % os.path.basename(sys.argv[0])
if __name__ == '__main__':
try:
opts, args = getopt.getopt(sys.argv[1:], "u:c:e:p:vh",
["user=", "chroot=", "exec=", "pidfile=", "verbose", "help"])
except getopt.GetoptError:
usage()
sys.exit(2)
user = None
chroot = None
execfname = None
pidfname = None
verbose = False
for o, a in opts:
if o == "-u":
user = a
elif o == "-c":
chroot = a
elif o == "-e":
execfname = a
elif o == "-p":
pidfname = a
elif o == "-v":
verbose = True
elif o == "-h":
usage()
sys.exit(0)
if user is None or chroot is None or execfname is None:
usage()
sys.exit(2)
pidfd = None
if pidfname is not None:
pidfd = file(pidfname, 'w')
if verbose:
print "Daemonise in progress"
daemonise_process(close_fds=False, verbose=False, pid_fd=pidfd,
stdin=None, stdout=None, stderr=None)
else:
daemonise_process(close_fds=True, verbose=False, pid_fd=pidfd)
if verbose:
print "Jail process in progress"
jail_process(user, chroot, verbose)
# Change directory where our python file resides
os.chdir(os.path.dirname(execfname))
# strip path from execfname
execfname_base = os.path.basename(execfname)
# setup new command line arguments
args.insert(0, execfname_base)
sys.argv = args
if verbose:
print "Attempting to execfile (python exec): %s with args %s" % (execfname_base, sys.argv)
execfile(execfname_base)
File (4): lighttpd.conf fragment
$HTTP["host"] == "your.wiki.vhost.name" {
server.document-root = "/your-path-to-document-root/"
accesslog.filename = "| exec /usr/local/sbin/cronolog /www/log/lighttpd/your.wiki.vhost.name-%Y-%m.log"
fastcgi.server = ( "/your-wiki-prefix" =>
( "localhost" =>
(
"host" => "127.0.0.1",
"port" => 8888,
"check-local" => "disable",
"broken-scriptfilename" => "enable",
"docroot" => "/your-wiki-prefix",
)
)
)
# path to the static moinmoin data
alias.url = (
"/wiki" => "/usr/local/share/moin/htdocs",
)
url.redirect = (
"^/$" => "/your-wiki-prefix/",
)
}
Maybe this seems a bit overkill to you, but in reality it's quite simple and ensures the usual security constraints. Open questions? Ask!
k-what?
18th of December 2005
Ja es kann tasächlich mein CA-cert lesen und akzeptieren ;-)
My home
26th of June 2005
Ist ja witzig, dass man jetzt bei google maps auch Satelitenphotos von Deutschland zu sehen bekommt. Btw. hier wohne ich
Lighttpd Umstellung
26th of June 2005
Wie schon zuvor angemerkt, habe ich meinen host auf lighttpd umgestellt (über Sinn oder Unsinn kann man sich natürlich streiten). Da ich nicht so viele vhosts hoste (um die 10), war die Konfiguration ziemlich übersichtlich.
Einzig und alleine meine bis dato recht dürftige Erfahrung mit fastcgi machte die Umstellung etwas “mühsam”.
Wie schon zuvor angemerkt, habe ich meinen host auf lighttpd umgestellt (über Sinn oder Unsinn kann man sich natürlich streiten). Da ich nicht so viele vhosts hoste (um die 10), war die Konfiguration ziemlich übersichtlich.
Einzig und alleine meine bis dato recht dürftige Erfahrung mit fastcgi machte die Umstellung etwas “mühsam”.
Unabhängig von lighttpd, wird bei fastcgi pro Applikation ein (oder mehrere) persistente Prozesse gestartet, die dann natürlich unter ganz anderen Benutzern laufen können, als der eigentlich Webserver. So kann man z.B. ziemlich schmerzlos für Benutzer A eine Webapplikation betreiben, die auch Zugriff auf das Filesystem hat, aber keinen Schreibzugriff auf Verzeichnisse anderer Webapplikationen (Benutzer) hat…, was bei naivem mod_php nicht möglich ist (ok es gibt Dinge wie mod_suPHP).
Lighttpd unterstützt für fastcgi zwei Betriebsarten. Beim sog. adaptive-spawning startet lighttpd die fastcgi-Prozesse selbstständig und erzeugt bei Bedarf, konfigurierbar, mehr Prozessem, falls die Last steigt.
Alternativ können fastcgi-Prozesse über TCP oder UnixDomain-Sockets angesprochen werden. D.h. die Prozesse müssen extern (und unabhängig) vom Webserver gestartet werden.
Gut gefällt mir auch, dass man mit lighttpd load balancing für fastcgi benutzen kann.
In meiner Testumgebung hatte ich zunächst die erste Variante verwendet, da man sich so erstmal auf den Webserver und die Applikationen konzentrieren kann. Apropos Testumgebung: hierzu habe ich mir ein test-Verzeichnis anglegt und dort
- lighttpd
- mysql
- python
- php
- cronolog
installiert (configure—prefix=$HOME/test) und ausgehend davon die einzelnen Webapps getestet.
Untersucht habe ich folgende (alle fastcgi):
- Textpattern
- Wordpress
- Scuttle
- Squirrelmail
- Websvn
- einige selbstgeschriebene Applikationen
Probleme gab es eigentlich keine grösseren, ausser bei Scuttle, das extensiv PATH_INFO nutzt. Nützlich war hier dann letztlich der ausgesprochen freundliche IRC-channel #lighttpd auf freenode, wo mir Jan von der undokumentierten Option “broken-scriptfilename” erzählte.
MoinMoin habe ich leider, trotz einigen Experimenten, nicht mit fastcgi zum laufen bekommen (obwohl ich es in der Vergangenheit schon einmal unter fastcgi mit dem Indianer im Betrieb hatte). MoinMoin lieferte immer nur die Startseite aus, unabhängig von der angeforderten Seite. Nachdem ich “request.py” irgendwann total zerpflückt hatte, hab ich die Lust verloren und es so gemacht, wie man auf der MoinMoin-Site verfährt: ein lokaler twisted-Server, in dem moinmoin persistent läuft. Lighttpd verbindet sich dann per mod_proxy auf diesen.
Wie zu erwarten, gab es bei normalen CGIs (bei mir z.B. AWStats) wenig Probleme. Nagut, ViewCVS habe ich nicht auf Anhieb überreden können, aber das wollte ich sowieso durch WebSVN ersetzen.
mod_davsvn habe komplett eleminiert und durch svnserve ersetzt.
Mein persönliches Fazit ist: I love it! Die Konfiguration ist sehr übersichtlich und kompakt. Die Performanz ist ideal (auch dank freebsd-kqueue). Hier und da würde ich mir zwar mehr Einstellmöglichkeiten wünschen (z.B. bei ssl/tls), aber lighttpd ist ja noch jung und relativ unbekannt.
Lighttpd
25th of June 2005

Endlich habe ich Zeit gefunden meinen host auf lighttpd umzustellen. Mit fastcgi läuft ja nun schon eine Weile alles; nun aber richtig :-)
Dumm nur, dass bestimmte Applikationen sehr starke Darmschmerzen verursachen :-/
Dafür ist jetzt endlich TXP total br0ken!
Update: Scheint nur das Datumsformat gewesen zu sein. Wie immer: Für Hinweise bin ich dankbar :-)
Del.irio.us - deliri what?
30th of March 2005
Del.irio.us, Or How Not to Clone a Service
[via theflow]
Kein Sinn
10th of March 2005
Normalerweise schau ich sp*m nicht mal an. Aber ab und an ist das schon ganz witzig. Da stellt sich die Frage…
hits=24.5 tests=DATE_IN_FUTURE_96_XX, FRONTPAGE, HTML_60_70, HTML_FONT_BIG, HTML_FONT_INVISIBLE, HTML_IMAGE_RATIO_04, HTML_MESSAGE, HTML_OBFUSCATE_05_10, HTTP_ESCAPED_HOST, HTTP_EXCESSIVE_ESCAPES, MIME_HEADER_CTYPE_ONLY, MIME_HTML_ONLY, PRIORITY_NO_NAME, RCVD_IN_SORBS_DUL,RCVD_IN_XBL, UPPERCASE_50_75, URIBL_AB_SURBL, URIBL_OB_SURBL, URIBL_SC_SURBL, X_LIBRARY
Kann man als sp*mer noch mehr falsch machen?
Pagerank
14th of February 2005
PR(A) = (1-d) + d (PR(T1)/C(T1) + ... + PR(Tn)/C(Tn))
Aha, so ist das also mit dem Pagerank :)
Hier die Details (kannte ich noch garnicht).
Update:
obsolet
