Codeception: HTML and Accessibility Validation

For my latest web project, Antragsgrün 3, I’m heavily using Codeception for acceptance testing. As I want to ensure that the system validates against the HTML5 standard and is accessible, I’ve written two helpers for Codeception that I want to share: one Helper that validates the current site using the Nu Html Checker (http://validator.github.io/validator/), and one that validates it against WCAG2.0 (A, AA or AAA) or Section 508 using Pa11y.

Both helpers are using the command line tools, so they do not rely on an online web service and can be used offline. While the accessibility validator works with both the PhpBrowser and the Webdriver module of Codeception, the Html Validators needs Webdriver (which, while a bit more difficult to set up, is superior anyway).

Validating the current site is as easy as:

$I->validateHTML();
$I->validatePa11y();

(There are also some parameters for choosing the accessibility standard and to ignore certain errors).

The code and installation instructions are on these two gists:
HTML Validator
Accessibility Validator

Bezirksausschuss Laim: Website

Vor wenigen Tagen ging nach langer Vorbereitungszeit endlich die neue Website des Laimer Bezirksausschuss online:

Screenshot der Website des Bezirksausschuss Laim (Internale)

Die lange Vorbereitungszeit lag dabei nicht an der eigentlichen Gestaltung – technisch ist die Seite eher trivial, wie man denke ich recht schnell sieht. Ungewohnt war für mich nur, einmal komplett ohne serverseitigen Skriptsprachen zu arbeiten und stattdessen nur auf statische HTML-Seiten zu setzen – aber dank Jekyll & co ist das ja inzwischen auch kein Problem mehr. Die rechtliche Klärung dauerte dafür aus nicht ganz nachvollziehbaren Gründen locker fünfmal so lang wie die eigentliche Programmierung. Na ja, Ende gut, alles gut – jetzt ist sie endlich da und alle sind glücklich. 🙂

Vortrag: München Transparent

Dank der Einladung des SIN – Studio im Netz e.V. habe ich kommenden Donnerstag, den 18. Juni um 19:00 Uhr die Gelegenheit, im Rahmen der Münchner Webwoche das Projekt München Transparent vorzustellen. Den Vortrag halte ich zusammen mit Marcus M. Dapp, der über Open Data und Open Government im größeren Kontext sprechen wird. Wer Lust hat, sich es anzuhören: der Vortrag ist kostenlos, nur eine Voranmeldung ist nötig.

Nachtrag: die Folien des Vortrags sind nun online.

Antragsgrün 3 – Aktuelle Planung

In den letzten Wochen und Monaten kam wieder einiges an Schwung in die Weiterentwicklung von Antragsgrün. Da sich momentan eine komplette Überarbeitung des Antragstools abzeichnet, will ich hier die aktuellen Planungen kurz umreißen.

Rückblick

Die erste Version von Antragsgrün hatte ich 2012 für den Landesverband Bayern von Bündnis 90 / Die Grünen geschrieben, um die Antragsverwaltung auf den Landesdelegiertenkonferenzen sowohl für Delegierte als auch die Geschäftsstelle zu vereinfachen. Es unterstützte damals unter anderem schon Anträge, Änderungsanträge, Kommentare und automatisch generierte PDFs. Es war relativ schnell klar, dass auch andere grüne Verbände Interesse daran haben, und dass das anfängliche Modell, für jeden Verband eine neue Instanz zu installieren, nicht wirklich skalierte. Daher folgte schnell Antragsgrün 2, dessen wichtigste Neuerung die Mandantenfähigkeit war – also dass eine zentrale Installation beliebig viele Verbände bedienen kann. Antragsgrün ist damit einerseits Open-Source-Software, die frei auf eigenen Servern installiert werden kann – andererseits aber auch ein zentrales Portal www.antragsgruen.de, über das sich alle grünen Verbände kostenlos ohne technische Kenntnisse eigene Programmdiskussionen einrichten können.

Neue Anforderungen

Nun zeigt sich aber, dass Antragsgrün auch für deutlich mehr als nur reine Antragsarbeit verwendet wird und damit auch ein großer Bedarf für neue Anwendungsszenarien besteht, die momentan nicht oder nur auf Umwegen abgedeckt werden. Beispiele dafür sind Bewerbungen und strukturierte Programmarbeit, was beispielsweise einen Bilder-Upload und deutlich flexiblere Formulare benötigt als Antragsgrün mit seiner momentan noch recht starren Fixierung auf das „Antragstext + Begründung“-Schema liefern kann. Oft gewünscht wird auch eine Tagesordnungsfunktion, bessere Anpassbarkeit in so ziemlich allen denkbaren Gebieten (Wording, Layout, verschiedene Antragsschlüsse, …) und eine bessere Kompatibilität mit verwandten Tools wie OpenSlides und cvtx. Um diese Funktionen einzubauen, müssen einige grundlegende Strukturen von Antragsgrün überarbeitet werden.

Nicht zuletzt gibt es auch einige rein technische Gründe, die für eine größere Überarbeitung sprechen: von den meisten verwendeten Software-Bibliotheken gibt es nach vier Jahren nun große neue Versionen, insbesondere vom zugrunde liegenden PHP-Framework Yii. Und, um ehrlich zu sein: einige grundlegende Design-Entscheidungen beim bisherigen Antragsgrün waren rückblickend schlicht falsch und warten auf Korrektur. Eine Überarbeitung ist außerdem ein guter Anlass, auch endlich automatisierte Tests mit einzubauen, die die allgemeine Softwarequalität langfristig deutlich erhöhen sollte. Zumindest hatten sich zuletzt häufig Fehler eingeschlichen, die beim konsequenten Einsatz von Unit- und Acceptance-Tests vermieden hätten werden können.

Antragsgrün 3 soll mit den eben genannten Punkten und Verbesserungen noch im diesen Sommer erscheinen. Zeitlich ist das zwar ambitioniert, nach meiner aktuellen Einschätzung und mit der bisherigen Vorarbeit und Unterstützung aber realistisch.

Aktuelle Entwicklung

Die konkreten Arbeiten an Antragsgrün 3 begannen schon im Februar diesen Jahres, als sich abzeichnete, dass sowohl ein Grüner Landesverband Interesse an den Bewerbungen und der Tagesordnungsfunktion hat, als auch der Bundesverband Interesse bekundete, Antragsgrün verstärkt einzusetzen. In einem neuen Github-Branch liegt demnach auch schon einiges an Code – natürlich noch in einem recht frühen Zustand, da es bislang nur in meiner Freizeit entwickelt ist. Allerdings sind bereits alle wichtigen Kerntechniken grundlegend implementiert – von der neuen Datenstruktur über einen neu geschriebenen Diff-Algorithmus bis hin zu den Unit- und Acceptance-Tests.

Ein Großteil der Entwicklungsarbeit wird im Juli stattfinden. Im Juli werde ich, dank der Unterstützung durch den Grünen-Bundesverband sowie einiger -Landesverbände, in Vollzeit an Antragsgrün arbeiten können und in dieser Zeit hoffentlich einen Großteil der oben genannten Punkte umsetzen können. Es wird demnach wohl Ende Juli eine erste Beta-Version geben, die erste stabile Version ist für August geplant. Natürlich ist damit dann nicht die Entwicklung ein für alle mal abgeschlossen – nur wird das Tempo wieder stärker davon abhängen, wie viel Freizeit ich habe bzw. ob sich für bestimmte Neuerungen „Sponsoren“ finden.

Technischer Überblick

Achtung: hier folgt viel Technik-Fachsimpelei, das man auch einfach überspringen kann. Ab dem nächsten Abschnitt wird es wieder verständlicher. 🙂

Frameworks

Antragsgrün 3 wird technisch auf das Yii2-Framework aufsetzen, benötigt mindestens PHP 5.5, wird in der Produktivversion aber entweder auf PHP7 oder HHVM laufen.

Als CSS-Framework kommt Bootstrap 3 in der SASS-Variante, oder, falls bis dahin verfügbar, Bootstrap 4.

Für die Unit- und Acceptance-Tests setze ich Codeception ein, plus diverse Tools zur statischen Code-Analyse (PHP Mess Detector, PHP Code Sniffer). Als Coding-Standard verwende ich PSR-2. Noch unschlüssig bin ich bei der Wahl des Continuous-Integration-Tools; aktuell verwende ich noch PHPCI, bin allerdings nicht so ganz zufrieden und möchte daher auch mindestens noch Jenkins und Travis testen.

Es gibt auch schon ein prototypisches Docker-Image; eine Vagrant-basierte Umgebung ist angedacht.

Datenstrukturen und Features

Das große Motto von Antragsgrün 3 ist „Flexibilisierung“ (mit sinnvollen Voreinstellungen):

  • Es wird nicht mehr vorgegeben, aus welchen Bestandteilen ein Antrag, eine Bewerbung etc. genau besteht. Diskussionsvorschläge können beispielsweise nur ein Textfeld haben, Anträge dagegen zwei, und Bewerbungen noch ein Bild und tabellarische Angaben wie Geburtsjahr, KV usw. Zwar gibt es Voreinstellungen, die für die üblichen Verwendungszwecke (Parteitag mit Anträgen und Bewerbungen, Programmdiskussion, …) maßgeschneidert sind, die Strukturen werden aber nicht mehr fest einprogrammiert sein wie das bisherige Antragstext+Begründungs-Schema.
  • Es kann mehrere Dokumententypen pro Veranstaltung / Diskussion geben, die einerseits unterschiedlich strukturiert sind, andererseits aber auch unterschiedliche „Regeln“ haben. Damit ist es beispielsweise möglich, unterschiedliche Antragsschlüsse für Anträge, Satzungsänderungsanträge, Eilanträge und Bewerbungen festzulegen, oder unterschiedliche Voraussetzungen (ein Antrag, der z.B. 5 UnterstützerInnen benötigt, während es für Bewerbungen keine benötigt).
  • Möglichst alle Textbausteine auf einer Seite sollen auf Wunsch anpassbar sein.
  • Es wird die Möglichkeit geben, aus mehreren PDF-Vorlagen für Anträge, Änderungsanträge, Bewerbungen etc. zu wählen.

Weitere Änderungen sind unter anderem:

  • Verbessert werden soll auch die BenutzerInnenverwaltung. Beispielsweise fehlen aktuell noch grundlegende Funktionen wie eine Passwort-Zurücksetzen-Funktion, die nachgerüstet wird.
  • Texte werden nun intern nicht mehr als BBCode, sondern direkt als (normalisiertes) HTML gespeichert. Die Entscheidung für BBCode war indirekt für viele kleinere Probleme verantwortlich, die es bei Antragsgrün momentan noch gibt – auch scheinbar unzusammenhängende Probleme wie die unzulängliche Absatzerkennung bei der Eingabe von Texten.
  • Ein Betrieb auf eigenen Servern soll vereinfacht werden; beispielsweise soll kein eigener E-Mail-Server mehr vorausgesetzt werden.
  • Neben MySQL soll auch SQLite als Datenbank unterstützt werden.
  • Die Liste von AntragstellererInnen und UnterstützerInnen eines Antrags werden sauberer von der User-Tabelle getrennt sein. Die aktuelle Verschränkung dieser beiden Tabellen hatte häufiger für unerwartete Seiteneffekte gesorgt.
  • Die Funktion zur Anzeige von Änderungen wird nun direkt in Antragsgrün implementiert, nicht mehr über eine externe Bibliothek. Dadurch können Probleme hier leichter behoben werden, wie zum Beispiel die oft sehr unvorteilhafte Anzeige, wenn größere Textblöcke als ganzes durch Neue ersetzt werden.

Antragsgrün 4, 5, …

Bei den internen Treffen mit VertreterInnen anderer Landesverbände zeigte sich schon, dass es auch weit über die hier vorgestellten Funktionen noch größere Visionen gibt, die allerdings zeitlich dieses Jahr noch nicht umgesetzt werden können.

Das langfristige Ziel sollte bei Antragsgrün sein, die Arbeit der Antragskommission komplett ohne Medienbrüche abbilden zu können – was schon alleine deshalb herausfordernd ist, da die verschiedenen Antragskommissionen der Verbände teils grundlegend unterschiedlich arbeiten. Solche Medienbrüche, die derzeit noch üblich sind, sind das Ausdrucken von Spreadsheets/Excel-Tabellen, Google Speadsheets, oder die Verwendung anderer Tools für einzelne Aspekte der Antragsbearbeitung.

Auch eine Offline-Variante von Antragsgrün wird immer wieder gewünscht, was aber mit PHP gerade auf Windows leider doch komplizierter ist als beispielsweise mit Python. Ansatzpunkte könnten PHP Desktop oder PHPWebkit sein – allerdings habe ich hier noch keine Praxiserfahrung und wäre auch über sachdienliche Hinweise dankbar. 🙂

Ein weiterer Nachteil von Antragsgrün, auch der kommenden 3er-Version ist, dass es sich nicht in andere Content-Management-Systeme integrieren lässt. Für WordPress punktet hier das cvtx-Plugin von Alexander Fecke, für Typo3 ist mir keines bekannt. Ob eine WordPress- und/oder Typo3-Variante von Antragsgrün realistisch ist, müsste genauer evaluiert werden.

Da auch international keine wirklich mit Antragsgrün vergleichbare (Open-Source-)Software gibt, bietet sich eine Internationalisierung auch geradezu an. Da schon Antragsgrün 3 Mechanismen vorhält, Textbausteine auf der Seite flexibel zu ersetzen, ist auch schon ein erster Schritt in diese Richtung getan.

Choosing Android’s System Sounds for Cordova Push Notifications, using Native Configuration Screens

One of the features most wished for in one of my Cordova-based android apps was to let the users choose another sound for push notifications, or to disable sound altogether (without having to mute the whole smart phone and still keeping vibration). The Push Plugin supports custom sounds, however all sound resources have to be embedded in the app. In my case, I wanted to let the users choose among the system sounds provided by Android itself, which apparently isn’t possible without some major changes to the plugin.

Here, I’m going to outline the changes necessary to integrate Android’s native RingtonePreference dialog into a Cordova-based app to let the users choose another notification sound. I’ve published the modified plugin that should work on android projects on Github.

Screenshot_2015-04-29-18-13-18Screenshot_2015-04-29-18-13-23

Configuration Dialog

Choosing the preferences for push notifications is done in a native android PreferenceScreen that is opened from within the app using a new javascript-method on the pushNotification-Object. The configuration screen is defined by a xml file stored at platforms/android/res/xml/pushsettings.xml:



    

        

        

        

        

    

The referenced strings are stored in platforms/android/res/values/strings-gcm.xml:



    Notifications
    Light
    Light is switched on
    Light is switched off
    Vibration
    Vibration is switched on
    Vibration is switched off
    Sound
    Sound is switched on
    Sound is switched off
    Ring tone
    Choose a ring tone

Translated versions can be stored in files like platforms/android/res/values-de/strings-gcm.xml

Opening the dialog
First of all, a new activity has to be defined in the platforms/android/AndroidManifest.xml:


The Activity itself is pretty simple, just remember to replace the „CORDOVA_PACKAGE_ID“ by the id of your app (necessary to access the R.xml.pushsettings-resource):

package com.plugin.gcm;

import CORDOVA_PACKAGE_ID.R;
import android.os.Bundle;
import android.preference.PreferenceActivity;

public class PushSettingsActivity extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pushsettings);
    }
}

