Author Archives: alex

eisfair-Nostalgie

Angeregt durch eine Diskussion im IRC-Channel von eisfair, ist mir gerade klar geworden, dass ich mich jetzt schon etwa 5 (in Worten: fünf) Jahre lang mit dem System auseinandersetze. Wie hat das also damals angefangen?

Es muss irgendwann im Jahr 2003 gewesen sein, dass ich eisfair zum ersten Mal installiert und ausprobiert habe. Das Projekt selbst lief da schon einige Zeit, das Archiv der Newsgroup wurde jedenfalls im November 2001 eingerichtet. Ich hatte zu Beginn des Studiums ja noch den alten Pentium 233 MMX von meinen Eltern als Rechner benutzt, 2003 erstand ich bei eBay dann das ASUS TUSL2-C mit Celeron 1400, über das ich hier bereits schrieb. Das wurde dann Arbeitsrechner und aus den Teilen vom Basteln mit dem Fli4l-Router waren so einige Teile übrig, woraus dann ein Zweitsystem zusammengesteckt wurde. Irgendwann fand dann eisfair den Weg auf dieses Testsystem, zunächst wohl für Webentwicklung oder Spielerei oder ähnliches. Damals war noch Kernel 2.2.x Stand der Dinge (für eisfair) und es gab auch keine Install-CD. Meinen Promise Ultra 66 bekam ich erst mit dem ersten Testkernel 2.4.23 und manuellem Anlegen von /dev/hde? zum Laufen, das base-Paket war glaube ich noch bei 1.0.3 oder so.

Anfang 2004 waren ein paar Freunde für eine kleine private LAN-Party zu Besuch. Ich spielte immernoch unter Windows 98 und der eine oder andere wird sich erinnern, dass es da mit vernünftigem Multitasking, noch dazu aus nem Spiel raus, nicht soweit her war. Mal eben zum ICQ-Client wechseln und zurück gefährdete massiv die Stabilität des Spiels, warum also nicht den ICQ-Client auf dem zweiten Rechner laufen lassen? Da eisfair nun ein Serversystem ohne grafische Oberfläche ist, kamen da nicht viele Clients in Frage, genau genommen nur einer: micq.

Die damals verfügbare Version hatte Probleme mit der damals aktuellen Version vom ICQ-Protokoll und so fragte ich den damaligen Maintainer vom micq-Paket, Roman Schließmeyer, nach einem Update:

ich habe im Moment leider keine Zeit um die Pakete zu pflegen, deswegen werde ich auch kein Update des micq Paketes durchführen. Wenn du magst kannst du das gerne übernehmen,

So kam dann eins zum anderen und am 12.04.2004 veröffentlichte ich mein micq-Paket in Version 1.0.1. Warum? Eigenbedarf! Genau darum ging es nämlich im eingangs erwähnten Chat. Eine der größten Antriebskräfte im Open-Source-Bereich ist Eigenbedarf. Das gilt für meine eisfair-Pakete ebenso wie für IMPULS und es gilt nicht nur für mich selbst. Viele Open-Source-Entwickler arbeiten an »ihrer« Software, weil sie sie selbst einsetzen und benutzen wollen. Natürlich ist das nicht der einzige Grund, aber ein sehr wichtiger, das sehe ich bei eisfair im Prinzip täglich. Das Zitat zeigt aber auch noch etwas anderes: eisfair ist ein reines Freizeitprojekt und Zeitmangel ist bei den Entwicklern praktisch obligatorisch – damals wie heute.

Ende 2005 bekam ich dann die Einladung dem frisch gegründeten Test-Team beizutreten, im letzten Jahr war ich zum ersten Mal auf dem Entwicklertreffen. Seit 2003 ist viel passiert in der Entwicklung, ich hatte ja schon an der einen oder anderen Stelle mal was angedeutet. Da ließe sich auch noch viel mehr schreiben, aber das hebe ich mir mal für einen späteren Beitrag auf. ;-)

Schicke Grafiken in LaTeX mit pgfplots (2)

Ich hatte im Beitrag »Schicke Grafiken in LaTeX mit pgfplots (1)« noch ein zweites Beispiel angekündigt. Diesmal zeige ich wie man mit pgfplots eine Grafik mit horizontalen Balken baut. Als Grundlage dient die Grafik aus einem Paper mit dem Titel »Concrete-based constrained layer damping«. Das Original sieht bereits im Original verpixelt aus:

