Benutzer:Johannes Kroll (WMDE)/TLG Filterentwicklung Howto-de

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

(English version here)

Erstellen eines Filters für den Task List Generator

[Bearbeiten | Quelltext bearbeiten]

Der Task List Generator kann durch Filtermodule erweitert werden. Dazu wird eine Filterklasse erstellt und im Programm registriert. Der Filtercode wird in einer separaten Datei gespeichert. Änderungen im Rest des Programms sollten nicht notwendig sein.

Dieses Howto ist noch ein bisschen vorläufig. An manchen Stellen sind Dinge noch nicht so verlinkt, wie sie sein sollten. Trotzdem sollte es ausreichen, um einen Filter zu schreiben. Wenn etwas unklar ist, kann man nich natürlich auch fragen (s.u.).

Die Filtermodule befinden sich im Unterverzeichnis filtermodules. Jedes Filtermodul kann eine oder mehrere Filterklassen enthalten.

Jede Filterklasse erbt von [doxygen#FlawFilter FlawFilter]. Damit der Filter zugeordnet werden kann, muss jede Filterklasse die Attribute shortname, description und label enthalten (siehe Beispielcode). Jede Filterklasse wird beim Laden eines Filtermoduls durch Aufruf von FlawFilters.register() verfügbar gemacht.

Filter-Aktionen

[Bearbeiten | Quelltext bearbeiten]

Der TLG sucht zuerst nach dem im Frontend angegebenen Suchstring. Das Ergebnis ist eine Liste von page_id-Werten (Index in die Wiki-Datenbank). Die page_ids werden von Filteraktionen verarbeitet. Eine Methode in der Filterklasse erzeugt dazu eine Klasse, die von TlgAction erbt. Pro Aktion werden in der Regel mehrere page_ids verarbeitet ([doxygen#getPreferredPagesPerAction getPreferredPagesPerAction]-Methode).

MySQLdb-Cursor müssen für jeden Thread im TLG separat gehalten werden. Alle Cursor benutzen die DictCursor-Klasse.

Cursor für das im Frontend gewählte Wiki

[Bearbeiten | Quelltext bearbeiten]

SQL-Verbindungen und -Cursor für das gewählte Wiki sind für jeden Thread verfügbar und können im Kontext der Aktions-Klasse mit utils.getCursors()[self.wiki] abgefragt werden.

Sonstige Cursor

[Bearbeiten | Quelltext bearbeiten]

Wenn Cursor zu anderen Datenbanken benötigt werden, sollte die TempCursor-Klasse mit dem with-Statement verwendet werden. Die Cursor werden für jeden Thread zwischengespeichert und bei Nichtverwendung automatisch aufgeräumt. Ein Beispiel für die Verwendung findet sich in changedetector.py.

Utility-Funktionen und Caching

[Bearbeiten | Quelltext bearbeiten]

Für einige Datenbank-Abfragen existieren Funktionen in [doxygen utils.py]. Diese benutzen beaker.cache um die Ergebnisse zwischenzuspeichern. Damit unnötige Serveranfragen vermieden werden, sollten diese Funktionen benutzt werden, anstatt z. B. die gleichen SELECT-Statements neu zu schreiben.

Es folgt der Code für einen einfachen Filter, der alle Seiten findet, die heute geändert wurden. Dazu wird das page_touched-Feld abgefragt.

recent.py

#!/usr/bin/python
# -*- coding:utf-8 -*-
import time
from tlgflaws import *

## Ein Filter, der alle Seiten findet, die heute geändert wurden.
class FRecentlyChanged(FlawFilter):
    shortname= 'RecentlyChanged'                # Name, der den Filter identifiziert (nicht übersetzen!)
    label= _('Recently Changed')                # Label, das im Frontend neben der Checkbox angezeigt wird
    description= _('Page was touched today.')   # Längerer Beschreibungstext für Tooltip
    group= _('Timeliness')                      # Gruppe, in die der Filter eingeordnet wird

    # Die Action-Klasse für diesen Filter
    class Action(TlgAction):
        
        # execute() filtert die Seiten und steckt Ergebnisse in resultQueue.
        def execute(self, resultQueue):
            cur= getCursors()[self.wiki]
            # Formatstrings für mehrere Seiten generieren.
            format_strings = ','.join(['%s'] * len(self.pageIDs))
            # Beginn des heutigen Tages im Format der Wikipedia-Datenbank
            today= time.strftime( '%Y%m%d000000', time.localtime(time.time()) )
            params= []
            params.extend(self.pageIDs)
            params.append(today)
            # Subset der Seiten finden, die heute geändert wurden
            cur.execute('SELECT * FROM page WHERE page_id IN (%s) AND page_touched >= %%s' % format_strings, params)
            changed= cur.fetchall()
            # Alle gefundenen Seiten zurückgeben
            for row in changed:
                resultQueue.put(TlgResult(self.wiki, row, self.parent))

    # Wir wollen 100 Seiten pro Aktion verarbeiten. 
    def getPreferredPagesPerAction(self):
        return 100

    # Eine Aktion erstellen.
    def createActions(self, wiki, pages, actionQueue):
        actionQueue.put(self.Action(self, wiki, pages))

# Beim Laden des Moduls den Filter registrieren:
FlawFilters.register(FRecentlyChanged)

GPL?

Internationalisierung

[Bearbeiten | Quelltext bearbeiten]

Strings, die der Benutzer sieht, sollten auf Englisch verfasst sein und in '_()' "geklammert" werden, damit sie mit gettext übersetzt werden können. Wer möchte, kann die Strings auch zusätzlich auf deutsch übersetzen. Dazu kann eine Textdatei mitgegeben werden im Format

msgid "Some text as it appears in the program"
msgtext "Text, wie er im Programm auftaucht"

Zum Testen der Filterklassen empfiehlt es sich, das Backend vom git-repository zu klonen und auf dem Toolserver auszuführen. Nicht vergessen, .htaccess in public_html anzupassen, sofern nötig.

Folgende Python-module müssen ggf. lokal installliert werden:

  • wikitools (easy_install --prefix=$HOME/.local wikitools)

Folgende Parameter können im GET-Request an tlgwsgi.py übergeben werden (Beispiel):

  • action
    • action=listflaws -- gibt die registrierten Filterklassen zurück
    • action=query -- fragt CatGraph nach Kategorien ab und testet gefundene Artikel auf Mängel.
      • lang=<string> -- Wiki-Sprache, momentan läuft eine CatGraph-Instanz für 'de'
      • query=<string> -- Suchstring für die Kategorien, Semikolon-getrennte Liste, '+' und '-' für Schnittmenge/Ausschluss
      • querydepth=<integer> -- Rekursionstiefe für die Kategoriesuche, die auf alle Kategorienamen angewendet wird
      • flaws=<string> -- Durch Leerzeichen getrennte Liste der Mängel, nach denen gesucht werden soll ("listflaws" für mögliche Mängel).
  • format=json/html/wikitext: Ausgabeformat wählen.
  • chunked=true: Chunked Transfer Encoding benutzen (dynamischer Seitenaufbau, mit Statusdisplay im HTML-Format). Empfehlenswert zum Debugging.
  • showthreads=true: Anzeigen, was gerade in den Worker Threads passiert. Empfehlenswert zum Debugging.
  • i18n=langcode: legt die Sprache der ausgegebenen Texte fest. Unterstützte Werte für langcode sind momentan "de", "en".

Wenn ein funktionierendes Filtermodul veröffentlicht werden soll, kann man es mir per Email (jkroll bei toolserver punkt org) oder github pull request zukommen lassen. Natürlich freuen wir uns auch über sonstige Anregungen und Ideen zum TLG. Wenn es Fragen oder Ideen zu diesem Text gibt, kann man mir natürlich auch eine Mail schreiben.