2010-04-30
Neue Liste meiner NTP-Server
time.inf.ethz.ch ntp.metas.ch ntp.univ-lyon1.fr zg1.ntp.carnet.hr
Ändern mit dpkg-reconfigure ntp-simple.
Seinerzeit habe ich die Server anhand tiefer Ping-Zeiten ausgesucht.
swisstime.ethz.ch ist zum Stratum 1-Server avanciert und sollte
nicht mehr direkt von Endusern benützt werden.
15:06 [/software/debian] ntp_servers Google Trackback
Sommer, wo bleibst du?!?
Es muss einfach einmal gesagt sein: von einem Jahr war es nachts wärmer als diesen “Sommer” am Tag!
15:06 [/allgemein] sommer_2004 Google Trackback
Internet-Archäologie
Das erste Smiley wurde gefunden :-) [via Slashdot]
15:06 [/allgemein] smiley1 Google Trackback
Apache wieder OK
Während meinem heutigen dist-upgrade-Prozedere wurde Apache aktualisiert. Die Abhängigkeit von libdb1 ist tatsächlich schon kalter Kaffee:
apache (1.3.26-1.1) unstable; urgency=low
* NMU
* The "Shouldn't you be in Whoville stealing Christmas?" release.
* Applied patch from Ryan Murray to use db2's db185-compat functions
instead of glibc's (nonexistant) db1 library.
- Edited patch to include the same hack for mod_urlcount and mod_eaccess
from apache-contrib
- Closes: #143085 #156159 #156390 #156373 #155981
-- Adam Conrad <adconrad@0c3.net> Mon, 12 Aug 2002 21:08:40 -0600
Mein /usr/local/sbin/upgrade-Script sieht übrigens so aus:
#!/bin/sh
# constants
MAILTO=root
LOG=/var/log/aptitude
# mark the start of this upgrade in the log file
TAG="$(hostname | cut -f1 -d.) upgrade of $(date -Im)"
echo -e "\n${TAG}\n" >>$LOG
# grab the new package list
aptitude update
# do the dist-upgrade
aptitude dist-upgrade && aptitude autoclean
# update the local mirror in the background
if [ "$?" -eq 0 -a -d /mirrors -a "$1" != -q ]; then
apt-move local >/var/log/apt-move 2>&1 &
fi
# mail the new part of the log file
sed -ne "/^$TAG/,$p" $LOG | mail -s "$TAG" $MAILTO
Update: Jetzt ist es nur noch die libdav.so, die libdb1 immer noch benötigt!
libc6 breakage
Heute morgen hatte ich einen Fehler von Webalizer in meinem Server-Log:
Die libdb.so.2 war verschwunden! Gestern hatte sich die libc6 auf 2.2.5-13
aktualisiert, und in deren Changelog hatte ich folgendes gelesen:
- Remove db1 compat library. The only user I know of this is coda.
Coda can include it’s own version of the library now. I’ve emailed the
coda maintainer.
Da musste es doch einen Zusammenhang geben; offensichtlich ist Coda nicht
das einzige Paket, das noch auf diese Bibliothek angewiesen ist. Auf Debians
Paketsuchseite gibt es zwar noch
ein Ergebnis für die betroffene Datei, ein Vergleich mit der Dateiliste der
libc6 aus Sarge zeigt jedoch, dass die Datei in Sid jetzt fehlt. Anyway, ich
habe einen Bugreport für libc6 geschrieben.
15:06 [/software/debian] libc6_break Google Trackback
Arnold Stalder…
… wurde heute zum Gemeindepräsidenten von Aarberg gewählt.
Wir gratulieren und wünschen alles Nötige für dieses Amt!
15:06 [/allgemein] noldi_presi Google Trackback
Aus dem Keller
Dieses Progrämmli habe ich vor Monaten mal gebraucht, um eine Signatur zu generieren. Heute bin ich wieder einmal darauf gestossen:
#!/usr/bin/python
"""
This program encodes a string reversably into a longint.
The goal is to write the reverse function as a Python one-liner so that
it fits in an email signature.
The idea is to convert each character of the string to one digit of the number.
The twist is this: the number's base depends on the string, and each digit
is offset so that the base becomes as small as possible. The offset is one less
than the lowest numbered ASCII code in the string. The base is two more
than the difference between highest and lowest ASCII code. This way, the
lowest code gets the digit value 1, the highest code gets the value (base - 1).
The reverse function u() recursively undoes this transformation.
"""
print
str = raw_input('Enter a string: ')
if not str:
str = 'default test string'
# Convert the string to a list of ASCII codes.
codes = [ord(ch) for ch in str]
# Calculate offset and base.
ofs = min(codes) - 1
base = max(codes) + 1 - ofs
# Build the encoded number.
num = hex(reduce(lambda n, digit: base * n + digit - ofs, codes, 0L))
# Build the signature.
sig = """#!/usr/bin/python
def u(n, b, o): return n and u(n / b, b, o) + chr(n %% b + o) or ''
print u(%s, %d, %d)""" % (num, base, ofs)
print
print sig
# Verify.
print
exec sig
if u(eval(num), base, ofs) == str:
print 'OK'
else:
print 'not OK'
Das Ergebnis sieht für meine Mail-Adresse so aus:
#!/usr/bin/python def u(n, b, o): return n and u(n / b, b, o) + chr(n % b + o) or '' print u(0x90F8CA4FAD75C381BC173DA23L, 75, 45)
Das Dekodieren überlasse ich dem Leser als Übung!
15:06 [/software/python] mailsig Google Trackback
Hilfsprogramme für mein Album
Ich denke, dass jetzt ein guter Zeitpunkt ist, einmal meine paar Hilfsprogramme und -Scripts vorzustellen, mit denen ich die Bilder von der Kamera ins Album lade.
Das ganze geht in verschiedenen Schritten vor sich:
- Die Bilder werden mit einem USB-Kartenleser von der Compact-Flash-Karte in monatsweise Verzeichnisse auf der HD eingelesen. Ich benütze einen Kartenleser, weil so der Akku der Kamera geschont wird. Die HD-Verzeichnisse werden periodisch auf CD gebrannt.
- Zur Bildbearbeitung auf dem PC verwende ich IrfanView und/oder Photoshop Elements, das beim Scanner dabei war. Wenn ich an den Bildern überhaupt etwas editiere, beschränkt sich das meistens auf eine Freistellung des interessanten Ausschnitts (vor allem bei stark gezoomten Fotos) oder einen Farbausgleich.
- Als erstes rotiere ich mit der Batch-Konversion von IrfanView die Portrait-Bilder nach 90° links.
- Das Album-Verzeichnis auf dem Server ist via Samba mit dem PC verbunden.
- Die Bilder im Album sind meistens im Format 800×600 oder 600×800. Die Batch-Konversion von IrfanView ist bestens geeignet, um die Bilder zu verkleinern und gleichzeitig auf dem Server zu speichern.
- Auf dem Server generiert der Script
mkthumbdie Thumbnails neu, die nach dem Rotieren oder Ausschneiden natürlich nicht mehr dem Bild entsprechen.
Falls das Album nur klein ist, erledigen die Scripts mk800 und
mkportrait die Aufgaben von IrfanView direkt auf dem Server.
mkthumb
#! /bin/sh
# $Id: mkthumb 309 2004-09-14 22:10:35Z bb $
makethumb_file() {
echo "processing $f to tn_$f"
convert -size 160x160 "$f" -resize 160x160 -quality 50 -antialias "tn_$f"
}
makethumb_exif() {
exiftran -gibp "$f"
}
for f; do
case "${f##*.}" in
jpg)
makethumb_exif;;
png|gif)
makethumb_file;;
*)
echo "No thumbnail for $f";;
esac
done
Die Befehle convert und exiftran entstammen den Debian-Paketen
imagemagick resp.
exiftran.
Das Spezielle hier ist die Fallunterscheidung nach Dateityp. EXIF-Thumbnails können natürlich nur in JPEG-Dateien direkt gespeichert werden, alle anderen Bildformate brauchen eine externe Vorschaudatei.
mk800
#! /bin/sh
# $Id: mk800 301 2004-09-13 12:01:14Z bb $
make800x600() {
bak="${f}~"
mv "$f" "$bak" || true
convert -size 800x800 "$bak" -resize 800x800 -quality 80 -antialias "$f"
touch -r "$bak" "$f"
}
for f; do
make800x600
done
Ein Backup wird nur beim ersten Mal erstellt, und die originale Modifikationszeit wird vom Script wiederhergestellt.
mkportrait
#! /bin/sh
# $Id: mkportrait 300 2004-09-13 12:00:33Z bb $
makeportrait() {
exiftran -2ibp "$f"
}
for f; do
makeportrait
done
Dieser Script (resp. die Option “-2” von exiftran) berücksichtigt die Tatsache,
dass ich die Kamera bei Portrait-Bildern nach links drehe.
15:06 [/software] album_software Google Trackback
Unwort des Jahres
Gestern am Radio gehört: “präsentiert von …, dem [achtung, jetzt kommts:] Autoversicherungsprämienvergleichsdienst.”
Ich wusste ja immer, dass man in Deutsch zusammen gesetzte Nomen bilden kann, aber deswegen muss man solche Monstrositäten doch nicht am Radio in die halbe Welt hinaus posaunen… Tsk tsk!
15:06 [/medien] unwort_2004 Google Trackback
Verschwörungstheorien
Rense [via telepolis (in german)]:
As one trader reported, “My God! The bottom has fallen out and nobody calls it a crash. It’s like it’s your patriotic duty not to mention the word. Hell, the Dow’s lost more than 1,500 points—that’s a CRASH. But, if I’m overheard saying this, people look at me: `Where’s your American flag? Remember who you are and what’s going on. Do you want to help Osama bin Laden in his plot to destroy our economy?’ Unbelievable!”
But, as like many other media-brainwashed Americans, this trader was, in his words, “going with the program. It’s not a crash, it’s a terrorist event.”
Wer Verschwörungstheorien liebt…
15:06 [/allgemein] conspiracy_theories Google Trackback
Hundertster commit
Während dem Wochenende hat sich im Subversion-Repository, das fast mein
gesamtes $HOME-Verzeichnis beinhaltet, ein kleines Jubiläum ereignet:
Der einhundertste commit. Hier ist das diff (zugegebenermassen
nicht sehr blog-gen [ja, das war soeben meine erste Blog-spezifische Wortschöpfung!]):
bb@bolli:~$ svn diff -r99:100 Property changes on: public_html/news ___________________________________________________________________ Name: svn:ignore - index.* + *.html 200*
15:06 [/software] svn_rev100 Google Trackback
Microsofts brilliante Taktik
The Register USA: Microsoft identifies source of Windows 2000 attacks
Yesterday, though, Microsoft said the PSS Security Team has finally identified the reason for the attacks - users.
“The attacks seek to take advantage of situations where standard precautions have not been taken,” Microsoft said in an article posted on its web site.
The company listed standard precautionary measures not being adopted by users, including the elimination of blank or weak administrator passwords, disabling of guest accounts, running current anti-virus software with up-to-date virus signature definitions, using firewalls to protect internal servers including domain controllers, and maintaining up-to-date security patches.
Das ist natürlich eine brilliante Taktik. Mit solchen Aussagen wird den Benutzern ein schlechtes Gewissen eingeredet. Kommt dann die nächste Windows-Version mitsamt Palladium (in Verbindung mit Intels LaGrande-Chip) und unter dem Label «Sicherer, Schützt Ihre Daten besser als je zuvor», werden sich die meisten darauf stürzen (OK, sie werden ganz einfach keine andere Wahl haben, da die neuen 12 GHz-Octiums nur mit LaGrande erhältlich sein werden…). Nur ein paar Verwegene werden sich fragen, was das ganze soll, da sie ein Betriebssystem mit einem über dreissig-jährigen, aber trotzdem sichereren Sicherheitsmodell verwenden.
Für mich passt vieles in diesem grösseren Zusammenhang (DRM, Aufbewahren von Email-Verbindungsdaten, «Fair use» ade, etc.) auch ganz gut in die Nach-11.09-Atmosphäre, in der unter dem Vorwand der Terrorismusbekämpfung eine ganze Menge neuer Regeln durchgesetzt werden können, die vorher undenkbar gewesen wären.
15:06 [/software] reg_ms_users Google Trackback
TV-Karte läuft endlich
Nach langen Monaten ohne TV-Karte habe ich mich vor einigen Tagen entschlossen, es nochmals zu versuchen. Bisher hatte immer ein IRQ-Konflikt verhindert, dass ich ein Bild sehen konnte. Sendersuchlauf und Ton funktionierten. Nach einer kleinen Umsteck-Orgie hatte ich es geschafft, dass sich die TV-Karte (übrigens eine Pinnacle PCTV pro) den IRQ nur mit der Grafikkarte teilen musste, das nützte mit den beigelegten Treibern aber nichts: immer noch kein Bild!
Als Pinnacles Web-Seite habe ich dann allerdings neue Software gefunden. Meine mit der Karte gelieferte CD-ROM war Version 4.02 vom September 2000, aktuell auf dem WWW war 5.5 vom März 2003! Eigentlich erstaunlich, dass die Treiber noch aktualisiert werden… Nach dem 50MB-Download und einer komplizierten Installation war es dann so weit: es funktionierte!
15:06 [/software] pinnacle_pctv Google Trackback
OPML nach XHTML: funktioniert
Ich habe mich nochmals hinter das Problem der nicht funktionierenden XSL-Transformation meiner OPML-Datei geklemmt und tatsächlich herausgefunden, woran es lag. Es fehlte der Standard-Namespace, der die generierte Datei als XHTML deklariert hätte. Mit diesem neuen Vorspann in opml.xsl geht es:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns="http://www.w3.org/1999/xhtml" > <xsl:output method="xml" indent="yes" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" doctype-public="-//W3C//DTD XHTML 1.1//EN" />
Weitere “Kleinigkeiten”, die mir aufgefallen sind:
- IE6 wendet ein per
<xml-stylesheet>-processing instruction eingebundenes CSS-Stylesheet nicht an (wer hätte das gedacht;-) - Wenn die XSL-output method auf
htmlgesetzt wird, werden processing instructions nur mit > beendet, nicht mit ?>. - Es ist möglich, in XHTML PHP einzubetten, wenn das PHP-Flag
short_open_tagauffalsegesetzt wird. Andernfalls reklamiert PHP bereits bei der XML-Deklaration einen Syntax-Fehler.
15:06 [/software/blog] blogroll_xsl_success Google Trackback
Endlich: die Blogroll am rechten Rand!
Endlich habe ich es geschafft, meine Blogroll am rechten Rand zu verewigen. Grundlage ist das OPML-File, das auch von plagg gelesen wird. Mit Hilfe einer XSL-Transformation mache ich aus news.opml ein XHTML-Fragment, das von PHP an der entsprechenden Stelle eingefügt wird.
Dies ist das Transformations-File:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="no" standalone="yes"/>
<xsl:template match="head"/>
<xsl:template match="body">
<ul class="blogroll"><xsl:apply-templates/></ul>
</xsl:template>
<xsl:template match="outline">
<li><xsl:choose>
<xsl:when test='@htmlUrl != ""'>
<a href="{@htmlUrl}"><xsl:value-of select="@text"/></a>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@text"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test='@type = "rss"'> (<a href="{@xmlUrl}">RSS</a>)</xsl:when>
<xsl:when test='@type = "x-plagg-html"'/>
<xsl:when test='@type = "x-plagg-computed"'/>
<xsl:otherwise>
<ul><xsl:apply-templates/></ul>
</xsl:otherwise>
</xsl:choose></li>
</xsl:template>
</xsl:stylesheet>
Und hier das Makefile, das mir nach Änderungen einen Haufen Schreibarbeit spart: (habe ich eigentlich schon einmal gesagt, dass Programmierer im Grunde genommen alle ziemlich faul sind, wenn es um automatisierbare Abläufe geht? ;-)
blogroll.inc: blogroll.xsl news.opml xmlstarlet tr $^ | sed -e '1,3d' >$@
Dieser CSS-Abschnitt formatiert die Liste schliesslich:
.blogroll {
font-size: x-small;
margin-left: 0;
padding-left: 0;
}
.blogroll ul {
padding-left: 1em;
}
.blogroll li {
list-style-type: none;
}
Ich habe auch bereits versucht, die OPML-Datei direkt als XML-Datei mit einem Stylesheet zu versehen, bin dabei aber nicht ganz ans Ziel gelangt. Das Ergebnis sah immer so aus, wie wenn der Browser nur mein Stylesheet anwendet, nicht aber das default HTML-Stylesheet:

15:06 [/software/blog] blogroll Google Trackback
Mehr zum Thema DRM
BusinessWeek hat einen Artikel mit einem Interview mit Larry Lessig (Rechtsprofessor in Stanford) zur Zukunft des Internet [via Doc Searls].
Auch der Red Herring hat einen Artikel von Lessig, dieser ist Microsofts Palladium-Iniviative gegenüber—unerwarteterweise—recht positiv eingestellt.
15:06 [/allgemein] lessig_drm Google Trackback
Meine Patches für blosxom und blagg
Gestern abend habe ich meine Patches für blosxom und blagg an Rael Dornfest geschickt. Hier sind sie für die Nachwelt:
blosxom changes:
* Build the escape map and regexp only once.
* Allow the user to override the blog attributes from the blosxom.conf
file in the blog directory.
* Allow the user to define his own date and time formats. This is done
by changing the content/date and content/time templates.
* Add a save_title variable to be used in the Google search string.
* Make the default templates more accessible: The blog title is a <h1>,
dates are <h2>s, entry titles are <h3>s.
--- blosxom.orig 2002-06-04 04:59:31.000000000 +0200
+++ blosxom 2002-09-05 00:17:09.000000000 +0200
@@ -5,7 +5,7 @@
# Version: 0+4i
# Home/Docs/Licensing: http://www.oreillynet.com/~rael/lang/perl/blosxom/
-# --- Configurable variables -----
+# --- Configurable variables, may be overridden by blosxom.conf file -----
# What's my blog's title?
my $blog_title = 'Blosxom';
@@ -29,6 +29,7 @@
use FileHandle;
use File::stat;
use Time::localtime;
+use POSIX qw(strftime);
use CGI qw/:standard :netscape/;
# Take a gander at HTTP's PATH_INFO for optional blog name, archive yr/mo/day
@@ -53,6 +54,21 @@
$template{$ct}{$comp} = $txt;
}
+# Override blog attributes from a file in the blog directory
+if (-r "$datadir/blosxom.conf") {
+ $fh->open("$datadir/blosxom.conf");
+ foreach (<$fh>) {
+ $blog_title = $1 if m/^title:\s*(.*)/i;
+ $blog_description = $1 if m/^description:\s*(.*)/i;
+ $blog_language = $1 if m/^language:\s*(\w+)/i;
+ $num_entries = $1 if m/^entries:\s*(\d+)/i;
+ }
+ $fh->close;
+}
+
+my %escape = ('<'=>'<', '>'=>'>', '&'=>'&', '"'=>'"');
+my $escape_re = join '|' => keys %escape;
+
# Header
print header($content_type);
my $head = join '', $content_type eq 'text/html' && $fh->open("< $datadir/head.html") ? <$fh> : $template{$content_type}{'head'};
@@ -64,31 +80,34 @@
foreach (
sort { return -M "$datadir/$a" <=> -M "$datadir/$b"; }
grep /.txt$/, $dh->read
- ) {
+) {
last if $num_entries-- <= 0 && !$pi_yr;
my($fn) = ($_ =~ /^(.*)\.txt$/);
# Date fiddling for by-{year,month,day} archive views
- my $mtime = ctime(stat("$datadir/$fn.txt")->mtime);
- my($dw,$mo,$da,$ti,$yr) = ( $mtime =~ /(\w{3}) +(\w{3}) +(\d{1,2}) +(\d{2}:\d{2}):\d{2} +(\d{4})$/ );
+ my @mtime = @{localtime(stat("$datadir/$fn.txt")->mtime)};
+ my($yr,$mo,$da) = ($mtime[5] + 1900, $mtime[4] + 1, $mtime[3]);
next if $pi_yr && $yr != $pi_yr; last if $pi_yr && $yr < $pi_yr;
- next if $pi_mo && $mo ne ucfirst(lc $pi_mo);
+ next if $pi_mo && $mo != $pi_mo;
next if $pi_da && $da != $pi_da; last if $pi_da && $da < $pi_da;
- $content_type eq 'text/html' && $curdate ne "$dw, $da $mo $yr" &&
- print span({-class=>'blosxomDate'}, $curdate = "$dw, $da $mo $yr");
+ my $newdate = strftime($template{'content'}{'date'}, @mtime);
+ my $ti = strftime($template{'content'}{'time'}, @mtime);
+ $content_type eq 'text/html' && $curdate ne $newdate &&
+ print h2({-class=>'blosxomDate'}, $curdate = $newdate) . "\n\n";
# Entry
if (-T "$datadir/$fn.txt" && $fh->open("< $datadir/$fn.txt")) {
chomp(my $title = <$fh>);
+ my $save_title = $title;
+ $save_title =~ s/<.*?>//msg; # remove all tags
+ $save_title = escapeHTML($save_title);
chomp(my $body = join '', <$fh>);
if ($content_type eq 'text/xml') {
# Escape <, >, and &, and to produce valid RSS
- my %escape = ('<'=>'<', '>'=>'>', '&'=>'&', '"'=>'"');
- my $escape_re = join '|' => keys %escape;
$title =~ s/($escape_re)/$escape{$1}/g;
$body =~ s/($escape_re)/$escape{$1}/g;
}
@@ -105,9 +124,11 @@
# Default HTML and RSS template bits
__DATA__
-text/html head <html><head><link rel="alternate" type="type="application/rss+xml" title="RSS" href="$url/xml" /><title>Blosxom</title></head><body><center><font size="+3">$blog_title</font></center><p />
-text/html story <p class="blosxomEntry"><a name="$fn"><span class="blosxomTitle"><b>$title</b></span></a><br /><span class="blosxomBody">$body</span><br /><span class="blosxomTime">Posted at $ti</span> <a href="$url/$yr/$mo/$da#$fn">#</a> <a href="http://www.google.com/search?q=$title">G</a></p>\n
-text/html foot <p /><center><h6>Powered -- for some narrow definition of powered -- by <a href="http://www.oreillynet.com/~rael/lang/perl/blosxom/">Blosxom</a></h6></body></html>
-text/xml head <?xml version="1.0"?>\n<!-- name="generator" content="bloxsom/0+3i" -->\n<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">\n\n<rss version="0.91">\n <channel>\n <title>$blog_title</title>\n <link>$url</link>\n <description>$blog_description</description>\n <language>$blog_language</language>\n
-text/xml story <item>\n <title>$title</title>\n <link>$url/$yr/$mo/$da#$fn</link>\n <description>$body</description>\n </item>\n
-text/xml foot </channel>\n</rss>
+text/html head <html><head><link rel="alternate" type="type=application/rss+xml" title="RSS" href="$url/xml" /><title>Blosxom</title></head><body><h1>$blog_title</h1><p />
+text/html story <div class="blosxomEntry"><a name="$fn"><h3 class="blosxomTitle">$title</h3></a><span class="blosxomBody">$body</span><br /><span class="blosxomTime">Posted at $ti</span> <a href="$url/$yr/$mo/$da#$fn">#</a> <a href="http://www.google.com/search?q=$save_title">G</a></div>\n
+text/html foot <p /><center><h6>Powered -- for some narrow definition of powered -- by <a href="http://www.oreillynet.com/~rael/lang/perl/blosxom/">Blosxom</a></h6></body></html>
+text/xml head <?xml version="1.0"?>\n<!-- name="generator" content="bloxsom/0+4i" -->\n<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">\n\n<rss version="0.91">\n\n<channel>\n<title>$blog_title</title>\n<link>$url</link>\n<description>$blog_description</description>\n<language>$blog_language</language>\n
+text/xml story \n<item>\n <title>$title</title>\n <link>$url/$yr/$mo/$da#$fn</link>\n <description>$body</description>\n</item>\n
+text/xml foot \n</channel>\n\n</rss>
+content date %Y-%m-%d
+content time %H:%M
blagg changes:
* Build the unescape hash and regexp only once.
* Enter ! to blog the rest of this feed in automatic mode.
* De-emphasize the feed separator line.
* Make the parser RSS 0.94-compatible. This version uses the <guid> tag.
* The order of the title, link/guid and description tags is not defined.
Make the parser recognize this. This caught me on Mark Pilgrim's and
Dave Winer's feeds (http://diveintomark.org and http://www.scripting.com).
* Make the entry's title the link to the article, remove the "(link)".
IMO it's more intuitive to click on the title.
This change needs the related $safe_title change in blosxom.
--- blagg.orig 2002-04-30 19:13:22.000000000 +0200
+++ blagg 2002-09-04 21:24:04.000000000 +0200
@@ -38,26 +38,36 @@
# Does this blog specify any RSS feeds to watch?
$fh->open("< $datadir/rss.dat") or exit;
+my %unescape = ('<'=>'<', '>'=>'>', '&'=>'&', '"'=>'"');
+my $unescape_re = join '|' => keys %unescape;
+
+my $yn = param('-mode') eq 'automatic' ? '!!' : '';
+
# Loop through the feeds in the list and aggregate
foreach ( <$fh> ) {
my($f_nick,$f_url,$f_mode) = split;
next unless $f_nick =~ /^\w+$/ && $f_url =~ m#^\w+://# && $f_mode =~ /^(interactive|automatic)$/ && $f_mode eq param('-mode');
$fh->open("$get_prog '$f_url' |") || next;
- print "\n_____${f_url}_______________\n";
+ print "\n*** $f_url\n";
my $rss = join '', <$fh>;
$fh->close;
# Feed's title and link
my($f_title, $f_link) = ($rss =~ m#<title>(.*?)</title>.*?<link>(.*?)</link>#ms);
- # RSS items' title, link, and description
- while ( $rss =~ m{<item(?!s).*?>.*?(?:<title>(.*?)</title>.*?)?(?:<link>(.*?)</link>.*?)?(?:<description>(.*?)</description>.*?)?</item>}mgis ) {
- my($i_title, $i_link, $i_desc, $i_fn) = ($1||'', $2||'', $3||'', undef);
+ # RSS items
+ while ( $rss =~ m{<item(?!s).*?>(.*?)</item(?!s)>}mgis ) {
+
+ # Item's title, link and description
+ my $f_item = $1;
+ $_ = $1;
+ my($i_title, $i_link, $i_desc, $i_fn) = (undef, '', '', undef);
+ $i_title = $1 if $f_item =~ m{<title>(.*?)</title>}mis;
+ $i_link = $2 if $f_item =~ m{<(link|guid.*?)>(.*?)</(link|guid)>}mis;
+ $i_desc = $1 if $f_item =~ m{<description>(.*?)</description>}mis;
# Unescape & < > to produce useful HTML
- my %unescape = ('<'=>'<', '>'=>'>', '&'=>'&', '"'=>'"');
- my $unescape_re = join '|' => keys %unescape;
$i_title && $i_title =~ s/($unescape_re)/$unescape{$1}/g;
$i_desc && $i_desc =~ s/($unescape_re)/$unescape{$1}/g;
@@ -76,23 +86,22 @@
# Skip already-aggregated items (aka filename already exists)
next if -e $i_fn;
- my $item = "$i_title\n$i_desc<br />\n(" . a({-href=>$i_link},'link') . ") [" . a({-href=>$f_link}, $f_title) . "]\n";
- my $yn = '';
- if (param('-mode') eq 'automatic') {
- $yn = 'y';
- } else {
- print qq{\n"$i_title"\n[$i_link]\n$i_desc\n\nDo you want to blog this item? (y|n|q)?};
+ my $item = a({-href=>$i_link}, $i_title) . "\n$i_desc<br />\n[" .
+ a({-href=>$f_link}, $f_title) . "]\n";
+ if ($yn !~ /!/) {
+ print qq{\n"$i_title"\n[$i_link]\n$i_desc\n\nDo you want to blog this item? (y|n|q|!)?};
while (<STDIN>) {
- /^([ynq])$/ and $yn = $1, last;
+ /^([ynq!])$/ and $yn = $1, last;
};
}
$yn eq 'q' && exit;
# Save entry to file (and via plug-in if specified)
- $yn eq 'y' &&
+ $yn =~ /[y!]/ &&
$fh->open("> $i_fn") && print($fh $item) && $fh->close() &&
param('-plugin') &&
blaggplug::post($i_title, $i_link, $i_desc, $f_title, $f_link);
}
+ $yn = '' if $yn ne '!!';
}
# Clean up plugin, if specified.
15:06 [/software/blog] rael_patches Google Trackback
Ist es Zeit für einen neuen TV-Sender?
Heute abend nach unserem wöchentlichen Volleyball hatten wir eine Idee: Wie wäre es, wenn ein Sender ausschliesslich über alle Kriege berichten würde, dann hätten alle anderen Sender wieder Zeit, sich um die normale Berichterstattung zu kümmern?! In Anlehnung an EuroSport könnte er sich ja WorldWar nennen…
15:06 [/allgemein] war_tv Google Trackback
Kurze Album-URLs
In einem (vielleicht ineffektiven) Versuch, mein Album von Google & Co. besser suchbar zu machen1, habe ich heute alle URLs umgestellt: Was vorher offensichtlicherweise eine Query an den Album-Skript respektive dessen Library war, ist jetzt eine normale, “statische” URL, die von mod_rewrite in die alte Form umgewandelt wird.
Die Transformationen im einzelnen:
| Typ | alt | neu |
| Albumübersicht | /album/?album=Musik | /album/-Musik |
| Bild | /album/?album=Musik&image=bild.jpg | /album/-image/Musik/bild.jpg |
| Vorschau | /album/?album=Musik&thumb=bild.jpg | /album/-thumb/Musik/bild.jpg |
Diese Zeilen in .htaccess erledigen das (habe ich schon erwähnt, dass ich
Regular Expressions etwas vom Geilsten
in der gesamten Informatik finde? :-):
RewriteEngine On RewriteRule ^-((image)|(thumb))/(.+)/([^/]+)$ ?album=$4&$1=$5 [L] RewriteRule ^-(.+)$ ?album=$1
Bei der Syntax have ich mich von Tim Bray’s Blog beeinflussen lassen.
Nachdem dieses Regeln funktioniert hatten, war es ein Leichtes, die Album-Software und das blosxom-Plugin dazu zu bringen, anstelle der alten solche Links zu generieren.
1 Es ist eine Tatsache, dass die Crawler mit Vorliebe statische URLs durchsuchen!
15:06
[/software]
album_urls
Google
Trackback
Tags:
album
URL
searchability