Mit PGF bzw. besser gesagt mit TikZ lässt sich das nachbauen. Box, Anstriche, Beschriftungen und Balken müssen aber alle komplett von Hand erstellt werden.

begin{tikzpicture}[xcomb,thick]
    % die balken
    draw[color=gray,line width=10pt]
        plot coordinates{(0.75,0.5) (1.125,1) (7.5,1.5) (5.4,2)
        (6,2.5) (0.3,3) (0.05,3.5)};
    % box (rechteck) außen rum
    draw (0,0) rectangle (9,4);
    % die achsenbeschriftung links
    foreach y/ytext in {0.5/mild steel, 1/cast iron, 1.5/granite,
        2/polymer concrete, 2.5/lead, 3/6063 aluminium, 3.5/alumina}
        draw (-2pt,y cm) node[anchor=east] {footnotesizeytext};
    % anstriche für die achse unten
    draw (0,0) -- (-2pt,0);
    foreach x in {0,0.75,...,9}
        draw (x cm,0) -- (x cm,-2pt);
    % achsenbeschriftung unten
    foreach x/xtext in {0/0.000, 1.5/0.001, 3/0.002, 4.5/0.003,
        6/0.004, 7.5/0.005, 9/0.006}
        draw (x cm,-2pt) node[below] {footnotesizextext};
end{tikzpicture}

Das Ergebnis ist schon recht ansprechend, es werden die LaTeX-Schriften verwendet und es ist eine saubere Vektorgrafik:

Mit pgfplots muss man nicht alle Einzelheiten selbst nachbauen sondern definiert im Grunde nur noch Labels und Werte.

begin{tikzpicture}
    begin{axis}[
        xbar,
        width=10cm,
        height=6cm,
        ytick={1,...,7},
        yticklabels={%
            mild steel,
            cast iron,
            granite,
            polymer concrete,
            lead,
            6063 aluminium,
            alumina},
        xmin=0,
        xmax=0.006
    ]
    addplot[draw=darkblue,fill=blue!50!white,semithick] coordinates {
        (4.5e-4,    1)
        (7.5e-4,    2)
        (5e-3,      3)
        (3.6e-3,    4)
        (4e-3,      5)
        (2e-4,      6)
        (3e-5,      7)
    };
    end{axis}
end{tikzpicture}

Da ist erstens der Quelltext übersichtlich und verständlich und das Ergebnis überzeugt ebenso:

Mehr Text gibt’s dann ein ander Mal wieder, ich denke die Code-Beispiele und Bildchen sprechen für sich. ;-)

Schicke Grafiken in LaTeX mit pgfplots (1)

Vor einiger Zeit hatte ich im Beitrag Schicke Grafiken aus Matlab in LaTeX Möglichkeiten ausgelotet aus mit Matlab erzeugten Daten schicke Plots in LaTeX zu generieren. Sehr vielversprechend war dort das Paket pgfplots bei dem sich in den letzten Monaten einiges getan hat. Es liegt mittlerweile in Version 1.1 vor und hat neben dem Einbinden externer Datenquellen noch so manches dazugelernt. Ich möchte in diesem und einem folgenden Artikel an zwei Beispielen zeigen, wie man mit pgfplots tolle Ergebnisse produzieren kann.

Zunächst bleiben wir bei Matlab. Aus Matlab heraus ist es vergleichsweise einfach das .table-Format zu erzeugen, aus dem pgfplots Werte einlesen kann. Im einfachsten Fall benutzt man die Funktion dlmwrite. Will man auch noch Header und Kommentarzeilen in das Zwischenformat packen, muss man bisschen mehr Aufwand betreiben, ein entsprechendes Skript ist aber in kurzer Zeit fertiggestellt und bleibt dem geneigten Leser als Hausaufgabe überlassen. ;-) Meine Datei dahl_2008-08-19_05.table beginnt jedenfalls wie folgt:

time datadownsampled datadecimated dataresampled impactdownsampled impactdecimated impactresampled
7.2 0.0042314 0.0031181 0.0017701 7.6889e-005 7.5995e-005 4.3056e-005
7.201 0.010326 0.0048359 0.0049109 8.081e-005 8.0715e-005 8.7923e-005
7.202 0.013369 -0.0069568 -0.006471 7.9993e-005 8.087e-005 7.8394e-005
7.203 -0.011055 -0.010981 -0.011697 6.9248e-005 7.0035e-005 7.2734e-005

