diff options
Diffstat (limited to 'source/00_content')
22 files changed, 361 insertions, 0 deletions
diff --git a/source/00_content/articles/2010-02-06_debian_auf_dem_sheevaplug.md b/source/00_content/articles/2010-02-06_debian_auf_dem_sheevaplug.md new file mode 100644 index 0000000..df98769 --- /dev/null +++ b/source/00_content/articles/2010-02-06_debian_auf_dem_sheevaplug.md @@ -0,0 +1,47 @@ +# Debian auf dem SheevaPlug + +Auf dem herkömmlichen [Weg](http://www.cyrius.com/debian/kirkwood/sheevaplug/) ist es zwar möglich ein Debian auf dem SheevaPlug zu installieren, jedoch nur auf einem externen USB-Stick oder auf einer SD-Karte. Die Installation auf dem 512MB großen internen Flashspeicher des Plugs ist damit nicht möglich. Es gibt jedoch einen Weg um Debian auch im internen Speicher zu installieren, der auch noch um einiges komfortabler als der oben verlinkte Weg ist. + +Als erstes laden wir uns den normalen SheevaInstaller herunter mit dem man Ubuntu 9.04 auf dem Sheeva installieren kann ([klick](http://www.plugcomputer.org/index.php/us/resources/downloads?func=select&id=5)). Nach dem wir den Tarball heruntergeladen haben sollte man ihn entpacken. Als nächstes laden wir ein Debian Lenny / Squeeze Prebuild von [hier](http://www.mediafire.com/sheeva-with-debian) herunter. Nun ersetzen wir die „rootfs.tar.gz“ mit der neuen Debian „rootfs.tar.gz“. Bevor wir jedoch mit der Installation beginnen müssen wir die neue „rootfs.tar.gz“ mit „tar“ entpacken. Dazu führen wir auf der Konsole + + mkdir rootfs + cd rootfs + tar xfvz rootfs.tar.gz + +aus. In dem Ordner führen wir nun ein + + mknod -m 660 dev/ttyS0 c 4 64 + +aus. Mit diesem Befehl wird die fehlende serielle Konsole erstellt. Jetzt verpacken wir das Archiv wieder mit + + tar cfvz ../rootfs.tar.gz * + +Den gesamten Inhalt des Ordners /install im SheevaInstaller-Verzeichniss müssen wir jetzt auf einen mit FAT formatierten USB-Stick kopieren. Diesen stecken wir schon einmal in den USB-Port des Sheevas. Als nächstes verbinden wir den SheevaPlug mit einem Mini-USB Kabel mit unserem Computer und führen das Script „runme.php“ aus. Wenn alles klappt wird nun ein neuer Boot-Loader und das rootfs auf den Plug kopiert. Dannach ist unser Debian einsatzbereit. +Sollte der Plug den USB-Stick nicht erkennen und somit auch das rootfs nicht kopieren können hilft es einen anderen USB-Stick zu verwenden. Beispielsweise wurde mein SanDisk U3 Stick trotz gelöschtem U3 nicht erkannt. Mit einem anderen Stick funktionierte es jedoch tadelos. Auch sollte der Stick partitioniert sein. Der Bootloader des SheevaPlugs kann nicht gut mit direkt auf dem Stick enthalten Dateisystemen umgehen. Wenn die MiniUSB Verbindung beim Ausführen des runme-Scripts nicht funktionieren sollte hilft oft ein + + rmmod ftdi_sio + +und + + modprobe ftdi_sio vendor=0x9e88 product=0x9e8f + +(beides als root). Ebenfalls sollte kein zweites Serielles-Gerät am Computer angeschlossen sein. +Bei neueren Plugs kann man bei Problemen bei der Installation die Datei „uboot/openocd/config/interface/sheevaplug.cfg“ im SheevaInstaller-Ordner nach + + interface ft2232 + ft2232_layout sheevaplug + ft2232_vid_pid 0×0403 0×6010 + #ft2232_vid_pid 0x9e88 0x9e8f + #ft2232_device_desc “SheevaPlug JTAGKey FT2232D B” + jtag_khz 2000 + +umändern. +Wenn Debian jetzt auf dem SheevaPlug läuft und man sich über SSH einloggen konnte (pwd: nosoup4u), sollte man als erstes ein Update machen. + + apt-get update && apt-get dist-upgrade + +Über die Paketverwaltung kann man jetzt ganz einfach die benötigte Software installieren. Ich setzte auf meinem Plug z.B. lighttpd als Webserver mit PHP5 und MySQL für diese Website ein. Es empfielt sich /var und /tmp auszulagern um Löschzyklen zu sparen. Für /tmp eignet sich eine ramdisk. + +### Erfahrungen + +Ein Debian ist eine gute Alternative zu dem vorinstallierten Ubuntu 9.04. Denn dieses wirft Fehler bei booten aus und hat anfangs Konfigurationsprobleme. Auch braucht es im Vergleich zum Debian eine Ewigkeit zum booten. Das mag bei einem Server nicht wichtig sein, aber ich finde es dennoch schön schnell rebooten zu können. Das gute ist, dass man wenn man schon Erfahrung mit Ubuntu hat auch sehr gut mit Debian zurechtkommt. Aber Ubuntu Karmic lässt sich leider nicht mehr auf dem SheevaPlug installieren. Der SheevaPlug ist erstaunlich schnell. Er erstellt die Seiten etwa doppelt so schnell wie die Server des vorher von mir verwendeten Gratishoster “bplaced.net”. Auch hat er einen sehr geringen Stromverbrauch von nur 5 Watt. Und selbst wenn Webhostingangebote zumindest in der Internetanbindung schneller sein mögen, hat man mit einem SheevaPlug einen sehr günstigen Root-Server, auf dem man tun und lassen kann was man will. diff --git a/source/00_content/articles/2010-03-16_erfahrungen_mit_dem_sheevaplug_im_laengeren_einsatz.md b/source/00_content/articles/2010-03-16_erfahrungen_mit_dem_sheevaplug_im_laengeren_einsatz.md new file mode 100644 index 0000000..2e2369e --- /dev/null +++ b/source/00_content/articles/2010-03-16_erfahrungen_mit_dem_sheevaplug_im_laengeren_einsatz.md @@ -0,0 +1,22 @@ +# Erfahrungen mit dem SheevaPlug im längeren Einsatz + +Da ich den SheevaPlug ja jetzt schon seit längerer Zeit einsetze und auch dieses Blog auf ihm gehostet ist, will ich jetzt einmal über meine Erfahrungen mit dem Einsatz des SheevaPlugs über längere Zeit als Webserver berichten. + +Der SheevaPlug ist wirklich stabil und läuft ohne Probleme mit Debian Lenny. Als Webserver setze ich, wie schoneinmal geschrieben Lighttpd ein. Apache2 läuft zwar auch einwandfrei, jedoch ist die Erstellungszeit der Seiten mit PHP bei Lighttpd doch noch etwas schneller. Auch ist der Speicherverbrauch im RAM merklich geringer, was bei den 512 MB Ram des Plugs doch ganz nett ist. + +Als Datenbankserver verwende ich MySQL, welches zwar doch eine ganz schöne größe auf dem NAND-Speicher hat aber wirklich gut funktioniert. Zur Verwaltung der Datenbanken verwende ich phpMyAdmin. Auch das läuft wirklich zufriedenstellend und schnell übers Netzwerk. + +Da ich mit den Schreibzyklen und der Kapazität des NANDs möglichst sparsam umgehen möchte, habe ich /var komplett auf eine SD-Karte ausgelagert. Der SD-Reader ist schnell genug, nur wäre es schön, wenn die Karte irgendwie einrasten würde, da sie beim versehentlichen Verschieben des Plugs gerne herausrutscht. Jedoch bereue ich es mittlerweile, dass ich nicht das komplette System auf eine SD-Karte ausgelagert und im NAND nur ein Backup-OS belassen habe, da man mit nur 462 MB nicht wirklich viel machen kann. Auch steigt die Datenmenge im Speicher während der Plug läuft “zufällig” an. Er wird über die Wochen immer voller und kraxelt gemütlich den 65% entgegen (zumindest kann ich keine bestimmte Aktion meinerseits damit verbinden). Hat einer von euch eventuell eine Idee woran das liegen könnte? + +Auch verursacht der MySQL-Server in ebanfalls ungleichen Abständen eine 100%ige CPU-Auslastung, ich kann daraufhin nurnoch mit SSH und nicht mer über den Webserver auf den Plug zugreifen. Das abschießen von MySQL und auch ein reboot funktionieren nicht. Gebe ich “reboot” als root ein, werden zwar entsprechende Meldungen ausgegeben, rebooten tut der PlugComputer jedoch nicht (dann hilft nurnoch der harte Weg – Strom weg). Es ist so wirklich kein guter Zustand, sollte ich einmal für mehrere Tage keinen HW-Zugriff auf den SheevaPlug haben und es würde wieder anfangen, könnte ich nichts machen um den Fehler zu beheben. Hat auch zu diesem Problem (das vllt. nicht unbedingt am Plug, sondern auch an einer Fehlkonfiguration von mir liegt) vielleicht einer von euch eine mögliche Lösung parat? + +Das Netzwerkinterface des Plugs ist für mich ausreichend schnell (macht bei dem mageren DSL 2000 eh nichts aus), so wie es aussieht ist das einzige was wirklich ausbremst die Schreib- und Lesegeschwindigkeit des Speichers. Für einen Webserver reicht es jedoch ohne Probleme, nur zum Sichern der Backups könnte es schneller sein. + +Im Betrieb wird der Plug nur Handwarm, das einzige was man vllt. verbessern könnte wäre das störende Blinken des Netzwerkanschlusses. Damit könnte man den Energieverbrauch sicher noch ein wenig weiter senken, denn der Plug ist wirklich festlich beleuchtet. Sitzt man im dunkeln direkt daneben, kann das Blinken und Leuchten wirklich stören. +Die 1.2 Ghz der CPU reichen gut aus, schneller muss es für einen Webserver bei nicht explodierenden Besucherzahlen nicht sein (wobei das Problem vorher eher die Netzwerkanbindung nach außen wäre, aber für solche Belastungen ist der Plug ja auch nicht gebaut). + +Noch etwas zu den Anwendungen die ich auf dem SheevaPlug einsetze: WordPress für diesen Blog, Piwik um euch zu überwachen und phpMyAdmin für die Datenbanken. Ebenfalls läuft Dovecot als IMAP-Server in dem die Mails meiner verschiedenen Postfächer per fetchmail gesammelt und mit procmail sortiert werden. Torrents lade ich über das Webinterface von Transmission herunter, anderes über Nacht mit at und wget. + +Man sieht, der SheevaPlug lässt sich wirklich zu einigem gebrauchen und er funktioniert auch über längere Zeit gut. Als Alternative zu Debian bin ich neulich über [ArchMobile](http://www.archmobile.org/) gestolpert, einer Variante meiner Lieblingsdistribution für ARM, welche auch auf dem SheevaPlug läuft. Die Paketquellen sind allerdings noch etwas leer und beinhalten nicht alle Software die ich für den Webserver bräuchte. Und da ich keine Lust habe alles selber zu kompilieren (vor Arch habe ich Gentoo auf meinem Desktop eingesetzt), kommt es zur Zeit als Alternative für mich leider noch nicht in Frage. Werde aber trozdem informiert bleiben und eventuell auch einmal näher darüber [berichten](/symphony/artikel/plugbox-linux-ein-archlinux-port-fuer-den-sheevaplug). + +Der SheevaPlug ist wirklich ein wunderbares kleines Teil und ich habe durch ihn viel über Linux gelernt – allein dadurch hat er sich schon gelohnt. diff --git a/source/00_content/articles/2010-07-12_ocr_und_automatische_uebersetzung_mit_dem_n900.md b/source/00_content/articles/2010-07-12_ocr_und_automatische_uebersetzung_mit_dem_n900.md new file mode 100644 index 0000000..c842df8 --- /dev/null +++ b/source/00_content/articles/2010-07-12_ocr_und_automatische_uebersetzung_mit_dem_n900.md @@ -0,0 +1,17 @@ +# OCR und automatische Übersetzung mit dem N900 + +Heute bin ich auf einem Streifzug durch das Maemo5 testing-Repository auf ein sehr praktisches Programm gestoßen: PhotoTranslator. Mit ihm lässt sich der Text aus Bildern extrahieren und mittels Google-Translate übersetzen. + +<a href="http://imgur.com/a/7i39l"><img src="http://i.imgur.com/qycve.jpg" alt="PhotoTranslator - Start" width="600px" class="full"/></a> + +Das ist z.B. praktisch um fremdsprachige Speisekarten o.ä. in die eigene Sprache zu übersetzen. Nachdem man ein Bild ausgewählt oder direkt aus dem Programm heraus eines erstellt hat (funktioniert in der aktuellen Alpha-Version von PhotoTranslator noch nicht richtig) muss man als erstes den gewünschten Textteil mittels eines Rahmens, wie man ihn auch zum Zuschneiden von Fotos im Bildbetrachter des N900 verwendet auswählen – zur Zeit geht das jedoch leider nur mit einzelnen Zeilen und nicht mit ganzen Textblöcken. + +<a href="http://imgur.com/a/7i39l"><img src="http://i.imgur.com/45ub5.jpg" alt="PhotoTranslator - Textauswahl" width="600px" class="full"/></a> + +Danach muss man nurnoch die Ausgangs und Zielsprache wählen, kurz warten und schon bekommt man den eingescannten Ausgangstext und die Übersetzung präsentiert. Das funktioniert auch schon in dieser frühen Alpha-Version sehr gut. + +<a href="http://imgur.com/a/7i39l"><img src="http://i.imgur.com/1FSSP.jpg" alt="PhotoTranslator - Übersetzung" width="600px" class="full"/></a> + +PhotoTranslator lässt sich aber nicht nur zum Übersetzen von Bildern, sondern auch als einfache Oberfläche für Google-Translate mit Texteingabe über die Tastatur verwenden. +Weitere Informationen und ein Demo-Video findet ihr unter [cybercomchannel.com](http://www.cybercomchannel.com/?p=63). Installieren lässt sich PhotoTranslator bei aktivierten extras-testing Repositories bequem aus der Paketverwaltung des N900 heraus. +Anmerkung: Auch diesen Artikel habe ich komplett aus dem Browser des N900 heraus geschrieben – das Gerät ist einfach fantastisch, ich kann es nur empfehlen. diff --git a/source/00_content/articles/2011-10-02_tarsnap_backups_fuer_paranoide.md b/source/00_content/articles/2011-10-02_tarsnap_backups_fuer_paranoide.md new file mode 100644 index 0000000..7aedf41 --- /dev/null +++ b/source/00_content/articles/2011-10-02_tarsnap_backups_fuer_paranoide.md @@ -0,0 +1,28 @@ +# Tarsnap - Backups für Paranoide + +Für meine Backups nutze ich jetzt seit einiger Zeit den Online-Service [Tarsnap](http://www.tarsnap.com/). Dabei handelt es sich um einen Client der es ermöglicht verschlüsselte Backups in der Amazon-Cloud zu speichern und zu verwalten. + +Das ganze ist so aufgebaut, dass immer nur veränderte und neue Dateien übertragen werden müssen. Alle Daten werden schon vom Client verschlüsselt, sodass keine unverschlüsselten Daten übers Netzwerk fließen und weder die Entwickler von Tarsnap noch Amazon den Inhalt der Daten auslesen können. + +Der Service ist nicht kostenlos, aber sehr günstig - der Preis pro Byte Speicher / Datenverkehr beträgt 300 Picodollar, ein Gigabyte kostet also pro Monat nur 0,30$. + +Der Tarsnap-Client ist im Quellcode verfügbar (aber nicht unter einer Open Source Lizenz) und lässt sich problemlos auch auf ARM Prozessoren kompilieren, sodass ich auch vom N900 und SheevaPlug aus Zugriff auf meine Backups haben kann. Die Authentifizierung mit dem Server funktioniert über einen Schlüssel, der sich nach Eingabe des Passworts mit folgendem Befehl generieren lässt: + + tarsnap-keygen --keyfile [pfad-zum-schlüssel] --user [email] --machine [hostname] + +Die resultierende Datei ermöglicht ohne zusätzliche Authentifizierung Zugriff auf die Backups und sollte somit sicher aufbewahrt werden und nicht in falsche Hände geraten, denn ohne sie hat man keinen Zugriff mehr auf seine Daten. + +Ein neues Backup lässt sich über diesen Befehl anlegen: + + tarsnap -c -f [name-des-backups] [zu-sichernder-pfad] + +Jedes weitere Backup geht danach um einiges schneller weil Tarsnap nur veränderte Daten überträgt. Standardmäßig wird dieser Cache unter "/usr/local/tarsnap-cache" und der Schlüssel unter "/root/tarsnap.key" erwartet, dies lässt sich jedoch über entsprechende Parameter steuern - näheres dazu findet sich auf der [Manpage](http://www.tarsnap.com/man-tarsnap.1.html). + +Sollte man dann einmal in die nicht wünschenswerte Situation kommen Zugriff auf sein Backup zu benötigen, reicht dieser Befehl um die Daten wiederherzustellen: + + tarsnap -x -f [name-des-backups] [wiederherzustellender-pfad] + +Tarsnap kann ich wirklich empfehlen, es hat mich vom [Konzept](http://www.tarsnap.com/design.html) und der Umsetzung her voll überzeugt und ist auf jeden Fall eine ernst zunehmende Alternative zu anderen Backuplösungen in der _Wolke_. + +Der Tarsnap Client ist direkt aus den ArchLinux Repositories verfügbar: [tarsnap](http://www.archlinux.org/packages/community/i686/tarsnap/) + diff --git a/source/00_content/articles/2011-11-08_informationen_umformen_mit_xsl.md b/source/00_content/articles/2011-11-08_informationen_umformen_mit_xsl.md new file mode 100644 index 0000000..40777d0 --- /dev/null +++ b/source/00_content/articles/2011-11-08_informationen_umformen_mit_xsl.md @@ -0,0 +1,129 @@ +# Informationen umformen mit XSL + +Im Rahmen meiner Vorstandstätigkeit beim KV Konstanz der Piratenpartei betreue ich die Webseite [piraten-konstanz.de](http://piraten-konstanz.de) + +Unsere Termine organisieren wir üblicherweise im [Wiki](http://wiki.piratenpartei.de/Kreisverband_Konstanz) - seit der Einführung der neuen KV Seite auf Basis von Wordpress müssen wir diese Termine doppelt pflegen. Da dies kein Zustand ist welcher mir auf Dauer gefällt, habe ich nach Möglichkeiten zum Auslesen der Terminliste im Wiki und dem anschließenden Darstellen in Wordpress gesucht. + +Schlussendlich habe ich dann eine [XSLT](http://de.wikipedia.org/wiki/XSLT) geschrieben und rufe diese von einem einfachen [PHP-Script](http://piraten-konstanz.de/wp-content/tool/events_rss.php) auf. + +Mit XSL lassen sich XML Dateien in andere Formen bringen. Da Mediawiki mehr oder weniger valides XHTML ausgibt, kann man, nachdem das XHTML mit [Tidy](http://tidy.sourceforge.net) ein wenig aufgeräumt wurde, sehr einfach die [Terminliste](http://wiki.piratenpartei.de/BW:Kreisverband_Konstanz/Termine) extrahieren und gleichzeitig in RSS umformen: + + <xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:x="http://www.w3.org/1999/xhtml" + exclude-result-prefixes="x"> + + <xsl:import href="date-time.xsl"/> + + <xsl:output method="xml" + doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" + doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" + omit-xml-declaration="yes" + encoding="UTF-8" + indent="yes" /> + + <xsl:template match="/"> + <rss version="2.0"> + <channel> + <title>Termine des KV Konstanz</title> + <link>http://wiki.piratenpartei.de/BW:Kreisverband_Konstanz/Termine</link> + <description>Termine des KV Konstanz</description> + <xsl:apply-templates/> + </channel> + </rss> + </xsl:template> + + <xsl:template match="x:div[@id='pkn_main']/x:table"> + <xsl:for-each select="x:tr"> + <xsl:choose> + <xsl:when test="position() > 1"> + <item> + <title><xsl:value-of select="x:td[3]"/> am <xsl:call-template name="format-date"> + <xsl:with-param name="date" select="x:td[1]/x:span/."/> + <xsl:with-param name="format" select="'d.n.Y'"/></xsl:call-template> um <xsl:value-of select="x:td[2]"/> Uhr</title> + <link>http://wiki.piratenpartei.de<xsl:value-of select="x:td[3]/x:a/@href"/></link> + </item> + </xsl:when> + </xsl:choose> + </xsl:for-each> + </xsl:template> + + <xsl:template match="text()"/> + + </xsl:stylesheet> + +Der Kern dieses XSL ist nicht mehr als ein Template welches auf den [XPATH](http://de.wikipedia.org/wiki/XPATH) zum Finden der Terminliste reagiert. Die For-Each-Schleife iteriert dann durch die Termine und formt diese entsprechend in RSS um. +Der einzige Knackpunkt kommt daher, dass XHTML kein normales XML ist und somit seinen eigenen Namespace hat. Diesen sollte man im Element `xsl:stylesheet` korrekt angeben, sonst funktioniert nichts. Auch muss im XPATH Ausdruck dann vor jedem Element ein `x:` eingefügt werden um dem XSL Prozessor den Namespace für das jeweilige Element mitzuteilen. + +Das leere Template `xsl:template match="text()"` sorgt dafür, dass alle XML-Zweige, die nicht auf ein anderes Template passen, nicht ausgegeben werden. +`xsl:template match="/"` springt auf das Root-Element der XHTML-Seite an, bildet die RSS Grundstruktur und bindet dann alle anderen Templates ein. + +Zum Anpassen des Datums verwende ich - wie auch in diesem Blog - die [date-time.xsl](http://symphony-cms.com/download/xslt-utilities/view/20506/) Transformation. + +### Generieren des RSS Feed + +Mit der eben beschriebenen XSLT lässt sich jetzt in drei Schritten das fertige RSS generieren: + + #!/bin/sh + wget -O termine_wiki.html "http://wiki.piratenpartei.de/BW:Kreisverband_Konstanz/Termine" + tidy -asxml -asxhtml -O termine_tidy.html termine_wiki.html + xsltproc --output termine_kvkn.rss --novalid termine_kvkn.xsl termine_tidy.html + +In PHP ist das ganze dann zusammen mit sehr einfachem Caching auch direkt auf einem Webserver einsetzbar: + + define('CACHE_TIME', 6); + define('CACHE_FILE', 'rss.cache'); + + header("Content-Type: application/rss+xml"); + + if ( file_exists(CACHE_FILE) ) + { + if ( !filemtime(CACHE_FILE) < time() - CACHE_TIME * 3600 ) { + readfile(CACHE_FILE); + } + else { + if ( !generate_rss() ) { + readfile(CACHE_FILE); + } + } + } + else { + ob_start(); + + generate_rss(); + + ob_end_flush(); + + $cache_file = fopen(CACHE_FILE, 'w'); + fwrite($cache_file, ob_get_contents()); + fclose($cache_file); + } + + function generate_rss() + { + $event_page = file_get_contents('http://wiki.piratenpartei.de/BW:Kreisverband_Konstanz/Termine'); + + if ($event_page != false) + { + $config = array('output-xhtml' => true, 'output-xml' => true); + + $tidy = new tidy(); + + $xml = new DomDocument(); + $xml->loadXML( $tidy->repairString($event_page, $config) ); + + $xsl = new DomDocument(); + $xsl->load('termine_kvkn.xsl'); + + $xslt = new XsltProcessor(); + $xslt->importStylesheet($xsl); + + $rss = $xslt->transformToXML($xml); + echo $rss; + + return true; + } + else { + return false; + } + } diff --git a/source/00_content/articles/2012-01-25_erfahrungen_mit_openslides.md b/source/00_content/articles/2012-01-25_erfahrungen_mit_openslides.md new file mode 100644 index 0000000..3d7c534 --- /dev/null +++ b/source/00_content/articles/2012-01-25_erfahrungen_mit_openslides.md @@ -0,0 +1,46 @@ +# Erfahrungen mit OpenSlides + +Für den letzten Kreisparteitag des [KV Konstanz](http://piraten-konstanz.de) suchte ich nach einer möglichst bequemen Möglichkeit die aktuelle Tagesordnung auf einem Beamer abzubilden. Gestoßen bin ich dabei auf die freie Software [OpenSlides](http://openslides.org/de/index.html). + +OpenSlides ist ein auf dem Python-Webframework [Django](https://www.djangoproject.com/) basierendes Präsentationsystem zur Darstellung und Steuerung von Tagesordnungen, Anträgen, Abstimmungen und Wahlen - also ein für die Organisation von Parteitagen sehr gut geeignetes Werkzeug. + +Das UI ist dabei in den Administrationsbereich, über den sämtliche Daten eingegeben werden können, und eine Beamer-Ansicht geteilt. Beide dieser Komponenten laufen in einem gewöhnlichen Webbrowser. Das Aussehen lässt sich also einfach durch Modifikation der Templates und der CSS-Formatierungen an die eigenen Wünsche anpassen. + +<a href="http://imgur.com/eNDNN"><img src="http://i.imgur.com/eNDNNl.jpg" alt="" title="KPT OpenSlides" class="full"/></a> + +Nachdem ich anfangs alle Wahlen, bekannten Teilnehmer und Anträge in das Redaktionsystem eingespiesen hatte, ließ sich am Parteitag selbst dann mit wenigen Mausklicks eine ansprechende Präsentation des aktuellen Themas erzeugen. +Wahlergebnisse waren ebenso wie die Annahme oder Ablehnung eines Antrags über entsprechende Formulare schnell eingepflegt und dargestellt. +Sehr gefallen hat mir im Vorfeld auch die Möglichkeit der Generierung von Antragsbüchern als PDF. + +<a href="http://imgur.com/NzwVH"><img src="http://i.imgur.com/NzwVHl.png" alt="" title="KPT OpenSlides" class="full"/></a> + +Der Funktionsumfang von OpenSlides geht jedoch über die bloße Darstellung der TO auf einem Beamer hinaus. So kann wenn gewünscht jeder Teilnehmer über sein eigenes Endgerät auf das Webinterface zugreifen und als Deligierter an der Versammlung teilnehmen - also Abstimmen, Wählen und Anträge stellen. +Theoretisch ermöglicht es diese Software also - bei entsprechender Authentifizierung - die Durchführung von dezentralen Versammlungen. Aber auch wenn dies z.B. aufgrund von zur Nachvollziehbarkeit nötiger Klarnamenspflicht nicht in Frage kommt, ergibt sich doch so für die Teilnehmer immerhin die Möglichkeit den Ablauf auf einem eigenen Gerät nachzuverfolgen. + +Der einzige Punkt der mich wirklich störte war die fehlende Anzeige von Wahlergebnissen der Teilnehmer die eine Wahl verloren hatten. Die jeweilige Stimmenzahl war im Frontend erst sichtbar nachdem der entsprechende Kandidat als Sieger markiert worden war. +Doch auch dieses Problem ließ sich - OpenSource sei Dank - schnell über manuelles Eingreifen im Quelltext korrigieren: + + --- /home/adrian/Downloads/original_views.py + +++ /opt/hg.openslides.org/openslides/agenda/views.py + @@ -132,14 +132,11 @@ + for poll in assignment.poll_set.all(): + if poll.published: + if candidate in poll.options_values: + - if assignment.is_elected(candidate): + - option = Option.objects.filter(poll=poll).filter(user=candidate)[0] + - if poll.optiondecision: + - tmplist[1].append([option.yes, option.no, option.undesided]) + - else: + - tmplist[1].append(option.yes) + + option = Option.objects.filter(poll=poll).filter(user=candidate)[0] + + if poll.optiondecision: + + tmplist[1].append([option.yes, option.no, option.undesided]) + else: + - tmplist[1].append("") + + tmplist[1].append(option.yes) + else: + tmplist[1].append("-") + votes.append(tmplist) + +OpenSlides ist wirklich ein tolles Stück Software und ich kann nur jedem der vor der Aufgabe steht eine Versammlung zu organisieren, sei es die eines Vereins oder wie in meinem Fall die einer Partei, empfehlen sich es einmal näher anzusehen. +Weitere Angaben zur Installation und Konfiguration finden sich auf der [Webpräsenz](http://openslides.org/de/index.html) und im [Quell-Archiv](http://openslides.org/download/openslides-1.1.tar.gz). diff --git a/source/00_content/articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md b/source/00_content/articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md new file mode 100644 index 0000000..ae46d92 --- /dev/null +++ b/source/00_content/articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md @@ -0,0 +1,57 @@ +# Mapping arrays using tuples in C++11 + +During my proof-of-concept implementation of external functions enabling [XSLT based static site generation](https://github.com/KnairdA/InputXSLT) I came upon the problem of calling a template method specialized on the Nth type of a `std::tuple` specialization using the Nth element of a array-like type instance as input. This was needed to implement a generic template-based interface for implementing [Apache Xalan](http://xalan.apache.org/xalan-c/index.html) external functions. This article aims to explain the particular approach taken to solve this problem. + +While it is possible to unpack a `std::tuple` instance into individual predefined objects using `std::tie` the standard library offers no such helper template for `unpacking` an array into individual objects and calling appropriate casting methods defined by a `std::tuple` mapping type. Sadly exactly this functionality is needed so that we are able to call a `constructDocument` member method of a class derived from the [`FunctionBase`](https://github.com/KnairdA/InputXSLT/blob/master/src/function/base.h) external function interface template class using static polymorphism provided through the [curiously recurring template pattern](https://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern). This interface template accepts the desired external function arguments as variadic template types and aims to provide the required validation and conversion boilerplate implementation. While we could recursively generate a `std::tuple` specialization instance from an array-like type using a approach simmilar to the one detailed in my article on [mapping binary structures as tuples using template metaprogramming](http://blog.kummerlaender.eu/artikel/mapping-binary-structures-as-tuples-using-template-metaprogramming) this wouldn't solve the problem of passing on the resulting values as individual objects. This is why I had to take the new approach of directly calling a template method on individual array elements using a `std::tuple` specialization as a kind of blueprint and passing the result values of this method to the `constructDocument` method as separate arguments. + +Extracting array elements obviously requires some way of defining the appropriate indexes and mapping the elements using a tuple blueprint additionally requires this way to be statically resolvable as one can not pass a dynamic index value to `std::tuple_element`. So the first step to fullfilling the defined requirements involved the implementation of a template based index or sequence type. + + template <std::size_t...> + struct Sequence { + typedef Sequence type; + }; + + template < + std::size_t Size, + std::size_t Index = 0, + std::size_t... Current + > + struct IndexSequence { + typedef typename std::conditional< + Index < Size, + IndexSequence<Size, Index + 1, Current..., Index>, + Sequence<Current...> + >::type::type type; + }; + +This is achieved by the [`IndexSequence` template](https://github.com/KnairdA/InputXSLT/blob/master/src/support/type/sequence.h) above by recursively specializing the `Sequence` template using static recursion controlled by the standard libraries template metaprogramming utility template `std::conditional`. This means that e.g. the type `Sequence<0, 1, 2, 3>` can also be defined as `IndexSequence<4>::type`. + +Now all that is required to accomplish the goal is instantiating the sequence type and passing it to a variadic member template as [follows](https://github.com/KnairdA/InputXSLT/blob/master/src/function/base.h): + + [...] + this->callConstructDocument( + parameters, + locator, + typename IndexSequence<parameter_count>::type() + ) + [...] + template <std::size_t... Index> + inline xalan::XalanDocument* callConstructDocument( + const XObjectArgVectorType& parameters, + const xalan::Locator* locator, + Sequence<Index...> + ) const { + [...] + return this->document_cache_->create( + static_cast<const Implementation*>(this)->constructDocument( + valueGetter.get<typename std::tuple_element< + Index, + std::tuple<Types...> + >::type>(parameters[Index])... + ) + ); + } + +As we can see a `IndexSequence` template specialization instance is passed to the variadic `callConstructDocument` method to expose the actual sequence values as `Index`. This method then resolves the `Index` parameter pack as both the array and `std::tuple` index inside the calls to the `valueGetter.get` template method which is called for every sequence element because of this. What this means is that we are now able to implement non-template `constructDocument` methods inside XSLT external function implementations such as [FunctionTransform](https://github.com/KnairdA/InputXSLT/blob/master/src/function/transform.h). The values passed to these methods are automatically extracted from the argument array and converted into their respective types as required. + +While this article only provided a short overview of mapping arrays using tuples in C++11 one may view the full implementation on [Github](https://github.com/KnairdA/InputXSLT/blob/master/src/function/base.h) or [cgit](http://code.kummerlaender.eu/InputXSLT/tree/src/function/base.h). diff --git a/source/00_content/tags/cpp/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md b/source/00_content/tags/cpp/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md new file mode 120000 index 0000000..ae7da97 --- /dev/null +++ b/source/00_content/tags/cpp/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md @@ -0,0 +1 @@ +../../articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md
\ No newline at end of file diff --git a/source/00_content/tags/development/2011-11-08_informationen_umformen_mit_xsl.md b/source/00_content/tags/development/2011-11-08_informationen_umformen_mit_xsl.md new file mode 120000 index 0000000..235ecdd --- /dev/null +++ b/source/00_content/tags/development/2011-11-08_informationen_umformen_mit_xsl.md @@ -0,0 +1 @@ +../../articles/2011-11-08_informationen_umformen_mit_xsl.md
\ No newline at end of file diff --git a/source/00_content/tags/development/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md b/source/00_content/tags/development/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md new file mode 120000 index 0000000..ae7da97 --- /dev/null +++ b/source/00_content/tags/development/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md @@ -0,0 +1 @@ +../../articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md
\ No newline at end of file diff --git a/source/00_content/tags/english/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md b/source/00_content/tags/english/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md new file mode 120000 index 0000000..ae7da97 --- /dev/null +++ b/source/00_content/tags/english/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md @@ -0,0 +1 @@ +../../articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md
\ No newline at end of file diff --git a/source/00_content/tags/german/2010-02-06_debian_auf_dem_sheevaplug.md b/source/00_content/tags/german/2010-02-06_debian_auf_dem_sheevaplug.md new file mode 120000 index 0000000..661f450 --- /dev/null +++ b/source/00_content/tags/german/2010-02-06_debian_auf_dem_sheevaplug.md @@ -0,0 +1 @@ +../../articles/2010-02-06_debian_auf_dem_sheevaplug.md
\ No newline at end of file diff --git a/source/00_content/tags/german/2010-03-16_erfahrungen_mit_dem_sheevaplug_im_laengeren_einsatz.md b/source/00_content/tags/german/2010-03-16_erfahrungen_mit_dem_sheevaplug_im_laengeren_einsatz.md new file mode 120000 index 0000000..c672c07 --- /dev/null +++ b/source/00_content/tags/german/2010-03-16_erfahrungen_mit_dem_sheevaplug_im_laengeren_einsatz.md @@ -0,0 +1 @@ +../../articles/2010-03-16_erfahrungen_mit_dem_sheevaplug_im_laengeren_einsatz.md
\ No newline at end of file diff --git a/source/00_content/tags/german/2010-07-12_ocr_und_automatische_uebersetzung_mit_dem_n900.md b/source/00_content/tags/german/2010-07-12_ocr_und_automatische_uebersetzung_mit_dem_n900.md new file mode 120000 index 0000000..1d18e50 --- /dev/null +++ b/source/00_content/tags/german/2010-07-12_ocr_und_automatische_uebersetzung_mit_dem_n900.md @@ -0,0 +1 @@ +../../articles/2010-07-12_ocr_und_automatische_uebersetzung_mit_dem_n900.md
\ No newline at end of file diff --git a/source/00_content/tags/german/2011-10-02_tarsnap_backups_fuer_paranoide.md b/source/00_content/tags/german/2011-10-02_tarsnap_backups_fuer_paranoide.md new file mode 120000 index 0000000..9787662 --- /dev/null +++ b/source/00_content/tags/german/2011-10-02_tarsnap_backups_fuer_paranoide.md @@ -0,0 +1 @@ +../../articles/2011-10-02_tarsnap_backups_fuer_paranoide.md
\ No newline at end of file diff --git a/source/00_content/tags/german/2011-11-08_informationen_umformen_mit_xsl.md b/source/00_content/tags/german/2011-11-08_informationen_umformen_mit_xsl.md new file mode 120000 index 0000000..235ecdd --- /dev/null +++ b/source/00_content/tags/german/2011-11-08_informationen_umformen_mit_xsl.md @@ -0,0 +1 @@ +../../articles/2011-11-08_informationen_umformen_mit_xsl.md
\ No newline at end of file diff --git a/source/00_content/tags/german/2012-01-25_erfahrungen_mit_openslides.md b/source/00_content/tags/german/2012-01-25_erfahrungen_mit_openslides.md new file mode 120000 index 0000000..9d88caf --- /dev/null +++ b/source/00_content/tags/german/2012-01-25_erfahrungen_mit_openslides.md @@ -0,0 +1 @@ +../../articles/2012-01-25_erfahrungen_mit_openslides.md
\ No newline at end of file diff --git a/source/00_content/tags/linux/2010-02-06_debian_auf_dem_sheevaplug.md b/source/00_content/tags/linux/2010-02-06_debian_auf_dem_sheevaplug.md new file |