This activity is called from PushPlugin.java’s execute-method, something like:

if ('showPushSettings'.equals(action)) {
    Intent i = new Intent(this.cordova.getActivity(), PushSettingsActivity.class);
    this.cordova.getActivity().startActivityForResult(i, RESULT_PUSH_SETTINGS);
    callbackContext.success();
}

The JavaScript-method to call this in PushNotification.js is:

PushNotification.prototype.showPushSettings = function (successCallback, errorCallback) {
    if (errorCallback == null) {
        errorCallback = function () {}
    }
    if (successCallback == null) {
        successCallback = function () {}
    }

    if (typeof errorCallback != "function") {
        console.log("PushNotification.showPushSettings failure: failure parameter not a function");
        return;
    }

    if (typeof successCallback != "function") {
        console.log("PushNotification.showPushSettings failure: success callback parameter must be a function");
        return;
    }

    cordova.exec(successCallback, errorCallback, "PushPlugin", "showPushSettings", []);
};

With all these changes applied, a call to plugins.pushNotification.showPushSettings() should open the configuration dialog and let the user apply her desired notification sound. The settings are stored automatically in android’s SharedPreferences. In the source code of the plugin, I also added a getPushSettings()-method that returns the settings into JavaScript, if you ever need to query these settings.

Using the settings for the notification
The actual notification sound is triggered in GCMIntentService.java’s onMessage-method. The new code reads the settings from the SharedPreferences and acts accordingly:

SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean vibration = app_preferences.getBoolean("com.plugin.gcm.vibration", true);
boolean sound = app_preferences.getBoolean("com.plugin.gcm.sound", true);
boolean light = app_preferences.getBoolean("com.plugin.gcm.light", true);
String ringtonePath = app_preferences.getString("com.plugin.gcm.ringtone", "defValue");
int defaults = 0;
if (vibration) defaults = defaults | Notification.DEFAULT_VIBRATE;
if (light) defaults = defaults | Notification.DEFAULT_LIGHTS;
		
NotificationCompat.Builder mBuilder =
    new NotificationCompat.Builder(context)
        .setDefaults(defaults)
        .setSmallIcon(context.getApplicationInfo().icon)
        .setWhen(System.currentTimeMillis())
        .setContentTitle(extras.getString("title"))
        .setTicker(extras.getString("title"))
        .setContentIntent(contentIntent)
        .setAutoCancel(true);

if (!ringtonePath.equals("") && sound) {
    Uri uri = Uri.parse(ringtonePath);
    Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), uri);
    r.play();

    mBuilder.setSound(null);
}

I’m using the Ringtone.play() instead of the setSound()-method of NotificationCompat.Builder, as the latter one somehow didn’t actually change the sound, even with the URL of the sound provided. I haven’t yet figured out why, but there probably is a solution that’s more elegant than the one showed above.
That’s it. Have fun! 🙂