Es folgen knapp fünfhundert weitere Zeilen. Wie man bereits am Header sieht ist es empfehlenswert ein Downsampling der zu plottenden Daten vorzusehen, wenn eine Datenreihe mehr als ein paar hundert Elemente enthält. Diese spezielle Datei enthält in der ersten Spalte die Zeit, in den Spalten zwei bis vier ein Signal und in den Spalten fünf bis sieben ein zweites Signal. Für beide Signale wurden je drei verschiedene Downsampling-Verfahren ausgetestet, das jedoch nur nebenbei und zur Erläuterung, für den Plot werde ich nur die Spalten time und datadownsampled nutzen.

In LaTeX-Dokument sollten die notwendigen Pakete geladen sein, in diesem Fall sieht das bei mir so aus:

usepackage{tikz}
usepackage{pgfplots}
pgfplotsset{every axis plot/.append style={very thick}}

Die Einbindung selbst erfolgt wie gewohnt in einer float-Umgebung, die das ganze zentriert und auch noch label und Bildunterschrift bereit stellt. Statt includegraphics fügt man aber einfach eine tikzpicture-Umgebung ein:

begin{figure}[htb]
	centering
	begin{tikzpicture}
		begin{axis}[
			xlabel=Zeit (s),
			ylabel=Kraft (N),
			width=12cm,
			height=8cm]
		addplot[smooth,color=blue]
			table[x=time,y=datadownsampled] {plots/dahl_2008-08-19_05.table};
		end{axis}
	end{tikzpicture}
	caption{Rohdaten Messung texttt{dahl_2008-08-19_05}}
	label{fig:rohdaten_dahl_2008-08-19_05.txt}
end{figure}

Wichtig für das Lesen aus der externen .table-Datei ist die Anweisung table in der Zeile beginnend mit addplot. Das Ergebnis ist eine Vektorgrafik. Die Achsen sind wunderbar mit der im restlichen LaTeX-Dokument verwendeten Schrift beschriftet und zwar immer in der richtigen Größe. Mit extern als .eps oder ähnlichen Formaten eingebundenen Grafiken ist so etwas kaum möglich. Das Ergebnis spricht für sich:

Tiefenanordnung von Linien in Matlab-Plots

Heute geht es mal um ein sehr spezielles Problem mit einer Lösung auf die ich gestern durch Probieren gekommen bin und sehr erstaunt war, dass das so funktioniert und offenbar sogar so vorgesehen ist. Zunächst ein paar Worte zum ursprünglichen Problem.

Ich arbeite im Institut mit Matlab 6.1, zwar schon etwas in die Jahre gekommen aber brauchbar. Für die Auswertung meiner Messdaten habe ich ein GUI programmiert wo ich zwei verschiedene Sachen gleichzeitig in einem axes-Objekt darstellen will. Normalerweise kann man hier mit den Funktionen hold und plot arbeiten, aber mir war das zu unflexibel und ich habe daher gleich die LowLevel-Funktionen benutzt. Ich habe in dem GUI das gewünschte axes-Objekt. Direkt darunter in der Objekthierarchie kommen bereits die line-Objekte, die auch plot erzeugt. Von Hand kann man sich die mit dem Befehl line erzeugen, die landen dann in dem aktuellen axes-Objekt, das man zuvor mit axes(axeshandle) festlegen sollte. Bei der Erzeugung der line-Objekte speichere ich das line-Handle um später direkt wieder drauf zugreifen und beispielsweise die zugrundeliegenden Daten ändern zu können.

Soweit so gut, nun ist es so, dass ich nicht bestimmen kann, wann der Benutzer die eine Sache zum Plotten anklickt und wann die andere. Oben erscheint aber immer die zuletzt gewählte. Genauso verhält sich der Befehl plot. Was zuerst geplottet wird, landet hinten, die nachfolgenden Sachen darüber. Das ist bei vielen Darstellungen egal, bei einigen aber nicht.

Der Trick um die Darstellungsreihenfolge – oder englisch z-Order – zu ändern klingt ein wenig wie »von hinten durch die Brust ins Auge«, funktioniert aber wunderbar. Um zu verstehen, was dort gemacht werden muss, schaut man sich am besten nochmal die Objekthierarchie an. Ein axes-Objekt beherbergt beliebig viele line-Objekte. Die Handles dieser Objekte kann man sich ausgeben lassen:

linehandles = get(gca, 'Children')

Die einzelnen Elemente des Vektors linehandles haben genau die Reihenfolge der Anordnung in z-Richtung wobei das erste Element das zu oberst angezeigte ist. Es spricht nichts dagegen, die Elemente umzuordnen und dem axes-Objekt wieder zuzuweisen, z.B. in umgekehrter Reihenfolge:

set(gca, 'Children', flipud(get(gca, 'Children')))

Ich war einigermaßen überrascht, dass das tatsächlich so funktioniert, da ich in der ausführlichen Matlab-Hilfe nie darüber gestolpert bin. Dass das wirklich so vorgesehen ist, sagt einem Matlab selbst, wenn man versucht der Eigenschaft Children etwas anderes als ein umgeordnetes selbst zuzuweisen:

??? Error using ==> set
Children may only be set to a permutation of itself.

Damit das ganze noch ein wenig anschaulicher wird, habe ich noch ein kleines Skript geschrieben, dass die Sache nochmal illustriert:

% test data
a = rand(5,1)
b = rand(5,1)
c = rand(5,1)
% line handles
hp = plot([a b c])                  % hp in order we plotted
ha = get(gca, 'Children')           % reverse order
% vectors of line handles equal?
all(hp==ha)                         % not equal
all(hp==flipud(ha))                 % should be equal, see above
all(sort(hp)==sort(ha))             % also equal
% thick lines
set(ha, 'LineWidth', 10)
title('original order')
legend('a','b','c')                 % order as in plot call
print(gcf, '-dpng', 'z-order-original.png')
% color of the most front line, should be c
get(ha(1), 'Color')                 % should be red aka [1 0 0]
% now flip lines, put c in the back
set(gca, 'Children', [ha(2) ha(3) ha(1)])
title('flipped order')
print(gcf, '-dpng', 'z-order-flipped.png')
% color of the most front line, should be b
ha = get(gca, 'Children')
get(ha(1), 'Color')                 % should be green aka [0 0.5 0]

Schaut man sich hier die erzeugten PNG-Bilder an, erkennt man, dass die Linie für die Datenreihe c zunächst ganz vorn und dann ganz hinten dargestellt wird:

Alte Revisionen wiederherstellen mit Subversion

Im täglichen Umgang mit Subversion passiert es, dass man Dateien eincheckt, die man dann doch eigentlich nicht commiten wollte. Zum Glück kann man alte Revisionen wiederherstellen, dafür hat man ja das Versionsverwaltungssystem, man muss nur wissen wie.

Die erste Idee: revert – das funktioniert nicht, weil revert nur Änderungen an der lokalen Working Copy rückgängig macht, nach dem Commit kann revert nichts mehr ausrichten.

Die zweite Idee: update auf die ursprüngliche Version. Dann hat man in der Working Copy zwar zunächst mal die alte Version liegen. Man kann sie aber nich direkt commiten, weil Subversion sie für aktuell hält. Das ist sie im Grunde auch, nur halt in einer vorherigen Revision. Lokale Änderungen gibt es in dem Sinne nicht an der Datei. Bei Binärdateien kommt man an dieser Stelle nicht weiter, wenn man nicht jedesmal wieder ein update auf die alte Revision machen will.

Die dritte Idee: ins Handbuch schauen. Das exzellente Subversion-Buch hat natürlich auch zu dieser Problematik die passenden Tipps parat: Undoing Changes. (Wir arbeiten hier noch mit Subversion 1.4, daher der Link ins »alte« Buch.) Was auf den ersten Blick überraschend klingt: merge ist die Lösung für das Problem. Der Trick ist, dass wir dieses Mal rückwärts mergen. Dadurch gelangt die ältere Revision wieder in die Working Copy und nachdem man kontrolliert hat, ob damit alles stimmt, kann man die erneut commiten.

Genug der Vorrede, ich zeige den Vorgang mit dem Kommandozeilen-Client und mit TortoiseSVN am Beispiel. Ich habe hier eine Binärdatei driftcompgui.fig, die ich zuletzt in Revision 297 korrekt eingecheckt habe. In Revision 300 habe ich versehentlich eine falsche Version der Datei eingecheckt und möchte jetzt wieder die Version aus Revision 297 haben. Auf der Kommandozeile sieht das recht einfach aus (mit anschließendem Screenshot der Ausgaben):

svn merge -c -300 driftcompgui.fig

Wie man sieht liegt die Datei nun geändert in der Working Copy und zwar in der gleichen Version wie in Revision 297. Jetzt kann man die so einchecken oder noch weiter damit arbeiten. Bei TortoiseSVN erschließt sich diese Funktion aus dem GUI eher überhaupt nicht. Ich zeige zunächst mal den entscheidenden Screenshot und erkläre dann nochmal:

Hier wählt man zunächst im Feld »From:« die gewünschte Datei aus und klickt »HEAD Revision« an. Das ist sozusagen der Startpunkt des Rückwärts mergens. Bei »To:« natürlich »Use “From:” URL« auswählen, da es um die selbe eine Datei geht. Als Ziel Revision gibt man hier die an, die man wiederherstellen will, in meinem Fall 297. Jetzt kann man ohne weiteres auf »Merge« klicken und dann die Datei in der Working Copy untersuchen. Sollte irgendetwas nicht stimmen, kommt man mit revert wieder zur HEAD Revision, da wie bei jedem anderen Merge kein automatischer Commit passiert sondern die Änderungen des merge nur in der Working Copy landen. Wenn alles ok ist, kann man commiten und hat danach wieder die alte Version der Datei im HEAD des Repository.

Keys für Upgrade auf WordPress 2.6

Gestern kam mal wieder ein neues Update für WordPress. Wir setzen hier die DE-Edition ein und da gibt es auch eine detaillierte Anleitung zum Upgrade. Dort wird einem verraten, dass es für WordPress 2.6 neue Variablen in der Datei wp-config.php gibt. Der entsprechende Abschnitt in der wp-config-sample.php sieht so aus:

// Ändere jeden SECRET_KEY in eine beliebiege, möglichst einzigartige Phrase. Du brauchst dich später
// nicht mehr daran erinnern, also mache sie am besten möglichst lang und kompliziert.
// Auf der Seite https://www.grc.com/passwords.htm kannst du dir einen Ausdruck generieren lassen.
// Bitte trage für jeden SECRET_KEY eine eigene Phrase ein.
define('AUTH_KEY', 'put your unique phrase here'); // Trage hier eine beliebige, möglichst zufällige Phrase ein.
define('SECURE_AUTH_KEY', 'put your unique phrase here'); // Trage hier eine beliebige, möglichst zufällige Phrase ein.
define('LOGGED_IN_KEY', 'put your unique phrase here'); // Trage hier eine beliebige, möglichst zufällige Phrase ein.

Jetzt ist da eine Seite angegeben, auf der man sich diese Keys erzeugen lassen kann. Das ist für den DAU ganz nett, aber schrieb nicht fefe gerade die Tage:

Man sollte denken, niemand könnte je so unglaublich dämlich sein, sich einen Krypto-Schlüssel von jemand anderem generieren zu lassen

Glücklicherweise gibt es ja noch mehr Möglichkeiten zufällige Zeichenketten zu erzeugen. Eine davon habe ich vor einigen Monaten im Beitrag Kleiner Passwortgenerator in Perl vorgestellt. Was der Beitrag verschweigt: Ich hatte wenige Tage später noch eine kleine Anpassung an dem Skript vorgenommen, die es erlaubt, beim Aufruf die Anzahl der zurückzugebenden Zeichen als Parameter zu übergeben. So war es ein leichtes die nötigen Keys für die Konfigurationsdatei von WordPress zu generieren:

perl genpasswd.pl 64

Das veränderte Skript ist jetzt übrigens auch über Penguineering Tools abrufbar.

Security by Obscurity

Im April hatte ich über die Sicherheitslücke in Chipkarten des Typs Mifare Classic geschrieben, die auch als Studentenausweis an der Uni Magdeburg dienen. Der Hersteller InterCard hatte Anfang April angekündigt sich zügig mit seinen Kunden in Verbindung zu setzen. Davon hat man hier an der Uni bisher nichts gemerkt.

Unabhängig davon ist heute bekannt geworden, dass NXP, der Hersteller der Chips, eine niederländische Universität verklagt hat, damit die keine Paper zu der Thematik veröffentlichen. Fefe schreibt dazu:

Das sagt mir persönlich ja immer alles, was ich über eine Firma wissen muß, wenn die ihre Sicherheitslücken nicht fixen und dazu stehen sondern den Boten unter Beschuß nehmen.

Ich frage mich, wie die sich das vorstellen. Die Niederländer sind ja lange nicht die einzigen, die Details zu der Sicherheitslücke veröffentlicht haben. Da gab’s einen Vortrag auf dem 24C3, die c’t hat lang und breit drüber berichtet und all diese Informationen sind seit über einem halben Jahr öffentlich, lange genug Zeit also für böse Buben sich da schlau zu machen und das Wissen zu speichern. Viel interessanter ist die Frage, wie sie die bestehenden Systeme absichern oder auf neue Systeme migrieren wollen. Wäre glatt mal interessant beim hiesigen Studentenwerk anzufragen, ob der Hersteller schon Kontakt aufgenommen hat und was da möglicherweise hinsichtlich neuer Karten o.ä. geplant ist.

Homepage mit trac 0.10.x

Wir arbeiten ab und zu an IMPULS. Anfang des Jahres sind wir mit dem Subversion-Repo hier nach antiblau gezogen und benutzen jetzt Trac anstelle des Bugtracking-Systems von Sourceforge. Trac bietet neben Repository Browser, Bug Tracker und Milestone-Verwaltung auch ein Wiki. Andere Projekte wie z.B. Licq oder lcd4linux haben ihre ganze Homepage mit Trac realisiert. Da sich ein Wiki ganz gut eignet um unabhängig von HTML-Editor, PHP-Kenntnissen etc. so eine Seite aktuell zu halten, beschloss ich die Homepage für Impuls auch mit dem sowieso schon genutzten Trac zu verwirklichen.

Die größte Hürde für eine sinnvolle Nutzung von Trac als Homepage stellt die Navigation dar. Im Wiki selbst sind mehr oder weniger nur Sprünge von Seite zu Seite möglich, eine einheitliche Navigation, beispielsweise über eine Sidebar ist so zunächst nicht vorgesehen. Dass das irgendwie möglich ist, sieht man bei Licq, also hab ich mir angeschaut, wie man das mit den Paketen von Debian Etch sinnvoll umsetzen kann, dort wird Trac in Version 0.10.x verwendet also noch vor der Umstellung der Template-Engine mit der 0.11.x.

Das Prinzip ist eigentlich ganz einfach: Trac an geeigneter Stelle in irgendeinem HTML-Template einen neuen div-Container unterschieben mit beliebiger Id und anhand dieser Id dann ein passendes CSS Stylesheet bauen. In diesem Fall haben wir in /usr/share/trac/templates/header.cs eine Zeile eingefügt:

<div id="mainnav" class="nav"><?cs call:nav(chrome.nav.mainnav) ?></div>
<?cs include "site_navi.cs" ?>
<div id="main">

Das hat den Vorteil, dass jede neue Trac-Installation von der Änderung erstmal nichts mitbekommt. Die Datei site_navi.cs muss im jeweiligen Trac-Projekt-Ordner angelegt werden, um in den Genuss der Navi-Sidebar zu kommen. Konkret geschieht dies im Unterordner templates des Trac-Projektordners, da wo z.B. auch die Dateien site_header.cs und site_footer.cs liegen. Die Datei site_navi.cs enthält dann den Inhalt der Sidebar, im Fall der IMPULS-Homepage sieht das so aus:

<?cs
####################################################################
# Site header - Contents are automatically inserted above Trac HTML
?>
<div id="left">
    <div id="navi1">
        <ul>
            <li><a href="http://www.impuls-toolset.org/trac/wiki">Start</a></li>
            <li><a href="http://www.impuls-toolset.org/trac/roadmap">Roadmap</a></li>
            <li><a href="http://www.impuls-toolset.org/trac/wiki/Toolset">Toolset</a></li>
            <li><a href="http://www.impuls-toolset.org/trac/wiki/MailingLists">Mailing lists</a></li
            <li><a href="http://www.impuls-toolset.org/trac/wiki/FrequentlyAskedQuestions">F.A.Q.</a
            <li><a href="http://www.impuls-toolset.org/trac/wiki/Download">Download</a></li>
            <li><a href="http://www.impuls-toolset.org/trac/wiki/Development">Development</a></li>
            <ul>
                <li><a href="http://www.impuls-toolset.org/trac/wiki/ProjectConventions">Project con
                <li><a href="http://www.impuls-toolset.org/trac/wiki/ProtocolSpecification">Protocol
            </ul>
        </ul>
    </div>