München Transparent

Heute wurde nach langer Vorbereitungszeit die erste Version von „München Transparent“ offiziell vorgestellt. Eine große Erleichterung, nachdem ich das Projekt über Jahre hinweg vorbereitet hatte – anfangs alleine unter dem Arbeitstitel „OpenRIS“, seit 2014 dann zusammen mit Bernd Oswald und Konstantin Schütze im Rahmen des Münchner „OK Labs“. Über das Konzept der Seite hatte ich ja bereits gebloggt – einmal 2012 die grobe Vision, und 2014 über viele technischen Aspekte. Seitdem ging es hauptsächlich darum, die Seite optisch ansprechend zu gestalten ( was dank des Material-Design-Themes für Bootstrap glaube ich ganz gut gelungen ist), kleinere Funktionen einzubauen (man Kann Anträge nun verschlagworten, StR-/BA-Mitglieder können sich Mini-Profile anlegen, …) und die Seite um redaktionelle Inhalte zu erweitern (z.B. erläuternde Texte, ein Glossar und eine erste Version eines Erkläungsvideos). Nicht zuletzt gab es im Dezember ’14 dann schließlich nach langer Beratung auch das offizielle „OK“ von der Stadt München zu diesem Projekt.München-Transparent-Screenshot

Im Blog der Open Knowledge Foundation gibt es auch eine ausführlichere Ankündigung von München Transparent.

 

Using the Ionic Framework for Windows (Phone) 8.1 apps

Update: Most of the patches mentioned here are not necessary anymore, since they have been addressed by the v1.0.0-rc.5 release of the Ionic Framework.

Cordova not only supports Windows Phone 8, but also the new Windows platform, which includes Windows 8, Windows 8.1 and Windows Phone 8.1 apps. Currently, I love creating apps for Android and iOS with the Ionic Framework. So I wondered how difficult it would be to deploy an Ionic-based app to Windows Phone, even though it’s not officially supported (yet). For Windows Phone 8, there are several threads discussing problems and ways around them, like this one. So I concentrated on Windows Phone 8.1, Windows 8.1 and the Windows Push Notification Service. It turned out, that it is in fact possible to run basic Ionic-based apps, although with some major issues.

The Ionic Demo, running as a Windows desktop App

The Ionic Demo, running as a Windows desktop App

Development Environment

You will need at least Windows 8.1 to develop apps for Windows 8.1 and Windows Phone 8.1. The free technical Preview of Windows 10 works as well (except for the App Certification Kit, which is needed when submitting an app to the store).

As an IDE, the free Microsoft Visual Studio Community 2013 with Update 4 (download) works perfectly. When installing Visual Studio, it is important to include all optional features (ie. the Windows Phone 8.0 SDK and the Tools for Maintaining Store Apps For Windows 8).

Other programs I needed:
The Git Bash
NodeJs

Starting the app

npm install ionic
ionic start MyWinApp
cd MyWinApp
ionic platform windows

Now, the CordovaApp.Phone.jsproj (for Windows Phone 8.1) and CordovaApp.Windows.jsproj (for Windows 8.1) in MyWinApp\platforms\windows\ can be opened with Visual Studio.

Problems and getting around them

1. Security vs. innerHTML

Angular doesn’t work with Windows Phone 8.1 by default, as Angular relies on the innerHTML-property, which is not accessible on Windows Phone 8.1 for security reasons. Trying to start the blank Ionic app results in the following message:

Unhandled exception at line 10951, column 9 in ms-appx://2f930110-8ae3-11e4-b252-af36a362e5f3/www/lib/ionic/js/ionic.bundle.js

0x800c001c – JavaScript runtime error: Unable to add dynamic content. A script attempted to inject dynamic content, or elements previously modified dynamically, that might be unsafe. For example, using the innerHTML property to add script or malformed HTML will generate this exception. Use the toStaticHTML method to filter dynamic content, or explicitly create elements and attributes with a method such as createElement. For more information, see http://go.microsoft.com/fwlink/?

MSOpenTech provides a shim that almost solves the problem. The file winstore-jscompat.js needs to be included before ionic.bundle.js.
However, the shim as it is does not completely solve the problem, as there still occurs an exception that leads to a blank page:

Error: [$compile:tplrt] Template for directive ‚ionTabNav‘ must have exactly one root element.
http://errors.angularjs.org/1.3.6/$compile/tplrt?p0=ionTabNav&p1=

Replacing the „cleansePropertySetter(„innerHTML““ block in winstore-jscompat.js by the following code (as suggested by Arjan Snoek) really solves the problem:

cleansePropertySetter("innerHTML", function (propDesc, target, elements) {
    empty(target);
    for (var eix = 0, elen = elements.length; eix < elen; eix++) {
        if (elements[eix].nodeName == 'BODY') {
            for (var cix = 0, clen = elements[eix].childNodes.length;
                    cix < clen; cix++) {
                target.appendChild(elements[eix].childNodes[0]);
            }
        }
    }
});

Now, the app starts, even the icons work perfectly (unlike with Windows Phone 8.0) and the Tabs are working too.

2. Broken Links in the app („Search for app in the Store“)

When trying to open a person in the „Chats“ tab of Ionic’s demo app, the message „Search for app in the Store“ appears and nothing happens inside the app.
This happens because of the URI Scheme of these links: „unsafe:ms-appx://[appid]/www/index.html“. It can be solved by registering the URI schemes with Angular, by adding the following line to the .config-Function of app.js (line 25ff in the demo app):

.config(function($stateProvider, $urlRouterProvider, $compileProvider) {
    $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|ghttps?|ms-appx|x-wmapp0):/);
    ...
})

3. Hidden elements (ng-show / ng-hide) are still visible

ng-show and ng-hide hide elements by adding the CSS-class „ng-hide“ to the affected elements.
It seems like the necessary stylesheets are not added to the document automatically, so we need to add the following rule explicitly in the stylesheet (eg. in css/style.css):

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak,
.x-ng-cloak, .ng-hide:not(.ng-hide-animate) {
    display: none !important;
}

4. Scrolling does not work

Unfortunately, this problem seems to be much more complex and I did not find a real solution until now.
However, adding the following CSS-rule to the stylesheets enables the browser-internal scrolling, which works surprisingly well:

body.platform-windowsphone .scroll-content,
body.platform-windowsphone8 .scroll-content {
    overflow: auto;
}

This is just a dirty hack, though, and probably breaks a couple of things.

5. Not fixed yet: Back Button

With Windows Phone 8.0, listening on the „backbutton“ event was pretty simple, just as with android. On WP8.1, this event is not triggered anymore.
I haven’t figured out how to enable it yet. Any hint would be appreciated.

6. Not fixed yet: Hover/Touch effect is permanent

When starting a touch gesture on a link without clicking it (e.g. when starting to scroll), the hover effect is not disabled afterwards.
This is probably related to the scrolling issue.

OpenRIS – Konzept und aktueller Stand

Vor gut zwei Jahren hatte ich schon einmal etwas zu meinem „Pet Project“ rund ums Münchner Ratsinformationssystem geschrieben. Leider lag das das Projekt danach für eine ganze Weile brach, insbesondere da die Klärung der rechtlichen Aspekte im Getriebe wechselnder Zuständigkeiten in der Münchner Verwaltung im Sande verlaufen ist. In den letzten Monaten habe ich aus zwei Gründen wieder mehr Elan gefunden, um das Projekt voranzutreiben: zum einen habe ich, seit ich in den Laimer Bezirksausschuss gewählt wurde, seit Mai fast täglich das „Vergnügen“, mit dem Münchner Ratsinformationssystem in Berührung zu kommen, Aggro-„Das geht doch besser!“-Reflexe inklusive. Zum anderen habe ich, ebenfalls seit Mai, über die „OK Labs“ der Open Knowledge Foundation ein gutes organisatorisches Umfeld gefunden, in dem man das Projekt aufhängen kann, um es zu mehr als nur meinem Privat-Projekt zu machen.

Der Name „OpenRIS“ ist ein reiner Arbeitstitel, ich werde den Namen dementsprechend austauschen, sobald es einen endgültigen Titel gibt.

Welche Probleme soll das Projekt lösen?

Das Ratsinformationssystem (RIS) bietet eine unglaubliche Zahl an Dokumenten rund um den Münchner Stadtrat und die Bezirksausschüsse (BAs), von Sitzungsvorlagen, Tagesordnungen und Niederschriften hin zu Stadtratsanträgen und – noch wichtiger, da meist noch informativer – den Stellungnahmen der Referate dazu. Geschätzt knapp 140.000 Dokumente. Nur: es ist furchtbar unübersichtlich und unpraktisch. Zur Einführung als neu gewählte Bezirksausschussmitglieder bekamen wir eine zehnseitige bebilderte Anleitung, wie man darin Beschlüsse finden kann – was für die Hilfsbereitschaft der Stadtverwaltung spricht, aber nicht gerade für die Usability des RIS, das ja eigentlich die Politik den BürgerInnen gegenüber transparent machen soll. Wichtige Funktionen fehlen, und eine nur schlecht funktionierende Volltextsuche rundet die Sache ab.

Kernfunktionen

OpenRIS soll einerseits die gezielte Volltextsuche nach Themen durch einen zentralen Suchindex erleichtern, der sich unabhängig vom Dokumenttyp mit der von Suchmaschinen her bekannten Syntax durchsuchen lässt – auch bei Dokumenten, die nur in gescannter Form vorliegen (OCR).

Vor allem aber soll es OpenRIS interessierten BürgerInnen leichter machen, auf dem Laufenden zu bleiben – zu konkreten Sachthemen sowie zu allen Angelegenheiten, die sich um ihr Wohngebiet (z.B. ihren Stadtteil) drehen. Dafür gibt eine Timeline-Ansicht aller Dokumente, die sich entweder auf die Stadt allgemein oder auf einen konkreten Stadtteil beziehen. Gefundene Dokumente werden anhand enthaltener räumlicher Bezugspunkte auf einer Karte eingezeichnet. Zentral ist dabei eine Benachrichtigungsfunktion: es ist möglich, zu einer Suche (sowohl im Volltext als auch zu Metadaten wie Stadtteilbezug) eine Benachrichtigung per E-Mail einzurichten, sodass man informiert wird, sobald es neue Dokumente gibt, die diesen Kriterien entsprechen.

OpenRIS wird aber nicht (wie z.B. Offenes-koeln.de) die Dokumente selbst anbieten – sondern stattdessen schlicht auf die Dokumente im Original-RIS verlinken.

Welche Probleme kann das Projekt nicht lösen?

OpenRIS kann keine Dokumente auffindbar machen, die nicht ohnehin schon im (öffentlichen) Ratsinformationssystem zu finden sind. Es kann also nichts daran ändern, wenn Dokumente gar nicht oder nur mit größerer Verzögerung online gestellt werden. Letzteres scheint leider gerade im Umfeld von Bezirksausschüssen sehr häufig vorzukommen.

Komponenten

OpenRIS besteht aus mehreren Teilen, die konzeptionell voneinander unabhängig sind und teils auch nicht alle zu Beginn eingebaut sein werden.

Scraping