</div>

Fehlt noch das passende Stylesheet, dazu sind noch folgende Änderungen nötig. Zunächst eine Anpassung der Datei site_css.cs, die im gleichen Projektordner liegt:

<?cs
##################################################################
# Site CSS - Place custom CSS, including overriding styles here.
?>

@import url(<?cs var:chrome.href ?>/site/style.css);

Wie man sieht wird hier eine Stylesheetdatei eingebunden. In dieser wird dann das angepasste Stylesheet definiert. Die Datei style.css liegt ebenfalls im Trac-Projektordner und zwar im Unterordner htdocs. Im Falle der Impuls-Homepage hat sie folgenden Inhalt:

#left {
	float: left;
	width: 13em;
	margin-bottom: 1em;
	margin-top: 1em;
}

#navi1 {
	color: #000000;
	background-color: #EEE5E6;
	padding: 0em 0.5em 0em 0.8em;
	margin: 0em 0em 1em 0em;
	border: 1px solid #A8071C;
}

#navi1 ul {
	margin-left: 1em;
	padding: 0;
}

#main {
	margin-left: 14em;
}

#altlinks {
	clear: right;
}

table.listing {
	clear: right;
}

#preview {
	clear: right;
}

#help {
	clear: right;
}

#info {
	clear: none;
}

@media print {
    #left { display: none; }
    #main { margin-left: 0em; }
}

Damit sich die Sidebar harmonisch einfügt sind auch einige kleine Hacks an den bereits vorhandenen Elementen der Seite nötig, speziell die clear:right, damit der eigentliche Inhalt sauber neben und nicht unter die Sidebar gesetzt wird.

Was man in der Sidebar dann letztendlich verlinkt, bleibt jedem selbst überlassen. Im Falle von Impuls wollte ich eigentlich eine sehr flache Hierarchie haben, ist mir nicht ganz gelungen. Ansonsten genügt es für weitere Änderungen die beiden Dateien style.css und site_navi.cs zu bearbeiten. Mit einem möglichen Update auf Trac 0.11.x wird das ganze dann aber sehr wahrscheinlich nicht mehr funktionieren, weil dort keine Clearsilver-Templates mehr benutzt werden. Wenn es soweit ist, müssen wir mal schauen, wie wir das dann umsetzen.

Bilder automatisch drehen

Wir waren am Wochenende unterwegs und hatten die Kamera meiner Freundin dabei, eine Canon PowerShot S3 IS. Das ist jetzt soweit nichts besonderes. Man knipst Bilder, kopiert die später von der Speicherkarte auf den Rechner und dann ist der erste Schritt: Hochkant geschossene Bilder drehen. Auch das ist kein Problem. Die Kamera hat ja einen Lagesensor drin und speichert die Ausrichtung in den EXIF-Daten jedes einzelnen Bildes. XnView dreht die Bilder dann dank verlustfreier JPEG-Transformation in die richtige Lage. Wenn das alles so einfach und problemlos ist, warum kann die Kamera das nicht schon selbst machen? Der Bildprozessor, der da drin steckt, sollte leistungsfähig genug sein. Hab ich nur irgendwo eine Option in den Menüs der Kamera übersehen, oder geht das wirklich nicht? Gibt es andere Kameras, die das können und machen?

eisXen und eisfair-2 auf dem Weg

Nachdem ich gerade auf eisfair.org die Ankündigung gelesen habe, dass die Release Candidates von eisXen und eisfair-2 offiziell veröffentlicht wurden, kann ich ja hier auch ein wenig drüber plaudern. Die wichtigsten Weichen wurden ja bereits im November gestellt und einige kleinere Punkte sind auch noch offen, aber wir haben gerade eisXen in den letzten Wochen um einiges voran gebracht und ich freue mich, dass es jetzt im Rahmen des LinuxTag 2008 endlich der weiten Welt vorgestellt wird. Da es »nur« ein RC ist, hätte ich die Wette mit Tux Weihnachten 2007 zwar immernoch verloren, aber ich denke mit dem Input von den Nutzern wird das Projekt jetzt wieder Fahrt aufnehmen. Die Entwicklungsumgebung für eisfair-2 ist auch fast fertig, so dass dann auch bald die Pakete folgen werden.