Da das offizielle Ratsinformationssystem keine API anbietet, über welche die Metadaten abrufbar sind, ist der erste Schritt ein Scraping-Mechanismus, der die öffentlich zugänglichen HTML-Seiten des Ratsinformationssystems in eine normalisierte SQL-Datenbank umwandelt. Jede Menge Regular Expressions kommen hier zum Einsatz, die in folgendes Datenmodell bespielen:

schema

Beim aktuellen Entwicklungsstand werden die Metadaten der Stadtratsanträge, Stadtratsvorlagen, Stadtrats(ausschuss)sitzungen, BA-Anträge, BA-Initiativen, BA-Sitzungen, Bürgerversammlungsempfehlungen, und die Liste der Stadtrats- und BA-Mitglieder erfasst, sowie die Beziehungen untereinander. Bei den Versammlungen werden insbesondere auch die Tagesordnungspunkte strukturiert erfasst und die gefassten Beschlüsse indiziert. Ich versuche dabei auch, einige der technischen Probleme des offiziellen RIS zu umschiffen – beispielsweise die Encoding-Probleme (langgezogene Bindestriche sowie deutsche Anführungszeichen im Titel werden grundsätzlich als Fragezeichen dargestellt; mein Nachname entwickelt eine ganz eigene Ästhetik).

Noch nicht erfasst werden u.a. Mitgliedschaften von Personen in einzelnen Gremien, die Metadaten zu den einzelnen ReferentInnen, und vereinzeln Angaben wie beispielsweise Positionen / Funktionen von Stadtratsmitgliedern.

Das Scraping bezieht sich dabei nur auf die Metadaten, also beispielsweise, wer wann einen Antrag gestellt hat sowie den Titel des Antrags – nicht aber den tatsächlichen Text des Antrags. Während die Metadaten am Ende auch über OpenRIS abrufbar sein sollen (z.B. auch über eine API), wird das bei den vollen Texten der Anträge und Vorlagen nicht der Fall sein, da das im Gegensatz zu den Metadaten möglicherweise Urheberrechte berühren könnte.

Volltextindex & Suche

Ähnlich wie bei gängigen Web-Suchmachinen wird ein Volltextindex aller gefundener Dokumente aufgebaut, in dem nach Schlüsselwörtern und Metadaten gesucht werden kann. Als Software kommt hier Apache Solr zum Einsatz. Wird ein Dokument über die Volltextsuche gefunden, wird ein Snippet angezeigt, nicht aber der gesamte Text des Dokuments – statt dessen wird einfach die Originaldatei verlinkt, was im Münchner RIS (anders als z.B. beim Kölner) ohne Probleme möglich ist.

Der Text wird auf zwei Wegen aus den Dokumenten ausgelesen: bei regulären PDF-Dateien, in denen der Text auch als solcher gespeichert wird, wird der Text mittels Apache PDFBox extrahiert (was bei meinen Tests zuverlässiger funktionierte als das verbreitetere pdf2text). Da sich unter den Dokumenten aber auch viele TIFF-Dateien und PDFs mit nur gescannten Bildern befinden, wird grundsätzlich jedes Dokument zusätzlich noch durch zwei OCR-Programme verarbeitet: zunächst das freie Tesseract, das passable Ergebnisse liefert und sich als Kommandozeilentool leicht automatisch einbinden lässt. In einem zweiten Schritt dann noch durch das kostenpflichtige OmniPage Ultimate, das in meinen Tests sehr viel bessere Ergebnisse lieferte als Tesseract, sich als reines Windows-Programm aber nur sehr eingeschränkt automatisieren lässt (zumindest in der noch bezahlbaren Version).

Aus dem Volltext der Dokumente wird dann noch versucht, Ortsbezüge herzustellen, indem im Text nach bekannten Straßennamen gesucht wird, ggf. mit den folgenden Hausnummern, und diese Angaben dann durch eine der vielen gängigen Geocoding-Webservices in Geodaten umgewandelt werden. Das funktioniert zurzeit nur so semi-toll; zwar gut genug, dass es einen wirklichen Mehrwert bietet – aber leider noch mit vielen fehlerhaften Treffern. Sei es weil eine Straße in einer anderen Stadt mit dem selben Namen wie eine Münchner Straße erwähnt wird, sei es, dass die „str.“-Abkürzung nicht immer für „Straße“ steht, sondern gerne auch mal für „Stadtrat“ und dadurch Missverständnisse entstehen. Das Problem haben auch vergleichbare Projekte anderer Städte wie beispielsweise „Offenes Köln“, sodass die Optimierung dieses Algorithmus ein lohnenswertes, für sich alleine stehendes Projekt sein könnte.

Diese Komponente ist inzwischen funktional weit gehend benutzbar (um das Wort „fertig“ vermeiden, das bei Web-Projekten bekanntermaßen nie zutrifft).

Web-Interface

Ein Großteil der Arbeit fließt momentan in das Web-Interface, über das neue Dokumente angezeigt und auf einer interaktiven Karte verzeichnet werden, Informationen zur Zusammensetzung des Stadtrats und der Bezirksausschüsse, eine Volltextsuche, usw. Technisch ist daran wenig Spannendes.

Ich erwähne dabei nur mal, dass ich vom einbettbaren Kartenmaterial von Skobbler sehr angetan bin, insbesondere da es auf den Daten von Openstreetmap basiert, die meinem Empfinden nach sehr viel detaillierter als Google Maps & co sind, in der fertig gerenderten Fassung aber meist große „ästhetische Defizite“ aufweist. Von der Kombination Leaflet.js + Skobbler bin ich sehr angetan, insbesondere seit letzteres auch Retina-kompatible Grafiken ausliefert.

Die spannendste Funktion des Web-Interface wird sicher die Möglichkeit sein, sich E-Mail-Benachrichtigungen einrichten zu können. Das funktioniert so, dass jede Suchanfrage (z.B. eine Kombination aus Stadtteilbezug und einem Suchbegriff, oder dem initiierenden Stadtratsmitglied) gespeichert und einer E-Mail-Adresse zugeordnet werden kann. Immer wenn ab dann dem Volltextindex neue Dokumente hinzugefügt werden, wird überprüft, ob es gespeicherte Suchanfragen gibt, die auf das neue Dokument zutreffen – und der Inhaber wird benachrichtigt. Darüber hinaus soll es auch möglich sein, einzelne Anträge zu abonnieren, um dann entweder über neue Dokumente zu diesem Antrag benachrichtigt zu werden (z.B. wenn ein Referat eine Anfrage beantwortet), oder über Statusänderungen (z.B. wenn der Antrag einer konkreten Sitzung zugeordnet wird).

E-Mail ist dabei die naheliegendste Benachrichtigungsform – andere Formen wie beispielsweise GCM oder APS für Android/iOS-Apps wären aber für die Zukunft auch denkbar.

Alternativ zu den Benachrichtigungen soll es die Suchergebnisse zu bestimmten Suchanfragen auch in Form von RSS-Feeds geben.

Das Web-Interface ist zurzeit aber noch sehr Alpha, und da sich hier einerseits noch Leute vom „OK Lab“ einbringen wollen, und ich das andererseits auch mindestens noch einer Person, die von Design mehr versteht als ich vorlegen will, dürfte da noch sehr viel passieren.

OParl-API

Seit einigen Monaten gibt es die OParl-Initiative, die einen offenen Standard zum Abruf von Daten aus parlamentarischen Informationssystemen erstellt – der erste Entwurf, wurde im Mai 2014 veröffentlicht. Über OParl wäre es beispielsweise möglich, mobile Apps zu entwickeln, welche auf die Daten verschiedener Ratsinformationssysteme zugreifen kann. Der Standard beschränkt sich momentan recht stark auf die Modellierung des Datenmodells und bietet einige wenige Anfragetypen an.

Meiner ersten Einschätzung nach ist das OParl flexibel genug, um die Datenstruktur des Münchner RIS abzubilden (insb. auch die recht spezielle Konstellation mit Stadtrat und Bezirksausschüssen). Daher bietet es sich an, diese API auch in OpenRIS zu implementieren. Diese API würde ausschließlich auf die Metadaten aufsetzen, die durch das Scraping gewonnen werden, da eine Volltextsuche derzeit vom OParl-Standard noch nicht vorgesehen zu sein scheint, und der Volltextabruf über OpenRIS aus den oben genannten Gründen voraussichtlich nicht möglich sein wird.

Für viele praktische Anwendungsfälle, wie die genannte Volltextsuche, eine Suche nach Ortsbezug, oder eine Benachrichtigungsfunktionalität, wird es aber „proprietäre“ Erweiterungen der API benötigen, bis sich diese vielleicht in einer zukünftigen Version von OParl wiederfinden.

BürgerInnenbeteiligung

Bei den OK Labs (und auch den inoffiziellen Vorgängern, den MOGDy-Treffen) kamen eine ganze Reihe an Ideen, die Plattform um interaktive, bis hin zu partizipativen Komponenten zu ergänzen. Ein Vorbild dafür ist „Frankfurt Gestalten“, über das BürgerInnen eigene Initiativen online stellen können. Ein Knackpunkt für solche Plattformen ist aber die Rückkopplung in die Stadtverwaltung bzw. -politik hinein: in einem Blog-Posting vom Mai ’14 beklagen die Betreiber von Frankfurt Gestalten auch genau diesen fehlenden Rückkanal als großen Nachteil ihrer Plattform. Wenn OpenRIS um eine solche Komponente ergänzt werden soll, wird daher sehr viel Arbeit in die Ausarbeitung eines Konzepts fließen müssen, damit am Ende keine Plattform entsteht, die BürgerInnenbeteiligung nur vorgaukelt – und sich auch von den bestehenden Angeboten (wie beispielsweise das bis vor kurzem laufende „Direkt zu Ude“, oder den Gefahrenatlas der Süddeutschen) abzuheben.

Vergleichsweise einfach wären dagegen Ideen, wie sie Georg Kronawitter in einem Stadtratsantrag vor einigen Jahren schon formulierte.

Statistische Daten

Eine weitere Möglichkeit, OpenRIS weiter auszubauen, wäre, statistische Daten mit zu integrieren, um eine gemeinsame Plattform zu haben, um solche Stadtbezogene Informationen anzubieten. Relevant dürften dabei insbesondere die Zahlen des Statistischen Amts München sein.

Entwicklung

Angaben dazu, wann das Projekt live geht, mache ich besser nicht mehr – mit „kommt jetzt wirklich bald“ habe ich mich schon vor zwei Jahren in die Nesseln gesetzt.
Den Quelltext des aktuellen Entwicklungsstands gibt es aber schon auf Github, und das Projekt wird natürlich auch unter eine OpenSource-Lizenz gestellt.

Animexx Event-App

Animexx Event-App

GooglePlay_130x45
AppStore_135x40

Die Event-App, die ich für den Animexx geschrieben habe, ist nun sowohl im Apple AppStore als auch auf Google Play verfügbar. Sie deckt einen Großteil der Funktionalität des Animexx-Eventkalenders ab, unter anderem:

  • Den Eventkalender nach Ort, Name und Gebiet durchsuchen und auf aufgerufene Events dann auch offline wieder zugreifen.
  • Man kann öffentlich bekannt geben, dass man zu einem Event geht.
  • Der Programmplan des Events ist über die App zugänglich, man kann sich auch für einzelne Programmpunkte eintragen.
  • Wenn es etwas Neues gibt, wird man aktiv über Push-Nachrichten darüber benachrichtigt – beispielsweise wenn ein Event, für das man sich eingetragen hat, auf Animexx eine neue News veröffentlicht, wenn sich ein Programmpunkt, für den man sich eingetragen hat, verschiebt, oder wenn es ein Neues Event einer abonnierten Eventreihe gibt.
  • Man kann Fotos zu einem Event anschauen, kommentieren, sich auf Fotos eintragen, auf denen man zu sehen ist und Bekannte auf Fotos „petzen“.
  • Eventkommentare schreiben und Eventberichte anderer Nutzer lesen und kommentieren.
  • Die wichtigsten Informationen der Steckbriefe der eigenen Bekannten einsehen, sowie Gästebucheinträge verfassen.
  • Event-bezogene Microblog-Nachrichten schreiben, mit Foto-Anhang.
  • Den Treffpunkt des Events kann man sich auf einer Karte anzeigen lassen, auf Wunsch auch in der Standard-Kartenanwendung (Google bzw. Apple Maps).
  • Conhopperorden am Animexx-Stand abholen (über einen QR-Code).

screenshot1screenshot2screenshot3

Die App ist hauptsächlich in HTML5 / JS / SASS geschrieben und per Cordova ins iOS/Android-App-Format gebracht.

manga-dō – der Weg des manga vom japanischen Holzschnitt zu Manga und Anime

Seit heute läuft in Münchner Kulturzentrum Gasteig die zweiwöchige Ausstellung „manga-dō – der Weg des manga vom japanischen Holzschnitt zu Manga und Anime“. Da ich als Vertreter des Animexx e.V. bei den Vorbereitungen der Ausstellung und des Begleitprogramms beteiligt war, will ich hier dazu auch ein paar Worte verlieren.

Gleich vorweg: den mit weitem Abstand größten Teil der Organisation und inhaltlichen Vorbereitung übernahm Günter Beck, Fotograf und Sammler japanischer Bildkultur, der einen Großteil der Ausstellungsstücke aus seiner privaten Sammlung zur Verfügung stellte und wie nebenbei noch Flyer und Plakate gestaltete sowie das Begleitheft zur Ausstellung in Eigenregie produzierte.

Das ganze Projekt wurde schon seit der zweiten Hälfte 2012 geplant, auch getrieben durch die Initiative von Dr. Freddy Litten (mit dem ich letztes Jahr auch schon einen Podcast zur Geschichte des Anime aufgenommen hatte). Sofort mit im Boot waren die Münchner Volkshochschule, die Münchner Stadtbibliothek und der Gasteig, die vor über zehn Jahren schon einmal eine Manga-Ausstellung ausgerichtet hatten und dabei wohl gute Erfahrung gemacht hatten.

11930059
11930069

Den Mittelpunkt der ganzen Aktion ist die Ausstellung, vor allem die vielen Historischen Exponate von Günter Beck. Hier werden in Vitrinen und Bildergalerien verschiedenste Zeichnungen und Gegenstände gezeigt, von Holzschnitten und historische Schriftrollen über „Japan Punch“-Ausgaben hin zu (inzwischen auch schon fast historischen) Anime-Cels und natürlich modernen Manga-Tankōbon. Nicht ausgespart werden dabei die „Shunga“ („Frühlingsbilder“), erotische Bilder, die in einem räumlich leicht abgetrennten Bereich präsentiert werden.

11930065
11930055

Vom Animexx kommen die Vitrinen zur „Cross-Medialität“ des Manga, in denen exemplarisch die Vernetzung des modernen Manga mit anderen Medien-Gattungen dargestellt werden soll. Da Anime und Dōjinshi schon an anderer Stelle behandelt werden, geht es hier um Manga-Realverfilmungen, Musicals, Cosplay, Light Novels, Visual Novels, Figuren und Model-Kits und J-Pop/-Rock. Das Prinzip ist dabei, dass jeweils zu einer konkreten Serie der Manga sowie das jeweils andere Medium präsentiert wird, damit dadurch die Umsetzung des Stoffes sichtbar wird. Aufgelockert wird das ganze noch durch diverses Merchandise.

An dieser Stelle auch ein Dankeschön an sakura_b, die für die Ausstellung ihr Jeanne-Kostüm, und  lore,  Kathal und  Ani, die ihre Figuren zur Verfügung gestellt haben.

1193008111930077

Es gibt aber nicht „nur“ die Ausstellung, sondern auch ein Rahmenprogramm, das über die zwei Wochen verteilt im Gasteig stattfindet. Besonders erwähnenswert ist dabei die Eröffnungsveranstaltung, die kommenden Samstag, den 25. Januar ab 18:00 Uhr stattfindet und darauf angelegt ist, ein Hauch von Con-Feeling zu vermitteln: neben einem kurzen Vortrag vom Comic-Journalisten Harald Havas (der eher aus der „klassischen“ Comic-Szene kommt, dessen unterhaltsame Vorträge im Rahmen des Comic-Salons Erlangen wir zu schätzen gelernt haben) wird es eine Show-Einlage der Tsuki no Senshi geben, sowie anschließend eine thematisch passendes Videoprogramm: wir zeigen die ersten vier Folgen von „Bakuman“, das durch die Thematisierung des Entstehungsprozesses moderner Manga gut zur Ausstellung passt (die Lizenzierung der Episoden war dank der Unterstützung von Anime on Demand dann auch gar nicht so umständlich, wie man es Lizenzverhandlungen ansonsten üblicherweise nachsagt).

Daneben gibt es noch eine Reihe an Vorträgen im Rahmen des Münchner Volkshochschule, die insbesondere auch für „fortgeschrittene Fans“ interessant sein dürften:

Bei „Tatsumi“ handelt es sich um einen Animationsfilm aus Singapur, der auf dem autobiografischen Manga „A Drifting Life (劇画漂流 Gekiga Hyōryū)“ von Yoshihiro Tatsumi basiert, einem der wichtigsten Vertreter des Gekiga-Mangas.

Ein Grund, eine der Veranstaltungen zu besuchen, ist übrigens, dass es hier auch die kostenlosen 42seitigen Begleithefte zur Ausstellung gibt, die noch eine Menge an zusätzlichen Informationen und Abbildungen beinhalten.

Noch ein paar mehr Fotos insb. vom Aufbau gibt es in meiner Fotogalerie.