ubuntuusers.de

12. Januar 2017

Wie im letzten Beitrag geschildert, ist dieser Blog auf einen anderen Server umgezogen.

Aktuell teste ich noch alle Funktionen und versuche, die gefundenen Fehler zu bereinigen. An dieser Stelle möchte ich mich auch schon einmal bei all denen bedanken, die mich auf Fehler aufmerksam gemacht haben.

Heute wurde ich im Backend auf das WordPress-Update 4.7.1 aufmerksam, welches ich umgehend installieren wollte. Dabei forderte mich WordPress unerwartet auf, FTP-Zugangsdaten einzugeben, um das Update durchführen zu können.

Diese Meldung irritierte mich etwas, da ich diese Informationen auf dem alten Server nicht benötigte. Auf dem aktuellen Server läuft noch ein weiterer WordPress-Blog, welcher ebenfalls ohne Angabe dieser Verbindungsinformationen aktualisiert werden konnte.

Nach kurzer Internetrecherche fand ich die Lösung für mein Problem in dem Artikel WordPress Berechtigungen korrekt setzen (Problem mit FTP-Serverdaten Aufforderungen beheben) von Ansas Meyer. Ich habe wie dort beschrieben die Berechtigungen überprüft. Diese waren jedoch bereits korrekt gesetzt. Anschließend habe ich der Datei wp-config.php folgende Zeile hinzugefügt:

define('FS_METHOD', 'direct');

Anschließend konnte das Update wie gewohnt über das Backend eingespielt werden.

Die Ursache, die für die plötzliche Anforderung der Verbindungsinformationen verantwortlich ist, kenne ich leider immer noch nicht. Jedoch bin ich froh, dass ich dank des Artikels von Ansas die Folgen behandeln konnte.

Seit mehr als 20 Jahren verfasse ich nahezu alle meine Texte, Hunderte von Seiten jedes Jahr, mit dem Editor Emacs. Selten hat mich seither ein anderer Editor in Versuchung gebracht, zu wechseln. Zu den wenigen Ausnahmen zählt Atom. Der Editor ist schnell zu erlernen, hat eine moderne Oberfläche, läuft unter Linux/Windows/macOS. Außerdem ist es sehr weitreichend konfigurierbar, und das ganz ohne Emacs-Gruft und Elisp-Horror.

Dieser Beitrag stellt Atom kurz vor und zeigt seinen Einsatz als Editor für Markdown-Dokumente in der Pandoc-Variante.

Das Grundgerüst von Atom ist Electron, ein Software-Konglomerat, das im wesentlichen aus Chrome (für das HTML-Rendering und als JavaScript-Engine) und aus Node.js zusammengesetzt ist.

Pakete

Atom ist ein modular aufgebauter Editor. Alle Funktionen mit Ausnahme elementarer Grundfunktion sind in Form von Paketen realisiert. Standardmäßig sind bereits rund 80 Core-Pakete installiert. Welche das sind, verrät File/Settings bzw. Atom/Preferences (macOS) im Dialogblatt Packages.

Liste der installierten Packages in Atom unter macOS

Neue Pakete und Themes (die das Aussehen von Atom beeinflussen) können Sie im Dialogblatt Install der Einstellungen suchen und installieren. Dabei haben Sie aktuell die Wahl aus über 5000 Paketen.

Pakete können nach der Installation mühelos wieder entfernt oder auch nur deaktiviert werden. Außerdem sehen viele Pakete einen Settings-Button vor, um Einstellungen des Pakets zu verändern. Zur Bedienung der Pakete finden Sie im Menü Packages entsprechende Kommandos. In diesem Menü sind die Pakete alphabetisch geordnet. Neu installierte Pakete werden anfänglich am Ende des Menüs platziert, ab dem nächsten Neustart von Atom aber wieder in alphabetischer Reihenfolge angeordnet.

Markdown-Unterstützung ohne Konfiguration

Grundsätzlich kommt Atom mit Markdown-Dateien standardmäßig zurecht. Bei Dateien mit der Endung *.md führt Atom automatisch ein ganz brauchbares Syntax-Highlighting durch. Die Tastenkombination Shift+Ctrl+M öffnet neben dem Text ein Preview-Ansicht, die ebenfalls für viele Zwecke ganz passabel ist. Damit übertrifft Atom quasi aus dem Stand und ohne jede Konfigurationsarbeit den Funktionsumfang vieler Markdown-Editoren. Und ist darüber hinaus nahezu unbegrenzt erweiterungsfähig und konfigurierbar …

Atom-Editor unter Ubuntu-Linux im Default-Dark-Scheme. Links eine Markdown-Datei, rechts die Vorschau.

Mit den in meiner Datei (übrigens Kapitel 1 meines Swift-Buchs) inkludierten LaTeX-Anweisungen kommt freilich weder das Syntax-Highlighting noch die Vorschau zurecht.

Light oder Dark Theme

Nach der Installation zeigt sich Atom von seiner dunklen Seite, d.h. Text wird in weißer/heller Schrift auf schwarzem Hintergrund angezeigt. Das mag modern sein, ich bin aber kein Fan davon. Abhilfe: File/Settings bzw. Atom/Preferences (macOS), Dialogblatt Themes, dort UI Theme und Syntax Theme neu einstellen (z.B. auf One Light).

Neue Datei-Extension definieren

Aus historischen Gründen haben die meisten meiner Markdown-Dateien die Endung *.text. Natürlich könnte ich sie in *.md umbenennen, weniger Arbeit macht es aber, Atom die neue Endung einfach beizubringen. Dazu öffnen Sie die zentrale Atom-Konfigurationsdatei config.cson mit File/Config oder mit Atom/Config (macOS). Danach fügen Sie nach den schon vorhandenen Zeilen "*": und core: vier neue Zeilen ein:

"*":
  core:
    customFileTypes:
      "source.gfm": [
        "text"
      ]

Das bewirkt, dass die Dateierweiterung *.text der Programmiersprache gfm zugeordnet wird. gfm steht dabei für GitHub Flavored Markdown, also für die Markdown-Variante, die auf GitHub üblich ist und die von Atom standardmäßig unterstützt wird.

Markdown-Preview-Plus mit Pandoc

Alle Bücher, die ich seit 2013 neu geschrieben habe, sind mit Pandoc und LaTeX gesetzt. Prinzipiell verwende ich also Markdown, allerdings angereichert um Pandoc-spezifische Elemente, einige LaTeX-Kommandos und ein paar eigene Erweiterungen, die durch sed– und python-Scripts verarbeitet werden. Eine echte Kontrolle des endgültigen Erscheinungsbilds ist nur möglich, wenn ich die Markdown-Texte mit pandoc in LaTeX-Code umwandle und aus diesem dann in einem zweiten Schritt eine PDF-Datei erzeuge.

90% aller Layout-Elemente lassen sich aber auch in einer simplen HTML-Preview kontrollieren. Und das gelingt sogar direkt in Atom, wenn einige Voraussetzungen erfüllt sind:

  • Das standardmäßig aktive Package markdown-preview muss deaktiviert werden (Button Disable).
  • Stattdessen muss das Package markdown-preview-plus installiert werden.
  • Dessen entscheidender Vorteil besteht darin, dass es anstatt der simplen GitHub-Markdown-Engine auch Pandoc aufrufen kann. Dazu müssen einige Optionen des Package konfiguriert werden:
    • Option Enable Pandoc Parser aktivieren.
    • Option Pandoc Options: Path einstellen. Unter Linux und macOS können Sie den Pfad der Pandoc-Installation einfach in einem Terminal mit which pandoc ermitteln. Unter Windows müssen Sie mit dem Explorer danach suchen. Üblich ist C:\Program Files (x86)\Pandoc\pandoc.exe.

    • Option Pandoc Options: Commandline Arguments einstellen: Hier können Sie Optionen angeben, die an Pandoc übergeben werden sollen. Wichtig: Wenn Sie mehr als eine Option angeben möchten, müssen Sie die Optionen durch Kommata trennen, also z.B. --option1 bla, ---option2, --option3 meh. Die Option -c my.css ist nicht zulässig. Eine eigene CSS-Datei für die Vorschau bringt leider die gesamte Atom-Oberfläche durcheinander.

    • Option Pandoc Options: Markdown Flavor einstellen: Hier geben Sie an, welche Markdown-Variante pandoc verwenden soll. Standardmäßig gilt markdown-raw_tex+tex_math_single_backslash. Für meine Zwecke ist einfach markdown erforderlich, also gewissermaßen der Standard-Markdown-Dialekt von Pandoc.

Konfiguration des Packages »Markdown-Preview-Plus«, damit dieses Pandoc verwendet.

Der (für mich) offensichtlichste Vorteil der Preview-Funktion mit pandoc besteht darin, dass diverse LaTeX-Kommandos, die nur für das finale Drucklayout relevant sind, aus der Vorschau verschwinden. Es bleibt also quasi der reine Text übrig.

Atom unter Windows (Light Theme) mit Pandoc-Preview.

Mehr Markdown-Pakete

Die Markdown-Unterstützung in Atom endet nicht bei den hier präsentierten Packages. Es gibt unzählige weitere Packages, mit denen z.B. Textpassagen ein- und ausgeklappt werden können (markdown-folder), die Vorschau mit der Cursor-Position synchronisiert werden kann (markdown-scroll-sync) etc. Suchen Sie einfach im Install-Dialogblatt von Atom nach markdown!

Diverse Erweiterungspakete bieten Markdown-Zusatzfunktionen an.

LaTeX-Syntax-Highlighting

In meine Markdown-Dateien sind häufig »gewöhnliche« LaTeX-Kommandos eingebettet, von \index{bla} bis \newline. Schön wäre, wenn Atom diese eingebetteten Kommandos erkennen und beim Syntax-Highlighting entsprechend berücksichtigen könnte. Dazu habe ich keine Möglichkeit gefunden. Stattdessen markiert Atom das nächste Zeichen hinter einem \ färbig, so als wäre damit ein Sonderzeichen gemeint.

Das Paket language-pfm-enhanced verspricht ein besseres, Pandoc-kompatibleres Syntax-Highlighting als language-gfm. Offensichtlich kommt es mit gut mit mathematischen Formeln zurecht, die in den Markdown-Text integriert sind. Aber für meine Zwecke bietet language-pfm-enhanced keine spürbaren Vorteile.

Kurzum, hier gäbe es aus meiner Sicht noch Verbesserungsbedarf. (Wobei mir klar ist, dass das Parsen verschiedener Sprachen in einem Text — hier also Markdown, HTML und LaTeX — immer schwierig ist.)

Atom versus Emacs

Atom ist ein wirklich faszinierender Editor, insbesondere was die einfachen Erweiterungs- und Konfigurier-Möglichkeiten betrifft. Meinen Emacs ersetzt es mir momentan noch nicht: Atom bietet im Vergleich zu dem auf meine Bedürfnisse optimal konfigurierten Emacs aktuell keine klaren Vorteile. Ich bin mir ziemlich sicher, dass ich Atom mit ähnlichen Funktionen wie den Emacs konfigurieren könnte — nur wäre das sicherlich mit viel Probieren und stundenlanger Arbeit verbunden. So werde ich wohl bis auf weiteres bei meinem Standardeditor bleiben.

Stünde ich aber heute vor der Entscheidung, mich in einen Editor neu einzuarbeiten, würde ich Emacs und Vi wohl links liegen lassen und mein Glück mit Atom versuchen.

Quellen

Grep ist wohl das Standardtool um den Inhalt von Dateien zu durchsuchen. Allerdings braucht man oft sehr viele Geduld. Für Ungeduldige gibt es ripgrep.

Ripgrep ist eine Alternative zu grep, welche in Rust geschrieben ist und die in vielen Fällen deutlich schneller zu einem Ergebnis kommt als grep. Bei ersten Tests konnte ich deutliche Unterschiede feststellen. Ich habe spaßeshalber einmal das ganze Homeverzeichnis meines Notebooks durchsucht.

grep -Ir Rybka /home/XYZ
/home/XYZ/Downloads/bundle.ini:[Rybka 2.2 32 bit]
/home/XYZ/Downloads/bundle.ini:ExeName=Rybka v2.2n2.mp.w32.exe
/home/XYZ/Downloads/bundle.ini:RelPath=\Engines\Rybka
/home/XYZ/Downloads/bundle.ini:[Rybka 2.2 64 bit]
/home/XYZ/Downloads/bundle.ini:ExeName=Rybka v2.2n2.mp.x64.exe
/home/XYZ/Downloads/bundle.ini:RelPath=\Engines\Rybka
/home/XYZ/Downloads/engines.ini:Rybka=Vasik Rajlich;USA
grep -Ir Rybka /home/XYZ 0,61s user 4,36s system 18% cpu 27,098 total
time rg -uu Rybka /home/XYZ
/home/XYZ/bundle.ini
23:[Rybka 2.2 32 bit]
24:ExeName=Rybka v2.2n2.mp.w32.exe
26:RelPath=\Engines\Rybka
32:[Rybka 2.2 64 bit]
33:ExeName=Rybka v2.2n2.mp.x64.exe
35:RelPath=\Engines\Rybka

/home/XYZ/Downloads/engines.ini
2666:Rybka=Vasik Rajlich;USA
rg -uu Rybka /home/XYZ 0,44s user 0,52s system 375% cpu 0,256 total

Wie man sieht, ist ripgrep hier leicht schneller. Andrew Gallant, der Entwickler von ripgrep, hat auf seinem Blog einen ausführlichen Artikel veröffentlicht, in dem neben diversen anderen Benchmarks genauer auf ripgrep eingegangen wird. Unter anderem auch für wen ripgrep eher nicht geeignet ist.

12 is better than 6 ist ein schneller 2D Top-Down-Shooter. Man spielt einen mexikanischen Revolverhelden, der im Süden der USA gejagt wird. In vielen kurzen Missionen gilt es jeweils, das Ende der Karte zu erreichen und dabei viele Gegner zu besiegen. Das ist gar nicht so einfach, denn sowohl die Gegner, Kugeln als auch die eigene Figur sind sehr schnell, und schon ein voller Treffer tötet. Gleichzeitig müssen Waffen manuell geladen, Revolver sogar nach jedem Schuss gespannt werden. Das erfordert Übung.

Gerade am Anfang ist es hilfreich, dass Gegner auch schleichend mit einem Messer erledigt werden können, das macht manche Karten wesentlich einfacher. Außerdem kann man Dynamit werfen, um mehrere Gegner auf einmal auszuschalten. Später im Spielverlauf gibt es Upgrades zu kaufen, z.B. eine Panzerweste oder mehr Platz für Munition.

Es ist ein mittelmäßiges Spiel. Die Spielmechanik selbst ist spaßig und fordernd, die gezeichnete Grafik originell, die Musik ebenfalls, wenn sie sich auch zu oft wiederholt. Die Story ist dagegen nur ansatzweise motivierend, das Ende sogar richtig schlecht, als sei dem Entwickler die Zeit ausgelaufen. Von den Upgrades hätte es mehr geben können. Am meisten stört mich, dass es für die Zufallsbegegnungen auf der Weltkarte zu wenige, sich daher immer wiederholende Karten mit fester Gegnerpositionierung gibt. Wobei die schlecht geschriebenen Gespräche vielleicht noch störender sind. Dafür läuft das Spiel mit dem freien Radeon-Treiber einwandfrei unter Linux. Die 2€, die es zur Zeit im Sondarangebot auf Steam kostet, ist es daher durchaus wert.

Mozilla rollt die neue Multiprozess-Architektur von Firefox nach und nach für mehr Anwender aus. Ein Kritierum sind dabei die installierten Erweiterungen. Mit Firefox 51 markiert Mozilla 773 weitere Add-ons als kompatibel.

Die neue Multiprozess-Architektur Electrolysis, kurz: e10s, ist seit Firefox 48 für erste Nutzer standardmäßig aktiviert, welche bestimmte Kriterien erfüllen. Unter anderem durfte der Anwender keine Erweiterungen installiert haben. In Firefox 49 waren erstmals ein paar von Mozilla ausgesuchte Erweiterungen plus WebExtensions zugelassen. In der aktuellen Version 50 qualifizieren schließlich alle Erweiterungen für die Nutzung von e10s, welche von ihrem Entwickler explizit als kompatibel mit der Multiprozess-Architektur markiert worden sind. Einzige Ausnahme stellt Tab Mix Plus dar, welches trotz entsprechender Markierung durch den Erweiterungs-Entwickler die Aktivierung von e10s verhindert. Diese Einschränkung wird in Firefox 52 aufgehoben werden.

Während der Beta-Phase von Firefox 51 hatte Mozilla neben WebExtensions alle Add-ons gemeinsam mit e10s erlaubt, welche von ihren Entwicklern nicht explizit als nicht kompatibel markiert worden waren. Für die finale Version von Firefox 51 möchte man diese Restriktion noch nicht so weit aufheben, weil dies für zu viele Nutzer auf einmal e10s aktivieren würde.

Stattdessen erlaubt man in Firefox 51 (erscheint am 24. Januar) zusätzlich zu allen WebExtensions und Add-ons, die von ihren Entwicklern explizit als kompatibel markiert worden sind, alle weiteren Add-ons, welche während der Beta-Phase von Firefox 51 mindestens 50 Nutzer hatten. In Zahlen ausgedrückt sind im Vergleich zu Firefox 50 damit 773 weitere Add-ons ab Firefox 51 gemeinsam mit der Multiprozess-Architektur nutzbar.

Wer herausfinden möchte, ob seine installierten Erweiterungen Teil dieser Liste sind, findet auf der Seite about:support eine Liste aller installierten Erweiterungen samt ihrer IDs und kann diese mit der unten stehenden Liste abgleichen. Einen allgemeinen Überblick über den Rollout-Plan der Multiprozess-Architektur gibt es hier.

Dies ist die Liste der IDs der 773 neu erlaubten Add-ons, alphabetisch sortiert:

Update 23.01.2017
Mozilla hat die Liste für die finale Version von Firefox 51 um drei Add-ons auf 770 Add-ons reduziert. Entfernt wurden 1Password, Self-Destructing Cookies sowie Amazon Assistant.

2.0@disconnect.me (Version 3.15.3.1-signed.1-signed oder höher)
2020Player_IKEA@2020Technologies.com (Version 5.0.94.1 oder höher)
2020Player_WEB@2020Technologies.com (Version 5.0.94.0 oder höher)
53ffxtbr@www.dailyfitnesscenter.com (Version 7.36.8.15623 oder höher)
5aa55fd5-6e61-4896-b186-fdc6f298ec92@mozilla (Version 0.1.2.1-signed oder höher)
6asa42dfa4784fsf368g@youtubeconverter.me (Version 0.1 oder höher)
86ffxtbr@download.yourvideochat.com (Version 7.36.8.15938 oder höher)
@90B817C8-8A5C-413B-9DDD-B2C61ED6E79A (Version 1.09 oder höher)
@A3592ADB-854A-443A-854E-EB92130D470D (Version 1.08.8.88 oder höher)
@autofillanyforms-easytatkal (Version 7.51.0 oder höher)
@chomikuj (Version 1.2.0 oder höher)
@com.virtualjame.disableads (Version 0.1.0 oder höher)
@Converter (Version 4.1.0 oder höher)
@DiscreteSearch (Version 0.2.1 oder höher)
@DownloadManager (Version 0.2.1 oder höher)
@E9438230-A7DF-4D1F-8F2D-CA1D0F0F7924 (Version 1.08.8.66 oder höher)
@Email (Version 4.0.12 oder höher)
@FormsApp (Version 0.2.0 oder höher)
@google-translate-menu (Version 1.0.1 oder höher)
@greatdealz (Version 0.0.3 oder höher)
@greatdealzu (Version 0.0.3 oder höher)
@irctctatkal (Version 2.0.0 oder höher)
@jetpack-easy-turism2 (Version 7.1.0 oder höher)
@kikikokicicidada (Version 2.1.2 oder höher)
@lottadealsun (Version 0.0.1 oder höher)
@Maps (Version 4.0.0 oder höher)
@mendeleyimporter (Version 1.6.8 oder höher)
@mysmartprice-ff (Version 0.0.6 oder höher)
@News (Version 0.2.0 oder höher)
@offersolymp (Version 0.0.2 oder höher)
@Package (Version 0.2.0 oder höher)
@pdfit (Version 0.1.9 oder höher)
@phextension (Version 6.0.2 oder höher)
@Radio (Version 0.2.0 oder höher)
@Recipes (Version 0.2.0 oder höher)
@safesearchincognito (Version 0.1.8 oder höher)
@searchincognito (Version 0.1.0 oder höher)
@searchlock-fx (Version 1.1.6 oder höher)
@simplepopupblocker (Version 1.2.1 oder höher)
@stopads (Version 0.0.4 oder höher)
@stremio (Version 1.0.2 oder höher)
@thebestyoutubedownloader (Version 1.0.0.7 oder höher)
@true-key (Version 1.23.0.2433 oder höher)
@vpn-unlimited-secure-proxy (Version 4.4 oder höher)
@windscribeff (Version 0.1.43 oder höher)
@youtube_downloader (Version 0.0.9 oder höher)
@youtubedownloadere (Version 0.0.1 oder höher)
@youtuberightclick (Version 0.0.3 oder höher)
@yset (Version 0.0.10 oder höher)
_12Members_@free.myscrapnook.com (Version 7.102.10.4739 oder höher)
_14Members_@download.totalrecipesearch.com (Version 7.102.10.4983 oder höher)
_14Members_@www.totalrecipesearch.com (Version 7.38.8.45925 oder höher)
_1cMembers_@www.bringmesports.com (Version 7.102.10.3646 oder höher)
_1eMembers_@www.videoscavenger.com (Version 7.38.8.45273 oder höher)
_1gMembers_@www.inboxace.com (Version 7.38.8.56535 oder höher)
_1pMembers_@www.referenceboss.com (Version 7.102.10.4932 oder höher)
_29Members_@www.headlinealley.com (Version 7.38.8.56537 oder höher)
_2bMembers_@www.bettercareersearch.com (Version 7.38.8.45828 oder höher)
_2vMembers_@www.dailybibleguide.com (Version 7.38.8.52880 oder höher)
_39Members_@www.mapsgalaxy.com (Version 7.102.10.4730 oder höher)
_49Members_@www.utilitychest.com (Version 7.38.8.45977 oder höher)
_4jMembers_@www.radiorage.com (Version 7.102.10.4916 oder höher)
_4lMembers_@www.bibletriviatime.com (Version 7.102.10.4330 oder höher)
_4wMembers_@www.retrogamer.com (Version 7.38.8.46604 oder höher)
_4zMembers_@www.videodownloadconverter.com (Version 7.102.10.5033 oder höher)
_57Members_@free.marineaquariumfree.com (Version 7.102.10.4716 oder höher)
_5aMembers_@download.mywebface.com (Version 7.102.10.4837 oder höher)
_5eMembers_@www.translationbuddy.com (Version 7.38.8.45962 oder höher)
_5mMembers_@download.myfuncards.com (Version 7.102.10.4783 oder höher)
_5qMembers_@www.zwinky.com (Version 7.38.8.45270 oder höher)
_5zMembers_@www.couponxplorer.com (Version 7.102.10.3738 oder höher)
_63Members_@www.aplusgamer.com (Version 7.38.8.45832 oder höher)
_64Members_@download.televisionfanatic.com (Version 7.38.9.3004 oder höher)
_64Members_@www.televisionfanatic.com (Version 7.102.10.4968 oder höher)
_65Members_@download.fromdoctopdf.com (Version 7.102.10.4221 oder höher)
_69Members_@www.packagetracer.com (Version 7.102.10.4831 oder höher)
_6oMembers_@free.heroicplay.com (Version 7.38.8.46626 oder höher)
_6xMembers_@www.readingfanatic.com (Version 7.102.10.4914 oder höher)
_73Members_@www.easyhomedecorating.com (Version 7.102.10.4129 oder höher)
_7eMembers_@www.homeworksimplified.com (Version 7.102.10.4290 oder höher)
_7jMembers_@download.gardeningenthusiast.com (Version 7.102.10.4260 oder höher)
_89Members_@download.safepcrepair.com (Version 7.39.8.51080 oder höher)
_8eMembers_@download.howtosimplified.com (Version 7.102.10.4285 oder höher)
_8hMembers_@download.allin1convert.com (Version 7.102.10.3584 oder höher)
_8iMembers_@download.audiotoaudio.com (Version 7.102.10.3585 oder höher)
_8jMembers_@download.myimageconverter.com (Version 7.102.10.4778 oder höher)
_8lMembers_@free.filesharefanatic.com (Version 7.102.10.4171 oder höher)
_94Members_@www.motitags.com (Version 7.102.10.4744 oder höher)
_9eMembers_@free.findmefreebies.com (Version 7.102.10.4193 oder höher)
_9pMembers_@free.onlinemapfinder.com (Version 7.102.10.4836 oder höher)
_9tMembers_@download.internetspeedtracker.com (Version 7.38.8.56171 oder höher)
_9tMembers_@free.internetspeedtracker.com (Version 7.102.10.4339 oder höher)
_aaMembers_@free.eliteunzip.com (Version 7.39.8.50909 oder höher)
_agMembers_@free.premierdownloadmanager.com (Version 7.102.10.4846 oder höher)
_apMembers_@free.puzzlegamesdaily.com (Version 7.102.10.4865 oder höher)
_b7Members_@free.mytransitguide.com (Version 7.102.10.4812 oder höher)
_beMembers_@free.dailylocalguide.com (Version 7.38.9.7920 oder höher)
_bfMembers_@free.snapmyscreen.com (Version 7.102.10.4951 oder höher)
_brMembers_@free.yourtemplatefinder.com (Version 7.102.10.5047 oder höher)
_btMembers_@free.catsandcatapults.com (Version 7.102.10.3677 oder höher)
_ceMembers_@free.easypdfcombine.com (Version 7.102.10.4117 oder höher)
_chMembers_@free.discoverancestry.com (Version 7.102.10.3818 oder höher)
_cxMembers_@www.autopcbackup.com (Version 7.102.10.3597 oder höher)
_d1Members_@free.mysocialshortcut.com (Version 7.102.10.4792 oder höher)
_d9Members_@www.everydaylookup.com (Version 7.102.10.4140 oder höher)
_dbMembers_@free.getformsonline.com (Version 7.102.10.4251 oder höher)
_diMembers_@www.free.easymaillogin.com (Version 7.102.10.4112 oder höher)
_dmMembers_@free.gounzip.com (Version 7.102.10.4277 oder höher)
_dnMembers_@www.free.webmailworld.com (Version 7.102.10.5052 oder höher)
_doMembers_@free.convertanyfile.com (Version 7.38.8.45860 oder höher)
_dpMembers_@free.findyourmaps.com (Version 7.102.10.4185 oder höher)
_dqMembers_@www.downspeedtest.com (Version 7.102.10.3827 oder höher)
_dvMembers_@www.testinetspeed.com (Version 7.38.8.45918 oder höher)
_dxMembers_@www.download-freemaps.com (Version 7.38.8.46371 oder höher)
_dyMembers_@www.dezipper.com (Version 7.102.10.3775 oder höher)
_dzMembers_@www.pconverter.com (Version 7.102.10.4851 oder höher)
_e0Members_@www.downshotfree.com (Version 7.102.10.3833 oder höher)
_e1Members_@free.actionclassicgames.com (Version 7.38.8.45834 oder höher)
_e2Members_@free.coolpopulargames.com (Version 7.38.8.45873 oder höher)
_e5Members_@www.productivityboss.com (Version 7.38.8.46590 oder höher)
_ebMembers_@download.metrohotspot.com (Version 7.102.10.4735 oder höher)
_edMembers_@free.myradioaccess.com (Version 7.102.10.4797 oder höher)
_eeMembers_@download.freeradiocast.com (Version 7.38.8.46366 oder höher)
_eiMembers_@www.100sofrecipes.com (Version 7.102.10.3580 oder höher)
_erMembers_@free.getvideoconvert.com (Version 7.102.10.5038 oder höher)
_euMembers_@free.filesendsuite.com (Version 7.102.10.4154 oder höher)
_evMembers_@www.bestbackground.com (Version 7.38.9.7654 oder höher)
_evMembers_@www.free.bestbackground.com (Version 7.102.10.3607 oder höher)
_ewMembers_@free.mergedocsonline.com (Version 7.102.10.4710 oder höher)
_exMembers_@free.easydocmerge.com (Version 7.102.10.4137 oder höher)
_f5Members_@free.typingfanatic.com (Version 7.102.10.5014 oder höher)
_f7Members_@download.smsfrombrowser.com (Version 7.38.8.45917 oder höher)
_fbMembers_@free.smarterpassword.com (Version 7.102.10.4936 oder höher)
_flMembers_@free.myformsfinder.com (Version 7.102.10.4784 oder höher)
_foMembers_@free.flightsearchapp.com (Version 7.102.10.4176 oder höher)
_fpMembers_@free.passwordlogic.com (Version 7.102.10.4853 oder höher)
_frMembers_@free.testforspeed.com (Version 7.102.10.4993 oder höher)
_fsMembers_@free.pdfconverterhq.com (Version 7.102.10.4849 oder höher)
_ftMembers_@free.mytelevisionhq.com (Version 7.102.10.4817 oder höher)
_fvMembers_@free.directionsace.com (Version 7.102.10.3790 oder höher)
_fwMembers_@free.howtosuite.com (Version 7.102.10.4280 oder höher)
_g3Members_@free.easyphotoedit.com (Version 7.102.10.4108 oder höher)
_gcMembers_@www.weatherblink.com (Version 7.38.8.56523 oder höher)
_gpMembers_@free.mymapswizard.com (Version 7.102.10.4775 oder höher)
_gtMembers_@free.gamingwonderland.com (Version 7.102.10.4263 oder höher)
_h2Members_@free.calendarspark.com (Version 7.102.10.3641 oder höher)
_hfMembers_@free.everydaymanuals.com (Version 7.102.10.4142 oder höher)
_hgMembers_@free.atozmanuals.com (Version 7.102.10.3604 oder höher)
_ivMembers_@free.simplepictureedit.com (Version 7.102.10.14166 oder höher)
_j2Members_@www.soccerinferno.com (Version 7.102.10.4948 oder höher)
_paMembers_@www.filmfanatic.com (Version 7.102.10.4163 oder höher)
_v4Members_@www.dictionaryboss.com (Version 7.102.10.3797 oder höher)
abb-acer@amazon.com (Version 10.161.13.1002 oder höher)
adbeaver@adbeaver.org (Version 0.7.2.9 oder höher)
adblockpopups@jessehakanen.net (Version 0.9.2.1-signed.1-signed oder höher)
adblockultimate@adblockultimate.net (Version 2.25 oder höher)
add-to-searchbox@maltekraus.de (Version 2.9 oder höher)
adguardadblocker@adguard.com (Version 2.4.14 oder höher)
admin@djamol.com (Version 4.31.1-signed.1-signed oder höher)
admin@hide-my-ip.org (Version 9.6.3 oder höher)
adonis.cuhk@gmail.com (Version 1.8.9.1-signed.1-signed oder höher)
alldownloader@link64 (Version 1.00.17.1-signed.1-signed oder höher)
AllMyTube@Wondershare.com (Version 4.9.1 oder höher)
ALone-live@ya.ru (Version 1.4.11 oder höher)
alx-ffdeveloper@amazon.com (Version 3.0.2 oder höher)
amcontextmenu@loucypher (Version 0.4.2.1-signed.1-signed oder höher)
amznUWL2@amazon.com (Version 1.11 oder höher)
antgroup@antdownloadmanager.com (Version 0.1.7 oder höher)
anti_banner@kaspersky.com (Version 4.0.10.15 oder höher)
anticontainer@downthemall.net (Version 1.5 oder höher)
antmark@ant.com (Version 1.1.14 oder höher)
anttoolbar@ant.com (Version 2.4.7.47 oder höher)
application2@allo-pages.fr (Version 4.5.0 oder höher)
application@itineraire.info (Version 4.5.0 oder höher)
application@les-pages.com (Version 4.4.0 oder höher)
application@recettes.net (Version 4.5.0 oder höher)
ar1er-ewrgfdgomusix@jetpack (Version 1.0.6 oder höher)
arf3@getcartt.com (Version 1.2.3 oder höher)
ascsurfingprotectionnew@iobit.com (Version 2.1.3 oder höher)
autoform@olifozzy (Version 1.2.4.1-signed.1-signed oder höher)
autopager@mozilla.org (Version 0.8.0.10.1-signed.1-signed oder höher)
autoproxy@autoproxy.org (Version 0.4b2.2013051811.1-signed.1-let-fixed.1-signed oder höher)
autorefresh@plugin (Version 1.0.2.1-signed.1-signed oder höher)
autoreload@yz.com (Version 1.21 oder höher)
avg@safeguard (Version 19.6.0.592 oder höher)
avg@wtu3 (Version 3.7.0.0 oder höher)
azan-times@hamid.net (Version 1.2.3.1-signed.1-signed oder höher)
azhang@cloudacl.com (Version 0.19.6.9.1-signed.1-signed oder höher)
bdwteffv19@bitdefender.com (Version 2.2.1 oder höher)
belgiumeid@eid.belgium.be (Version 1.0.21 oder höher)
BestMediaTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
bestproxyswitcher@bestproxyswitcher.com (Version 3.4.6.1-signed.1-signed oder höher)
browsec@browsec.com (Version 2.0.3 oder höher)
browsermodulecorp@browcorporation.org (Version 2.3 oder höher)
btpersonas@brandthunder.com (Version 2.0.4.7 oder höher)
button@scholar.google.com (Version 1.1.1-signed.1-signed oder höher)
caa1-aDOiCAxFFMOVIX@jetpack (Version 0.1.7 oder höher)
caa1-aDOiCAxFFPRIVATE@jetpack (Version 0.2.0 oder höher)
canitbecheaper@trafficbroker.co.uk (Version 3.9.78 oder höher)
captiondownloader@hiephm.com (Version 2.3.1-signed.1-signed oder höher)
check-compatibility@dactyl.googlecode.com (Version 1.3.1-signed.1-signed oder höher)
check4change-owner@mozdev.org (Version 1.9.8.1 oder höher)
clearcache@michel.de.almeida (Version 2.0.1.1-signed.1-signed oder höher)
clickclean@hotcleaner.com (Version 4.1.1-signed.1-signed oder höher)
client@anonymox.net (Version 2.5.2 oder höher)
clipconverter@clipconverter.cc (Version 1.5.2 oder höher)
colorPicker@colorPicker (Version 3.0.1-signed.1-signed oder höher)
commonfix@mozillaonline.com (Version 0.13 oder höher)
content_blocker@kaspersky.com (Version 4.0.10.15 oder höher)
content_blocker_6418E0D362104DADA084DC312DFA8ABC@kaspersky.com (Version 4.5.3.8 oder höher)
content_blocker_663BE8@kaspersky.com (Version 4.5.4.19.1 oder höher)
cookiemgr@jayapal.com (Version 5.12 oder höher)
CookiesIE@yahoo.com (Version 1.0.1-signed.1-signed oder höher)
coralietab@mozdev.org (Version 2.04.20110724.1-signed.1-signed oder höher)
csscoverage@spaghetticoder.org (Version 0.3.4.1-signed.1-signed oder höher)
d.lehr@chello.at (Version 1.2 oder höher)
DailymotionVideoDownloader@PeterOlayev.com (Version 1.0.6.1-signed.1-signed oder höher)
dam@tensons.com (Version 5.0.7 oder höher)
dealxplorermysites770@yahoo.com (Version 0.0.0.1 oder höher)
dgnria2@nuance.com (Version 15.00.000.058 oder höher)
dm@jetpack (Version 0.0.2 oder höher)
dmbarff@westbyte.com (Version 1.5.11 oder höher)
dmmm@westbyte.com (Version 1.3.4 oder höher)
dmpluginff@westbyte.com (Version 1.4.12 oder höher)
dmremote@westbyte.com (Version 1.9.3 oder höher)
downintab@max.max (Version 1.00.1-signed.1-signed oder höher)
downloadplan@firefoxmania.uci.cu (Version 1.3.1-signed.1-signed oder höher)
dta3noaero@vano (Version 1.0.1 oder höher)
e389d8c2-5554-4ba2-a36e-ac7a57093130@gmail.com (Version 1.44.275 oder höher)
e67f8350-7edf-11e3-baa7-0800200c9a66@fri-gate.org (Version 2.2.1.1-signed oder höher)
eagleget_ffext@eagleget.com (Version 3.8 oder höher)
easycopy@smokyink.com (Version 2.7.0 oder höher)
easycopypaste@everhelper.me (Version 1.1.0.1-signed.1-signed oder höher)
easyscreenshot@mozillaonline.com (Version 1.2.8 oder höher)
eliteproxyswitcher@my-proxy.com (Version 1.2.0.2.1-signed.1-signed oder höher)
email@jetpack (Version 0.0.16 oder höher)
emailExtractor@penzil.com (Version 1.3.1-signed.1-signed oder höher)
ERAIL.IN.FFPLUGIN@jetpack (Version 6.0.rev142 oder höher)
exif_viewer@mozilla.doslash.org (Version 2.00.1-signed.1-signed oder höher)
extension@hidemyass.com (Version 1.3.2 oder höher)
extension@one-tab.com (Version 1.17.0 oder höher)
extensions@gismeteo.com (Version 5.1.0.2 oder höher)
facepaste.firefox.addon@azabani.com (Version 2.91 oder höher)
FasterFox_Lite@BigRedBrent (Version 3.9.9Lite.1-signed.1-signed oder höher)
FavIconReloader@mozilla.org (Version 0.8.1-signed oder höher)
favorites_selenium-ide@Samit.Badle (Version 2.0.1-signed.1-signed oder höher)
fbmessengerpanel@alejandrobrizuela.com.ar (Version 1.0.3.1-signed.1-signed oder höher)
fbp@fbpurity.com (Version 9.3.2.1-signed oder höher)
feedly@devhd (Version 16.0.528.1-signed.1-signed oder höher)
ff_hpset@jetpack (Version 1.0.8 oder höher)
ffext_basicvideoext@startpage24 (Version 1.97.37.1-signed.1-signed oder höher)
ffvkontaktemusic@chupakabr.ru (Version 2.2.1-signed.1-signed oder höher)
FGZ-SAE@iacsearchandmedia.com (Version 8.5 oder höher)
firebug@tools.sitepoint.com (Version 1.6.1-signed.1-signed oder höher)
firefinder@robertnyman.com (Version 1.4.1-signed.1-signed oder höher)
fireforce@scrt.ch (Version 2.2.1-signed.1-signed oder höher)
firefox-autofill@googlegroups.com (Version 3.6.1-signed.1-signed oder höher)
firefox@dotvpn.com (Version 1.0.2 oder höher)
firefox@mega.co.nz (Version 3.6.19 oder höher)
firefox@online-convert.com (Version 1.4.1-signed.1-signed oder höher)
firefox@serptrends.com (Version 0.8.14 oder höher)
FirefoxAddon@similarWeb.com (Version 4.0.6 oder höher)
fireml@sirma.bg (Version 1.1.11.1-signed.1-signed oder höher)
FirePHPExtension-Build@firephp.org (Version 0.7.4.1-signed.1-signed oder höher)
firepicker@thedarkone (Version 1.4.3.1-signed.1-signed oder höher)
firequery@binaryage.com (Version 2.0.4 oder höher)
FireXPath@pierre.tholence.com (Version 0.9.7.1.1-signed.1-signed oder höher)
flashfirebug@o-minds.com (Version 4.9.1 oder höher)
flashlight@stephennolan.com.au (Version 1.2.1-signed.1-signed oder höher)
flashstopper@byo.co.il (Version 1.4.2 oder höher)
flv2mp3@hotger.com (Version 2.3.2-signed oder höher)
formhistory@yahoo.com (Version 1.4.0.6 oder höher)
foxfilter@inspiredeffect.net (Version 7.7.1-signed.1-signed oder höher)
foxmarks@kei.com (Version 4.3.19 oder höher)
FunCyberTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
FunkyMediaTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
FunkyTVTabs-the-extension1@mozilla.com (Version 0.1.9 oder höher)
FunMediaTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
FunSafeTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
FunSocialTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
FunTabSafe-the-extension1@mozilla.com (Version 0.1.9 oder höher)
FunTvTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
fvdmedia@gmail.com (Version 11.0.1 oder höher)
fxclickonce@rushyo.com (Version 0.1.1-signed.1-signed oder höher)
fxdevtools-adapters@mozilla.org (Version 0.3.5 oder höher)
gary@builtwith.com (Version 1.9.6.1-signed.1-signed oder höher)
gaurangnshah@gmail.com (Version 1.3.2.1-signed.1-signed oder höher)
gdrivepanel@alejandrobrizuela.com.ar (Version 1.0.2.1-signed.1-signed oder höher)
gmail@borsosfisoft.com (Version 1.0.1.1-signed.1-signed oder höher)
gmail_panel@alejandrobrizuela.com.ar (Version 1.2.0 oder höher)
google@hitachi.com (Version 0.3.1-signed.1-signed oder höher)
googledictionary@toptip.ca (Version 7.5 oder höher)
HighlightedTextToFile@bobbyrne01.org (Version 2.7.1 oder höher)
homepage@mail.ru (Version 1.0.2 oder höher)
homeutil@yandex.ru (Version 1.0.13 oder höher)
hotspot-shield@anchorfree.com (Version 1.2.87 oder höher)
IBM-cck@firefox-extensions.ibm.com (Version 2.3.0 oder höher)
idamm@westbyte.com (Version 1.3.2 oder höher)
idapluginff@westbyte.com (Version 1.5.9 oder höher)
idaremote@westbyte.com (Version 1.6.3 oder höher)
ifamebook@stormvision.it (Version 4.03.1-signed oder höher)
IGF.F3@igufei.com (Version 3.2.11 oder höher)
imageblock@hemantvats.com (Version 3.1 oder höher)
ImagePicker@topolog.org (Version 1.9.4 oder höher)
imgflashblocker@shimon.chohen (Version 0.7.1-signed.1-signed oder höher)
inf@youtube-mp3.video (Version 0.1 oder höher)
info@convert2mp3.net (Version 2.5.1-signed.1-signed oder höher)
info@mp3it.eu (Version 1.4.1.1-signed.1-signed oder höher)
info@priceblink.com (Version 4.8 oder höher)
info@youtube-mp3.org (Version 1.0.9.1-signed.1-signed oder höher)
inspector@mozilla.org (Version 2.0.16.1-signed oder höher)
intgcal@egarracingteam.com.ar (Version 1.5.1 oder höher)
ipfuck@p4ul.info (Version 1.2.1.1-signed.1-signed oder höher)
isreaditlater@ideashower.com (Version 3.0.6.1-signed oder höher)
ISVCU@iSkysoft.com (Version 5.1.0 oder höher)
izer@camelcamelcamel.com (Version 2.8.2 oder höher)
jdwimqhayu@yahoo.com (Version 0.0.0.6 oder höher)
jid0-AocRXUCRsLTCYvn6bgJERnwfuqw@jetpack (Version 2.8.3.1-signed.1-signed oder höher)
jid0-f82gosWvE8oeGQt6WDCGRF1Dy7Q@jetpack (Version 1.0.003 oder höher)
jid0-hyjN250ZzTOOX3evFwwAQBxE4ik@jetpack (Version 6.0.1-signed.1-signed oder höher)
jid0-jJRRRBMgoShUhb07IvnxTBAl29w@jetpack (Version 2.0.4 oder höher)
jid0-raWjElI57dRa4jx9CCiYm5qZUQU@jetpack (Version 3.0.12.1.1-signed.1-signed oder höher)
jid0-w1UVmoLd6VGudaIERuRJCPQx1dQ@jetpack (Version 1.6.8.1-signed oder höher)
jid0-YQz0l1jthOIz179ehuitYAOdBEs@jetpack (Version 2.0.2 oder höher)
jid0-zs24wecdcQo0Lp18D7QOV4WSZFo@jetpack (Version 0.2.1-signed.1-signed oder höher)
jid0-zXo3XFGyiDalgkeEO4UYJTUwo2I@jetpack (Version 1.0.0 oder höher)
jid1-16aeif9OQIRKxA@jetpack (Version 1.1.4 oder höher)
jid1-3gu11JeYBiIuJA@jetpack (Version 3.1.1 oder höher)
jid1-461B0PwxL3oTt1@jetpack (Version 0.2.1-signed.1-signed oder höher)
jid1-4P0kohSJxU1qGg@jetpack (Version 1.22.550 oder höher)
jid1-6AyZ1PQXsR9LgQ@jetpack (Version 0.2.1 oder höher)
jid1-6MGm94JnyY2VkA@jetpack (Version 2.1.8 oder höher)
jid1-8J7ayxTha4KqKQ@jetpack (Version 1.1.1-signed.1-signed oder höher)
jid1-9ETkKdBARv7Iww@jetpack (Version 0.20.1-signed.1-signed oder höher)
jid1-ach2kaGSshPJCg@jetpack (Version 0.1.1-signed.1-signed oder höher)
jid1-AoXeeOB4j7kFdA@jetpack (Version 8.1 oder höher)
jid1-AVgCeF1zoVzMjA@jetpack (Version 0.9.5.6 oder höher)
jid1-AXn9cXcB4fD1QQ@jetpack (Version 0.7.4 oder höher)
jid1-CGxMej0nDJTjwQ@jetpack (Version 1.0.1-signed.1-signed oder höher)
jid1-cHKBMlArKdIVEg@jetpack (Version 1.24.1-signed.1-signed oder höher)
jid1-cplLTTY501TB2Q@jetpack (Version 0.5.1 oder höher)
jid1-cwbvBTE216jjpg@jetpack (Version 2.1.0.1-signed.1-signed oder höher)
jid1-D7momAzRw417Ag@jetpack (Version 4.5.13 oder höher)
jid1-e7w0SHT82Gv9qA@jetpack (Version 1.2 oder höher)
jid1-f7dnBeTj8ElpWQ@jetpack (Version 1.34.1-signed.1-signed oder höher)
jid1-G80Ec8LLEbK5fQ@jetpack (Version 1.3.8 oder höher)
jid1-GeRCnsiDhZiTvA@jetpack (Version 1.0.3 oder höher)
jid1-hDf2iQXGiUjzGQ@jetpack (Version 2.5.0 oder höher)
jid1-HdwPLukcGQeOSh@jetpack (Version 1.2.3 oder höher)
jid1-HfCj61J5q2gaGQ@jetpack (Version 1.0.3 oder höher)
jid1-JcGokIiQyjoBAQ@jetpack (Version 0.6.1-signed.1-signed oder höher)
jid1-KWFaW5zc0EbtBQ@jetpack (Version 0.2.0 oder höher)
jid1-l6VQSR2FeKnliQ@jetpack (Version 2.0.1-signed oder höher)
jid1-LelsJ0Oz0rt71A@jetpack (Version 2.0.0 oder höher)
jid1-lpoiffmusixlib@jetpack (Version 0.1.9 oder höher)
jid1-LYopfl0r00ZV5k@jetpack (Version 1.0.1-signed.1-signed oder höher)
jid1-m3kqTBs1zKXXaA@jetpack (Version 0.2.6.1-signed.1-signed oder höher)
jid1-MIAJd5BiK7V4Pw@jetpack (Version 0.9.1-signed.1-signed oder höher)
jid1-mW7iuA66Ny8Ziw@jetpack (Version 0.9.1-signed.1-signed oder höher)
jid1-n5ARdBzHkUEdAA@jetpack (Version 3.8.7 oder höher)
jid1-n85lxPv1NAWVTQ@jetpack (Version 0.96.1.1-signed oder höher)
jid1-OY8Xu5BsKZQa6A@jetpack (Version 2.0.21 oder höher)
jid1-P34HaABBBpOerQ@jetpack (Version 0.2.1-signed.1-signed oder höher)
jid1-PBNne26X1Kn6hQ@jetpack (Version 3.3.3 oder höher)
jid1-QpHD8URtZWJC2A@jetpack (Version 4.3.0 oder höher)
jid1-r1tDuNiNb4SEww@jetpack (Version 1.1.2673 oder höher)
jid1-ReWlW1efOwaQJQ@jetpack (Version 1.1.2 oder höher)
jid1-rrMTK7JqsxNOeQ@jetpack (Version 2.1.0 oder höher)
jid1-rs90nxQtPi3Asg@jetpack (Version 1.8.1-signed.1-signed oder höher)
jid1-SDFC9fEAZRW7ab@jetpack (Version 0.1.3.1-signed.1-signed oder höher)
jid1-sNL73VCI4UB0Fw@jetpack (Version 2.1.4 oder höher)
jid1-TQvJxTBYHA8qXg@jetpack (Version 0.4.1-signed.1-signed oder höher)
jid1-u9RbFp9JcoEGGw@jetpack (Version 1.2.2.1-signed.1-signed oder höher)
jid1-UXDr6c69BeyPVw@jetpack (Version 0.8.2 oder höher)
jid1-V8ev2melBDV3qQ@jetpack (Version 1.0.12.1-signed.1-signed oder höher)
jid1-vFmnfCkyf5VeSA@jetpack (Version 0.4.0 oder höher)
jid1-vRJA7N8VwBoiXw@jetpack (Version 1.1.1.1-signed oder höher)
jid1-wKRSK9TpFpr9Hw@jetpack (Version 0.92 oder höher)
jid1-XgC5trUcILmXBw@jetpack (Version 2.0.3 oder höher)
jid1-xKH0EoS44u1a2w@jetpack (Version 0.1.1-signed.1-signed oder höher)
jid1-YcMV6ngYmQRA2w@jetpack (Version 1.37.9 oder höher)
jid1-ZM3BerwS6FsQAg@jetpack (Version 0.4.1-signed oder höher)
jid1-zmgYgiQPXJtjNA@jetpack (Version 1.23 oder höher)
jid1-zV8eHYwTDNUtwQ@jetpack (Version 1.0.4 oder höher)
jid2-l8SPBzHJWBIiHQ@jetpack (Version 3.1 oder höher)
jyboy.yy@gmail.com (Version 1.0.4.1-signed.1-signed oder höher)
k7srff_enUS@k7computing.com (Version 2.4 oder höher)
KVAllmytube@KeepVid.com (Version 4.10.0 oder höher)
lazarus@interclue.com (Version 2.3.1-signed.1-signed oder höher)
LDshowpicture_plashcor@gmail.com (Version 3.2 oder höher)
LDSI_plashcor@gmail.com (Version 1.1.0.3 oder höher)
leethax@leethax.net (Version 2016.12.02 oder höher)
light_plugin_ACF0E80077C511E59DED005056C00008@kaspersky.com (Version 4.6.3-15 oder höher)
light_plugin_D772DC8D6FAF43A29B25C4EBAA5AD1DE@kaspersky.com (Version 4.6.2-42-20160922074409 oder höher)
light_plugin_F6F079488B53499DB99380A7E11A93F6@kaspersky.com (Version 5.0.141-4-20161031140250 oder höher)
linkgopher@oooninja.com (Version 1.3.3.1-signed.1-signed oder höher)
low_quality_flash@pie2k.com (Version 0.2.1-signed.1-signed oder höher)
Lucifox@lucidor.org (Version 0.9.13 oder höher)
lumerias-instagram@lumerias.com (Version 1.3 oder höher)
LVD-SAE@iacsearchandmedia.com (Version 8.5 oder höher)
lwthemes-manager@loucypher (Version 0.2.1-signed.1-let-fixed.1-signed oder höher)
magicplayer_unlisted@acestream.org (Version 1.1.42 oder höher)
manish.p05@gmail.com (Version 12.9 oder höher)
manishjain9@hotmail.com_easiestyoutube (Version 7.2.1-signed.1-let-fixed.1-signed oder höher)
Media-Newtab-the-extension1@mozilla.com (Version 0.1.6 oder höher)
MediaNewTab-the-extension1@mozilla.com (Version 0.1.6 oder höher)
memoryrestart@teamextension.com (Version 1.18.1-signed.1-signed oder höher)
modernDownloadManager@teo.pl (Version 0.2.2 oder höher)
mp4downloader@jeff.net (Version 1.3.3.1-signed.1-signed oder höher)
MUB-SAE@iacsearchandmedia.com (Version 8.7 oder höher)
multifox-toolbar-button@rbaldwin (Version 4.28.1-signed.1-signed oder höher)
multifox@hultmann (Version 3.2.3 oder höher)
multilinksplus@hugsmile.eu (Version 3.9.3 oder höher)
multirevenue@googlemail.com (Version 6.1.1 oder höher)
myplaycitycom@gametab (Version 1.6 oder höher)
MySafeTabs-the-extension1@mozilla.com (Version 0.1.9 oder höher)
MyStartab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
mytube@ashishmishra.in (Version 0.979.1-signed.1-signed oder höher)
netvideohunter@netvideohunter.com (Version 1.2 oder höher)
newtab-tv-the-extension1@mozilla.com (Version 0.1.5 oder höher)
newtabgoogle@graememcc.co.uk (Version 1.0.2.1-signed.1-signed oder höher)
NewTabTVCool-the-extension1@mozilla.com (Version 0.1.9 oder höher)
nishan.naseer.googimagesearch@gmail.com (Version 0.5.1-signed.1-signed oder höher)
NoiaFoxoption@davidvincent.tld (Version 3.0.2.1-signed oder höher)
nortonsecurity@symantec.com (Version 7.2.0f90 oder höher)
nst@neiron.ru (Version 7.3.0.2 oder höher)
ocr@babylon.com (Version 1.1 oder höher)
odyssey_crypto_control@odysseytec.com (Version 3.5 oder höher)
omnibar@ajitk.com (Version 0.7.28.20141004.1-signed.1-signed oder höher)
online_banking@kaspersky.com (Version 4.0.10.15 oder höher)
online_banking_08806E@kaspersky.com (Version 4.5.4.19.1 oder höher)
online_banking_69A4E213815F42BD863D889007201D82@kaspersky.com (Version 4.5.3.8 oder höher)
open.about.permissions@jasnapaka.com (Version 1.2.1-signed.1-signed oder höher)
PageRank@addonfactory.in (Version 2.0.1-signed.1-signed oder höher)
panel-plugin@effectivemeasure.com (Version 4.0.0 oder höher)
partnerdefaults@mozilla.com (Version 1.0.1 oder höher)
paulsaintuzb@gmail.com (Version 8.2.1 oder höher)
pavel.sherbakov@gmail.com (Version 19.1.1 oder höher)
pixelperfectplugin@openhouseconcepts.com (Version 2.0.14 oder höher)
plugin@okta.com (Version 5.8.0 oder höher)
printPages2Pdf@reinhold.ripper (Version 0.1.9.3.1-signed oder höher)
printpdf@pavlov.net (Version 0.76.1-signed.1-signed oder höher)
proxyselector@mozilla.org (Version 1.31.1-signed.1-signed oder höher)
public.proartex@gmail.com (Version 1.1.3 oder höher)
qqmail_plugin_for_firefox@tencent.com (Version 1.0.0.22 oder höher)
quicksearch@yandex.ru (Version 1.0.13 oder höher)
qwantcomforfirefox@jetpack (Version 3.0.28 oder höher)
r2d2b2g@mozilla.org (Version 4.0.4.1-signed oder höher)
rainbow@colors.org (Version 1.6.1-signed.1-signed oder höher)
ramback@pavlov.net (Version 1.0.1-signed.1-signed oder höher)
rapportive@rapportive.com (Version 1.4.0.1.1-signed.1-signed oder höher)
readable@evernote.com (Version 10.2.1.7.1-signed oder höher)
rest-easy@quickmediasolutions.com (Version 0.3.1.1-signed oder höher)
restart@restart.org (Version 0.5.1-signed.1-signed oder höher)
restartbutton@strk.jp (Version 0.1.5.1-signed.1-signed oder höher)
rikaichan-jpen@polarcloud.com (Version 2.01.160101 oder höher)
rpnetdownloadhelper@gmail.com (Version 3.0.1-signed.1-signed oder höher)
SafeBrowseSearch-the-extension1@mozilla.com (Version 0.1.2 oder höher)
safefacebook@bkav (Version 1.0.4 oder höher)
safesearch@avira.com (Version 1.4.1.371 oder höher)
safesearchplus2@avira.com (Version 1.4.1.371 oder höher)
safesearchplus@avira.com (Version 1.4.1.371 oder höher)
saiful.neo@gmail.com (Version 3.0.1-signed.1-signed oder höher)
save-as-pdf-ff@pdfcrowd.com (Version 1.5.1-signed.1-signed oder höher)
savedeo-video-downloader@fczbkk.com (Version 0.4.1.1-signed.1-signed oder höher)
savefileto@mozdev.org (Version 2.5.5 oder höher)
search@mail.ru (Version 1.0.7 oder höher)
searchme@mybrowserbar.com (Version 2.8 oder höher)
searchprivacy@searchprivacy.co (Version 1.15 oder höher)
selenium-expert_selenium-ide@Samit.Badle (Version 0.25.1-signed.1-signed oder höher)
selenium_ide_buttons@egarracingteam.com.ar (Version 1.2.0.1-signed.1-signed oder höher)
sendtokindle@amazon.com (Version 1.0.2.76 oder höher)
seodoctor@prelovac.com (Version 1.6.5.1-signed.1-signed oder höher)
seostatus@rubyweb (Version 1.5.9.1-signed.1-signed oder höher)
service@touchpdf.com (Version 1.15.1-signed.1-signed oder höher)
shopcbtoolbar2@befrugal.com (Version 2013.3.23.1 oder höher)
shopearn@prodege.com (Version 219 oder höher)
showpassword@pratikpoddar (Version 1.7.1-signed.1-signed oder höher)
shpassword@shpassword.fr (Version 0.3.1-signed.1-signed oder höher)
SignPlugin@pekao.pl (Version 1.4.0.73 oder höher)
simplesiteblocker@example.com (Version 1.1.1-signed.1-signed oder höher)
SkipScreen@SkipScreen (Version 0.7.2.1-signed.1-signed oder höher)
smarterwiki@wikiatic.com (Version 5.2.1.1-signed.1-signed oder höher)
smile1Button@amazon.com (Version 1.0.1-signed.1-signed oder höher)
snt@simplenewtab.com (Version 1.3 oder höher)
soaclient@santoso (Version 0.2.1-signed.1-signed oder höher)
SocialNewPages-the-extension1@mozilla.com (Version 0.1.9 oder höher)
SocialNewtabs-the-extension1@mozilla.com (Version 0.1.9 oder höher)
speeddns@gmail.com (Version 0.2.1-signed.1-signed oder höher)
sqlime@security.compass (Version 0.4.7.1-signed.1-signed oder höher)
SQLiteManager@mrinalkant.blogspot.com (Version 0.8.3.1-signed.1-signed oder höher)
stealthyextension@gmail.com (Version 3.0.1.1-signed oder höher)
superstart@enjoyfreeware.org (Version 7.4.0.1-signed oder höher)
support@todoist.com (Version 4.0.5 oder höher)
support@videoadd.ru (Version 2.8.1.1-signed.1-signed oder höher)
testpilot@labs.mozilla.com (Version 1.2.3.1-signed oder höher)
text2voice@vik.josh (Version 1.15 oder höher)
TFToolbarX@torrent-finder (Version 1.3.1.1-signed.1-signed oder höher)
the-addon-bar@GeekInTraining-GiT (Version 3.2.9-compat-fixed-4 oder höher)
tilt@mozilla.com (Version 1.0.1.1-signed.1-signed oder höher)
tinyjsdebugger@enigmail.net (Version 1.1.5 oder höher)
tmbepff@trendmicro.com (Version 9.2.0.1026 oder höher)
toolbar@seomoz.org (Version 3.1.18 oder höher)
toolbar@shopathome.com (Version 8.20.3.1 oder höher)
toolbar_AVIRA-V7@apn.ask.com (Version 127.25 oder höher)
toolbar_TeoMediaTB@apn.ask.com (Version 135.3 oder höher)
TopSafeTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
TopSecurityTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
TopSocialHub-the-extension1@mozilla.com (Version 0.1.9 oder höher)
TopSocialTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
TopTabTV-the-extension1@mozilla.com (Version 0.1.9 oder höher)
TopTVTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
touchenex@raon.co.kr (Version 1.0.1.11 oder höher)
trackmenot@mrl.nyu.edu (Version 0.9.2 oder höher)
trafficlight@bitdefender.com (Version 0.2.23.1-signed.1-signed oder höher)
translator@dontfollowme.net (Version 2.0.5 oder höher)
translator@zoli.bod (Version 2.1.0.5.1.1-signed oder höher)
tvnewtab-the-extension1@mozilla.com (Version 0.1.5 oder höher)
tvplusnewtab-the-extension1@mozilla.com (Version 0.1.5 oder höher)
twoo@twoo.com (Version 1.6.0.1-signed oder höher)
txftn@tencent.com (Version 1.0.0.7 oder höher)
ubufox@ubuntu.com (Version 3.2 oder höher)
uploader@adblockfilters.mozdev.org (Version 2.1.1-signed.1-let-fixed.1-signed oder höher)
uriloader@pdf.js (Version 1.0.277.1-signed.1-signed oder höher)
url_advisor@kaspersky.com (Version 4.0.10.15 oder höher)
useragentoverrider@qixinglu.com (Version 0.4.1 oder höher)
VacuumPlacesImproved@lultimouomo-gmail.com (Version 1.2.1-signed.1-signed oder höher)
vdpure@link64 (Version 1.97.43 oder höher)
videoresumer@jetpack (Version 1.1.4 oder höher)
virtual_keyboard@kaspersky.com (Version 4.0.10.15 oder höher)
virtual_keyboard_074028@kaspersky.com (Version 4.5.4.19.1 oder höher)
virtual_keyboard_294FF26A1D5B455495946778FDE7CEDB@kaspersky.com (Version 4.5.3.8 oder höher)
vk@sergeykolosov.mp (Version 0.3.9.5 oder höher)
vlc_shortcut@kosan.kosan (Version 0.8.3.0 oder höher)
vlcplaylist@helgatauscher.de (Version 0.8.1-signed.1-signed oder höher)
vpn@hide-my-ip.org (Version 10.6.2 oder höher)
vwof@drev.com (Version 3.1.2 oder höher)
wappalyzer@crunchlabz.com (Version 3.2.7 oder höher)
webdavlauncher@benryan.com (Version 1.1.0 oder höher)
webmaster@keep-tube.com (Version 1.2.1-signed.1-signed oder höher)
WebProtection@360safe.com (Version 5.0.0.1005 oder höher)
webrank-toolbar@probcomp.com (Version 4.4.1.1-signed.1-signed oder höher)
whatsapppanel@alejandrobrizuela.com.ar (Version 1.1.1.1-signed.1-signed oder höher)
whodeletedme@deleted.io (Version 0.3.3 oder höher)
windowandtablimiter@weintraut.net (Version 4.28.1-signed.1-signed oder höher)
windowpromo@dm73.net (Version 1.6 oder höher)
wisestamp@wisestamp.com (Version 4.14.20 oder höher)
WSVCU@Wondershare.com (Version 7.1.0 oder höher)
xthunder@lshai.com (Version 1.3.4.1-signed.1-signed oder höher)
yasearch@yandex.ru (Version 8.20.4 oder höher)
YourMediaTab-the-extension1@mozilla.com (Version 0.1.9 oder höher)
youtube-video-player@lejenome.me (Version 0.2.38.1-signed.1-signed oder höher)
youtube2mp3@mondayx.de (Version 1.2.3.1-signed.1-signed oder höher)
YouTubeAutoReplay@arikv.com (Version 3.3.1-signed.1-signed oder höher)
YoutubeDownloader@huangho.net76.net (Version 1.6.5.1-signed.1-signed oder höher)
YoutubeDownloader@PeterOlayev.com (Version 2.4.1 oder höher)
youtubedownloader@trafficterminal.com (Version 1.0.1.1-signed.1-signed oder höher)
youtubemp3podcaster@jeremy.d.gregorio.com (Version 3.9.0 oder höher)
YouTubetoALL@ALLPlayer.org (Version 0.8.5.1-signed.1-signed oder höher)
youtubeunblocker@unblocker.yt (Version 0.6.20 oder höher)
yslow@yahoo-inc.com (Version 3.1.8.1-signed.1-signed oder höher)
{00f7ab9f-62f4-4145-b2f9-38d579d639f6} (Version 49 oder höher)
{018f3160-1a6f-4650-84fd-aad8c13609c8} (Version 0.1.1-signed.1-signed oder höher)
{023e9ca0-63f3-47b1-bcb2-9badf9d9ef28} (Version 4.4.3.1-signed.1-signed oder höher)
{02450954-cdd9-410f-b1da-db804e18c671} (Version 0.96.3.1-signed.1-signed oder höher)
{03B08592-E5B4-45ff-A0BE-C1D975458688} (Version 1.1.1-signed.1-signed oder höher)
{04426594-bce6-4705-b811-bcdba2fd9c7b} (Version 1.7.1-signed.1-signed oder höher)
{0538E3E3-7E9B-4d49-8831-A227C80A7AD3} (Version 2.2.2.1-signed.1-let-fixed.1-signed oder höher)
{0545b830-f0aa-4d7e-8820-50a4629a56fe} (Version 31.0.9 oder höher)
{063DA41A-2561-401B-91FA-AC75E460F4EB} (Version 1.0.7.1 oder höher)
{065829BC-17B5-4C0B-9429-3173C361092E} (Version 1.0.8 oder höher)
{065ee92a-ad57-42a2-b6d5-466b6fd8e24d} (Version 0.11.6.1-signed.1-signed oder höher)
{068c594c-1a69-4f51-888d-1e231eac59a3} (Version 1 oder höher)
{068e178c-61a9-4a63-b74f-87404a6f5ea1} (Version 2 oder höher)
{0AA9101C-D3C1-4129-A9B7-D778C6A17F82} (Version 2.09.1-signed oder höher)
{0fc22c4c-93ed-48ea-ad12-dc8039cf3795} (Version 1.3 oder höher)
{1082eb84-f0f2-11e5-8e18-9bb85ab7992e} (Version 1.07 oder höher)
{11483926-db67-4190-91b1-ef20fcec5f33} (Version 0.4.9.1 oder höher)
{12b6fdcd-4423-4276-82a3-73fdbff5f7e4} (Version 50 oder höher)
{139C4B80-60ED-11E4-80EC-84041E5D46B0} (Version 1.3 oder höher)
{146f1820-2b0d-49ef-acbf-d85a6986e10c} (Version 0.1.9.3.1-signed.1-signed oder höher)
{158d7cb3-7039-4a75-8e0b-3bd0a464edd2} (Version 2.7.1-signed.1-signed oder höher)
{15e67a59-bd3d-49ae-90dd-b3d3fd14c2ed} (Version 1.0.3.1-signed.1-signed oder höher)
{15fe27f3-e5ab-2d59-4c5c-dadc7945bdbd} (Version 2.1.1.1-signed.1-signed oder höher)
{19503e42-ca3c-4c27-b1e2-9cdb2170ee34} (Version 1.5.6.14 oder höher)
{195A3098-0BD5-4e90-AE22-BA1C540AFD1E} (Version 4.1.0.1-signed.1-signed oder höher)
{19EB90DC-A456-458b-8AAC-616D91AAFCE1} (Version 1.0.1-signed oder höher)
{1A2D0EC4-75F5-4c91-89C4-3656F6E44B68} (Version 0.6.3.1-signed.1-signed oder höher)
{1a5dabbd-0e74-41da-b532-a364bb552cab} (Version 1.0.9.1-signed oder höher)
{1B33E42F-EF14-4cd3-B6DC-174571C4349C} (Version 4.7 oder höher)
{1b80ae74-4912-44fc-9f27-30f9252a5ad7} (Version 2.3 oder höher)
{1BC9BA34-1EED-42ca-A505-6D2F1A935BBB} (Version 6.2.18.1 oder höher)
{20a82645-c095-46ed-80e3-08825760534b} (Version 1.3.1.1-signed oder höher)
{22119944-ED35-4ab1-910B-E619EA06A115} (Version 7.9.21.5 oder höher)
{22181a4d-af90-4ca3-a569-faed9118d6bc} (Version 11.0.0.1181 oder höher)
{22870005-adef-4c9d-ae36-d0e1f2f27e5a} (Version 0.4.0.9.1.1-signed.1-signed oder höher)
{24d26487-6274-48b1-b500-22f24884f971} (Version 2.3 oder höher)
{25A1388B-6B18-46c3-BEBA-A81915D0DE8F} (Version 1.7.8.5.1-signed.1-signed oder höher)
{2bc72c53-9bde-4db2-8479-eda9a5e71f4e} (Version 3.2 oder höher)
{2e17e2b2-b8d4-4a67-8d7b-fafa6cc9d1d0} (Version 1.2.7.0.1-signed.1-signed oder höher)
{2e710e6b-5e9d-44ba-8f4e-09a040978b49} (Version 1.7 oder höher)
{338e0b96-2285-4424-b4c8-e25560750fa3} (Version 3.1-signed.1-signed oder höher)
{35d6291e-1d4b-f9b4-c52f-77e6410d1326} (Version 4.11.1.0 oder höher)
{37964A3C-4EE8-47b1-8321-34DE2C39BA4D} (Version 2.5.4.174 oder höher)
{37E4D8EA-8BDA-4831-8EA1-89053939A250} (Version 3.0.0.2.1-signed.1-signed oder höher)
{394DCBA4-1F92-4f8e-8EC9-8D2CB90CB69B} (Version 5.1.1 oder höher)
{3b56bcc7-54e5-44a2-9b44-66c3ef58c13e} (Version 0.9.7.4 oder höher)
{3c59c791-aeec-44bb-af60-ff112eea18e3} (Version 3.2 oder höher)
{3cc6c6ba-654c-417e-a8af-6997ac388ae1} (Version 49 oder höher)
{3d7eb24f-2740-49df-8937-200b1cc08f8a} (Version 1.5.20 oder höher)
{3e0e7d2a-070f-4a47-b019-91fe5385ba79} (Version 3.6.5.2 oder höher)
{3e9bb2a7-62ca-4efa-a4e6-f6f6168a652d} (Version 2.7.7.1-signed.1-signed oder höher)
{4093c4de-454a-4329-8aff-c6b0b123c386} (Version 0.8.14.1-signed.1-signed oder höher)
{4176DFF4-4698-11DE-BEEB-45DA55D89593} (Version 0.8.50.1-signed.1-signed oder höher)
{4204c864-50bf-467a-95b3-0912b7f15869} (Version 1.2.00.1-signed.1-signed oder höher)
{455D905A-D37C-4643-A9E2-F6FEFAA0424A} (Version 0.8.17.1-signed.1-signed oder höher)
{45d8ff86-d909-11db-9705-005056c00008} (Version 1.3.4.8 oder höher)
{4BBDD651-70CF-4821-84F8-2B918CF89CA3} (Version 8.9.3.1 oder höher)
{4c7097f7-08f2-4ef2-9b9f-f95fa4cbb064} (Version 1.1 oder höher)
{4cc4a13b-94a6-7568-370d-5f9de54a9c7f} (Version 2.7.1-signed.1-signed oder höher)
{4DC70064-89E2-4a55-8FC6-E8CDEAE3618C} (Version 0.7.7.1-signed.1-signed oder höher)
{4ED1F68A-5463-4931-9384-8FFF5ED91D92} (Version 5.0.248.0 oder höher)
{51aa69f8-8825-4def-916a-a766c5e3c0fd} (Version 3.8 oder höher)
{524B8EF8-C312-11DB-8039-536F56D89593} (Version 4.91.0.0 oder höher)
{53152e75-fd90-472f-9d30-5cba3679eab9} (Version 48.3 oder höher)
{53A03D43-5363-4669-8190-99061B2DEBA5} (Version 1.5.14 oder höher)
{54e46280-0211-11e3-b778-0800200c9a66} (Version 0.3 oder höher)
{54FBE89E-C878-46bb-A064-AB327EE26EBC} (Version 3.8 oder höher)
{5546F97E-11A5-46b0-9082-32AD74AAA920} (Version 0.76.1-signed.1-signed oder höher)
{58d735b4-9d6c-4e37-b146-7b9f7e79e318} (Version 1.6 oder höher)
{5e594888-3e8e-47da-b2c6-b0b545112f84} (Version 1.3.18 oder höher)
{5F590AA2-1221-4113-A6F4-A4BB62414FAC} (Version 0.45.8.20130519.3.1-signed.1-signed oder höher)
{60B7679C-BED9-11E5-998D-8526BB8E7F8B} (Version 6.3 oder höher)
{62760FD6-B943-48C9-AB09-F99C6FE96088} (Version 4.2.9 oder höher)
{62DD0A97-FDD4-421b-94A5-D1A9434450C7} (Version 3.1 oder höher)
{635abd67-4fe9-1b23-4f01-e679fa7484c1} (Version 5.0.2 oder höher)
{64161300-e22b-11db-8314-0800200c9a66} (Version 0.9.6.18 oder höher)
{65e41d20-f092-41b7-bb83-c6e8a9ab0f57} (Version 1.2.6 oder höher)
{6614d11d-d21d-b211-ae23-815234e1ebb5} (Version 3.9.13 oder höher)
{686fc9c5-c339-43db-b93a-5181a217f9a6} (Version 1.11 oder höher)
{6AC85730-7D0F-4de0-B3FA-21142DD85326} (Version 2.8.2 oder höher)
{6cc0f0f7-a6e2-4834-9682-24de2229b51e} (Version 23.6 oder höher)
{6d96bb5e-1175-4ebf-8ab5-5f56f1c79f65} (Version 0.9.8 oder höher)
{6E727987-C8EA-44DA-8749-310C0FBE3C3E} (Version 2.0.0.11 oder höher)
{6e764c17-863a-450f-bdd0-6772bd5aaa18} (Version 1.0.3.1-signed.1-signed oder höher)
{6e84150a-d526-41f1-a480-a67d3fed910d} (Version 1.5.6.1-signed.1-signed oder höher)
{71328583-3CA7-4809-B4BA-570A85818FBB} (Version 0.8.6.3.1-let-fixed oder höher)
{725fc0a6-1f6b-4cf9-ae17-748d111dc16d} (Version 1.1.0 oder höher)
{73007fef-a6e0-47d3-b4e7-dfc116ed6f65} (Version 1.15.1-signed.1-signed oder höher)
{75493B06-1504-4976-9A55-B6FE240FF0BF} (Version 3.4.0.0 oder höher)
{75CEEE46-9B64-46f8-94BF-54012DE155F0} (Version 0.4.15 oder höher)
{761a54f1-8ccf-4112-9e48-dbf72adf6244} (Version 2.3.1-signed.1-signed oder höher)
{776f38cb-6255-4b92-b5cf-e5c71ff2b688} (Version 1.6 oder höher)
{77b819fa-95ad-4f2c-ac7c-486b356188a9} (Version 4.0.20130422.1-signed.1-signed oder höher)
{79c50f9a-2ffe-4ee0-8a37-fae4f5dacd4f} (Version 5.1.3 oder höher)
{7a526449-3a92-426f-8ca4-47439918f2b1} (Version 3.2 oder höher)
{7affbfae-c4e2-4915-8c0f-00fa3ec610a1} (Version 6.36.32 oder höher)
{7b8a500a-a464-4624-bd4f-73eaafe0f766} (Version 3 oder höher)
{7c6cdf7c-8ea8-4be7-ae5a-0b3effe14d66} (Version 49.1 oder höher)
{7CA9CF31-1C73-46CD-8377-85AB71EA771F} (Version 5.0.12 oder höher)
{7DD78D43-0962-4d9b-BC76-ABF13B3B2ED1} (Version 3.5.0.1428 oder höher)
{7e80e173-7e63-464e-8252-fe170b15c15a} (Version 2.3 oder höher)
{7eb3f691-25b4-4a85-9038-9e57e2bcd537} (Version 0.4.4.1-signed.1-signed oder höher)
{7f57cf46-4467-4c2d-adfa-0cba7c507e54} (Version 4.0.1 oder höher)
{82AF8DCA-6DE9-405D-BD5E-43525BDAD38A} (Version 8.0.0.9103 oder höher)
{8620c15f-30dc-4dba-a131-7c5d20cf4a29} (Version 3.9 oder höher)
{888d99e7-e8b5-46a3-851e-1ec45da1e644} (Version 45.0.0 oder höher)
{8AA36F4F-6DC7-4c06-77AF-5035170634FE} (Version 2016.9.16 oder höher)
{8b5bea8c-6194-4c7c-a440-d5ca181480c3} (Version 1.500.000.11 oder höher)
{8b86149f-01fb-4842-9dd8-4d7eb02fd055} (Version 0.26.1-signed.1-signed oder höher)
{8BCA0E8A-E57B-425b-A05B-CD3868EB577E} (Version 1.4.1-signed.1-signed oder höher)
{8F6A6FD9-0619-459f-B9D0-81DE065D4E21} (Version 1.13 oder höher)
{8f8fe09b-0bd3-4470-bc1b-8cad42b8203a} (Version 0.17.1-signed.1-signed oder höher)
{902D2C4A-457A-4EF9-AD43-7014562929FF} (Version 0.6.4 oder höher)
{90477448-b59c-48cd-98af-6a298cbc15d2} (Version 3.8 oder höher)
{95322c08-05ff-4f3c-85fd-8ceb821988dd} (Version 49 oder höher)
{95ab36d4-fb6f-47b0-8b8d-e5f3bd547953} (Version 4.20.13.1-signed.1-signed oder höher)
{95E84BD3-3604-4AAC-B2CA-D9AC3E55B64B} (Version 2.0.0.78 oder höher)
{987311C6-B504-4aa2-90BF-60CC49808D42} (Version 3.1-signed.1-signed oder höher)
{9AA46F4F-4DC7-4c06-97AF-6665170634FE} (Version 1.11.6.1-signed.1-signed oder höher)
{9aad3da6-6c46-4ef0-9109-6df5eaaf597c} (Version 1.4.1.1-signed.1-signed oder höher)
{9BAE5926-8513-417d-8E47-774955A7C60D} (Version 1.1.1d.1-signed.1-signed oder höher)
{9c51bd27-6ed8-4000-a2bf-36cb95c0c947} (Version 11.0.1.1-signed.1-signed oder höher)
{9d1f059c-cada-4111-9696-41a62d64e3ba} (Version 0.17.0.1 oder höher)
{9D6218B8-03C7-4b91-AA43-680B305DD35C} (Version 4.0.5 oder höher)
{9EB34849-81D3-4841-939D-666D522B889A} (Version 2.4.0.157 oder höher)
{a192bf54-089f-4325-ac25-7eafcd17a342} (Version 3.2 oder höher)
{a38384b3-2d1d-4f36-bc22-0f7ae402bcd7} (Version 1.0.0.51 oder höher)
{a3a5c777-f583-4fef-9380-ab4add1bc2a2} (Version 2.1.4 oder höher)
{a3a5c777-f583-4fef-9380-ab4add1bc2a5} (Version 2.4.2.1-signed oder höher)
{a6fd85ed-e919-4a43-a5af-8da18bda539f} (Version 2.9.1.1-signed oder höher)
{a949831f-d9c0-45ae-8c60-91c2a86fbfb6} (Version 0.2.1-signed.1-signed oder höher)
{a95d8332-e4b4-6e7f-98ac-20b733364387} (Version 1.0.5 oder höher)
{aa84ce40-4253-a00a-8cd6-0800200f9a67} (Version 3.12.0 oder höher)
{ab4b5718-3998-4a2c-91ae-18a7c2db513e} (Version 1.2.0.1-signed.1-signed oder höher)
{ad0d925d-88f8-47f1-85ea-8463569e756e} (Version 2.0.5 oder höher)
{ada4b710-8346-4b82-8199-5de2b400a6ae} (Version 2.1.5.5.3 oder höher)
{B068AC18-0121-4e67-9A7E-6386F93F4F7A} (Version 2.4 oder höher)
{b0e1b4a6-2c6f-4e99-94f2-8e625d7ae255} (Version 3.5.0.1-signed.1-signed oder höher)
{B17C1C5A-04B1-11DB-9804-B622A1EF5492} (Version 1.3.2 oder höher)
{b1df372d-8b32-4c7d-b6b4-9c5b78cf6fb1} (Version 0.87.1-signed.1-signed oder höher)
{b2bfe60c-eef8-4e20-8334-c53afdc1ffdd} (Version 3.2 oder höher)
{b6b1a201-b252-484f-b9fe-68efbb273fbd} (Version 1.10.1-signed.1-signed oder höher)
{b7389dbc-6646-412f-bbd5-53168ee68a98} (Version 49 oder höher)
{b749fc7c-e949-447f-926c-3f4eed6accfe} (Version 0.7.1.1.1-signed.1-signed oder höher)
{b7870b41-bfb3-44cd-8cc2-e392e51b0874} (Version 3.8 oder höher)
{B821BF60-5C2D-41EB-92DC-3E4CCD3A22E4} (Version 4.3.1.10 oder höher)
{BBB77B49-9FF4-4d5c-8FE2-92B1D6CD696C} (Version 2.0.0.1083 oder höher)
{C0CB8BA3-6C1B-47e8-A6AB-1FAB889562D9} (Version 0.7.6 oder höher)
{c151d79e-e61b-4a90-a887-5a46d38fba99} (Version 2.8.8 oder höher)
{c1970c0d-dbe6-4d91-804f-c9c0de643a57} (Version 1.3.2.13.1-signed.1-signed oder höher)
{C1A2A613-35F1-4FCF-B27F-2840527B6556} (Version 2016.8.1.9 oder höher)
{c2056674-a37f-4b29-9300-2004759d74fe} (Version 2.0.0.1090 oder höher)
{c2b1f3ae-5cd5-49b7-8a0c-2c3bcbbbb294} (Version 1.1.1-signed.1-signed oder höher)
{c2fc3c2b-a65a-453c-bf95-101fde56ed1d} (Version 2.3 oder höher)
{c36177c0-224a-11da-8cd6-0800200c9a91} (Version 3.9.85.1-signed.1-signed oder höher)
{c37bac34-849a-4d28-be41-549b2c76c64e} (Version 2.6 oder höher)
{c45c406e-ab73-11d8-be73-000a95be3b12} (Version 1.2.11 oder höher)
{c50ca3c4-5656-43c2-a061-13e717f73fc8} (Version 5.0.1.48.1-signed.1-signed oder höher)
{C7AE725D-FA5C-4027-BB4C-787EF9F8248A} (Version 1.0.0.4 oder höher)
{c8d3bc80-0810-4d21-a2c2-be5f2b2832ac} (Version 0.98 oder höher)
{c9b4529a-eeba-4e48-976e-f3d3f9026e04} (Version 1.1.1-signed.1-signed oder höher)
{c9b4cd26-6f0e-4972-a9e0-8b77e811aa8f} (Version 2.3 oder höher)
{cb40da56-497a-4add-955d-3377cae4c33b} (Version 10.2.0.271 oder höher)
{cd617372-6743-4ee4-bac4-fbf60f35719e} (Version 2.0.1-signed.1-signed oder höher)
{cd617375-6743-4ee8-bac4-fbf10f35729e} (Version 2.9.6 oder höher)
{ce7e73df-6a44-4028-8079-5927a588c948} (Version 1.1.4 oder höher)
{d0bfdcce-52c7-4b32-bb45-948f62db8d3f} (Version 49.1 oder höher)
{d3b9472c-f8b1-4a10-935b-1087bac8417f} (Version 3.8 oder höher)
{d48a39ba-8f80-4fce-8ee1-bc710561c55d} (Version 3.1.0.1-signed.1-signed oder höher)
{d49a148e-817e-4025-bee3-5d541376de3b} (Version 3.1.1-signed.1-signed oder höher)
{D4DD63FA-01E4-46a7-B6B1-EDAB7D6AD389} (Version 0.9.10.1-signed.1-signed oder höher)
{d4e0dc9c-c356-438e-afbe-dca439f4399d} (Version 49.1 oder höher)
{d57c9ff1-6389-48fc-b770-f78bd89b6e8a} (Version 1.46.1-signed.1-signed oder höher)
{d7f46ca0-899d-11da-a72b-0800200c9a65} (Version 0.1.2.1-signed.1-signed oder höher)
{DAD0F81A-CF67-4eed-98D6-26F6E47274CA} (Version 1.8.1-signed.1-signed oder höher)
{daf44bf7-a45e-4450-979c-91cf07434c3d} (Version 2.0.5 oder höher)
{dbac9680-d559-4cd4-9765-059879e8c467} (Version 5.0.5 oder höher)
{DBBB3167-6E81-400f-BBFD-BD8921726F52} (Version 7125.2016.0115.2213 oder höher)
{dd3d7613-0246-469d-bc65-2a3cc1668adc} (Version 1.1.8.1-signed.1-signed oder höher)
{DEDA1132-B316-11DD-8BC1-4E5D56D89593} (Version 0.18 oder höher)
{df4e4df5-5cb7-46b0-9aef-6c784c3249f8} (Version 1.3.0.1-signed.1-signed oder höher)
{e001c731-5e37-4538-a5cb-8168736a2360} (Version 0.9.9.152 oder höher)
{E173B749-DB5B-4fd2-BA0E-94ECEA0CA55B} (Version 7.4.1-signed oder höher)
{e30e9060-21d5-11e3-8224-0800200c9a66} (Version 1.2.12 oder höher)
{e33788ea-0bb9-4502-9c77-bdc551afc8ad} (Version 1.0.4 oder höher)
{E4091D66-127C-11DB-903A-DE80D2EFDFE8} (Version 1.6.5.5.1-signed.1-signed oder höher)
{e4f94d1e-2f53-401e-8885-681602c0ddd8} (Version 1.0.1-signed.1-signed oder höher)
{e6a9a96e-4a08-4719-b9bd-0e91c35aaabc} (Version 1.3.1.1-signed.1-signed oder höher)
{E6C93316-271E-4b3d-8D7E-FE11B4350AEB} (Version 2.1.25.1-signed.1-signed oder höher)
{E71B541F-5E72-5555-A47C-E47863195841} (Version 3.0.3 oder höher)
{e8deb9e5-5688-4655-838a-b7a121a9f16e} (Version 48.4 oder höher)
{e8f509f0-b677-11de-8a39-0800200c9a66} (Version 1.12.1-signed.1-let-fixed.1-signed oder höher)
{e968fc70-8f95-4ab9-9e79-304de2a71ee1} (Version 0.7.3.1-signed.1-signed oder höher)
{ea2b95c2-9be8-48ed-bdd1-5fcd2ad0ff99} (Version 0.3.8.1.1-signed.1-signed oder höher)
{ea4637dc-e014-4c17-9c2c-879322d23268} (Version 2.1.1-signed.1-signed oder höher)
{ea61041c-1e22-4400-99a0-aea461e69d04} (Version 0.2.4.1-signed.1-signed oder höher)
{eb4b28c8-7f2d-4327-a00c-40de4299ba44} (Version 1.7 oder höher)
{eb80b076-a444-444c-a590-5aee5d977d80} (Version 2.6.18 oder höher)
{eb8fff7e-1dce-4f3f-a51d-d9513ed6bab4} (Version 3.8 oder höher)
{ef4e370e-d9f0-4e00-b93e-a4f274cfdd5a} (Version 1.4.10.1-signed oder höher)
{f13b157f-b174-47e7-a34d-4815ddfdfeb8} (Version 0.9.89.1-signed.1-signed oder höher)
{f36c6cd1-da73-491d-b290-8fc9115bfa55} (Version 3.0.9.1-signed.1-let-fixed.1-signed oder höher)
{f3f219f9-cbce-467e-b8fe-6e076d29665c} (Version 50 oder höher)
{F5DDF39C-9293-4d5e-9AA8-E04E6DD5E9B4} (Version 1.6.3.1-signed.1-signed oder höher)
{F8A55C97-3DB6-4961-A81D-0DE0080E53CB} (Version 1.0.10 oder höher)
{fa8476cf-a98c-4e08-99b4-65a69cb4b7d4} (Version 1.7.6.1 oder höher)
{FBF6D7FB-F305-4445-BB3D-FEF66579A033} (Version 6 oder höher)
{FDBAD97E-A258-4fe3-9CF6-60CF386C4422} (Version 2.0.1.6 oder höher)
{fe272bd1-5f76-4ea4-8501-a05d35d823fc} (Version 2.1.9.1-signed.1-let-fixed.1-signed oder höher)

Der Beitrag Firefox 51: Multiprozess-Architektur mit 773 weiteren Add-ons kompatibel erschien zuerst auf soeren-hentzschel.at.

11. Januar 2017

Bei Discord handelt es sich um einen kostenlosen Client für Text- und Sprach-Chats. Zum Einsatz kommt das Programm hauptsächlich bei Gamern als Alternative zu Teamspeak. Heute wurde offiziell die erste Version für Linux veröffentlicht.

Auf der offiziellen Seite steht die Linuxversion als Deb-Paket sowie als Tar.gz-Archiv zum Download bereit. Da die Software allerdings nicht quelloffen ist, wird sie für den einen oder anderen nicht in Frage kommen. Persönlich wäre mir zum Beispiel Mumble auch lieber, aber bei vielen Spielen ist Discord inzwischen zum Standard geworden und bietet auch mehr Funktionen als so manche quelloffene Lösung.

Nutzer von Arch finden Discord im AUR.

Unter dem Namen Test Pilot führt Mozilla Experimente durch, welche es Firefox-Nutzern ermöglichen, potentielle neue Funktionen vorab zu testen und Feedback zu geben. Nun hat man gemeinsam mit Cliqz ein neues Experiment für deutschsprachige Nutzer gestartet.

Cliqz ist der Anbieter eines Browsers für den Desktop, Android und iOS sowie einer Erweiterung für den Firefox-Browser. Desktop- sowie iOS-Browser basieren auf Firefox von Mozilla. Das Besondere an Cliqz ist die Integration einer Schnellsuche in die Adressleiste sowie der Fokus auf Privatsphäre und Antitracking. Die Münchner Cliqz GmbH ist eine Mehrheitsbeteiligung des Medienkonzerns Hubert Burda Media. Im August 2016 hat Mozilla eine Beteiligung an der Cliqz GmbH bekannt gegeben.

Nun hat man ein gemeinsames Experiment im Rahmen von Test Pilot gestartet, welches einen wesentlichen Teil der bereits bekannten Firefox-Erweiterung in Firefox bringt. Somit werden Ergebnisse in der Adressleiste von Firefox anders dargestellt, vor allem aber werden bereits während der Eingabe Ergebnisse präsentiert. Dies beschränkt sich nicht nur auf das Vorschlagen von Domains. Ob aktuelle Fluginformationen, das Wetter, Nachrichten oder die Umrechnung zwischen Währungen: all dies geschieht live während der Eingabe, ohne dass der Anwender hierfür eine Webseite besuchen muss.

Cliqz Test Pilot

Cliqz Test Pilot

Cliqz Test Pilot

Cliqz Test Pilot

Cliqz Test Pilot

Cliqz Test Pilot

Cliqz Test Pilot

Auch die Seite, die beim Öffnen eines neuen Tabs erscheint, wird durch das Experiment ersetzt. Diese ist zweigeteilt zwischen den meistbesuchten Webseiten sowie Seiten, welche der Nutzer selbst hinzufügen kann.

Cliqz Test Pilot

Das neue Test Pilot-Experiment richtet sich ausschließlich an deutschsprachige Nutzer. Gleichzeitig wurden die Experimente Activity Stream, Tracking Protection sowie No More 404s auf der Test Pilot-Webseite aus Kompatibilitätsgründen deaktiviert. Wer wenigstens eines dieser Experimente aktiviert hat, erhält auf der Seite des Cliqz-Experiments einen entsprechenden Kompatibilitäts-Hinweis.

Der Beitrag Firefox: Mozilla und Cliqz starten Test Pilot-Experiment erschien zuerst auf soeren-hentzschel.at.

Der Kauf eines WLAN-Routers / WLAN-Accesspoints hat mit dem eines Autos oder eines neuen Laptops eins gemeinsam: Beworbene Leistungsmerkmale sind gnadenlos geschönt und werden in der Realität nicht erreicht. Das Auto verbraucht mehr Kraftstoff als angegeben, der Laptop-Akku hält nur halb so lange, wie angegeben, und der WLAN-Router lässt nicht die 750 MBit/s Datenübertragungsrate zu, die auf der Packung groß angegeben ist. Manchmal muss man sich mit einem Zehntel der Leistung begnügen. Mindestens von einer Halbierung muss aber in jedem Fall ausgegangen werden. In diesem Beitrag will ich erklären, welche Faktoren zu der erheblich geringeren Übertragungsleistung beitragen.

WLAN ist ein Shared Medium

Um zu verstehen, wieso WLAN meistens wesentlich langsamer ist, als angegeben, ist es wichtig zu verstehen, wie WLAN im Groben funktioniert. WLAN ist ein sog. “Shared Medium”, d.h. das Übertragungsmedium “Elektromagnetische Welle” wird von allen beteiligten Netzwerkteilnehmern in Anspruch genommen. Das Medium kann auf einem Funkkanal (in einem Frequenzbereich) allerdings immer nur von einem Sender belegt werden, um gegenseitige Störung zu verhindern. Der Zugriff aller Teilnehmer auf diesem Funkkanal muss daher über ein sog. Arbitrierungsverfahren geregelt werden. Im Fall von WLAN heißt das Verfahren “CSMA/CA” (Carrier Sense Multiple Access / Collision Avoidance).

Würden alle Teilnehmer gleichzeitig senden, könnte der Empfänger keine verwertbaren Informationen mehr empfangen. (Man stelle sich einen Marktplatz vor, auf dem alle Händler durcheinander rufen). Der Einsatz von CSMA/CA bedeutet, dass jeder Teilnehmer zuerst auf dem Medium lauscht, ob ein anderer Teilnehmer bereits sendet. Erst, wenn das Medium frei ist, beginnt er, seine Datenpakete zu senden. Dieses geordnete Sendeverfahren führt zwangsläufig dazu, dass ein Großteil der sende-bereiten Teilnehmer warten muss, bis das Medium wieder frei ist. Eine hohe Anzahl von sende-bereiten Teilnehmern führt also zu längeren Wartezeiten für jeden einzelnen.

Übrigens liegt hier auch das Problem mit Nachbarn, deren WLAN auf demselben Kanal funkt: Ein WLAN im selben Frequenzbereich bedeutet, dass der Zugriff auf den Kanal nicht nur mit den eigenen Geräten abgesprochen werden muss, sondern auch mit den Geräten des Nachbarn.

=> Mehr Teilnehmer, längere Wartezeiten beim Senden, weniger Datendurchsatz.

Ergänzung: MU-MIMO (Multi-User Multiple Input / Multiple Output) ermöglicht im Gegensatz zur oben beschriebenen Technik die gleichzeitige Nutzung von mehreren Datenstreams (gleichzeitiges Senden an mehrere Empfänger auf demselben Funkkanal). Dadurch steht jedem einzelnen Client ein Stream längere Zeit zur Verfügung, oder kann sogar dauerhaft genutzt werden (je nach Anzahl der Clients und MU-MIMO Modus). MU-MIMO ist allerdings noch relativ neu und bisher nur in wenigen Geräten verfügbar.

Reduzierung der Nutzdatenrate durch Protokoll-Overhead

Nicht nur die Tatsache, dass sich ein Übertragungsmedium geteilt werden muss, schränkt die Datenrate im WLAN ein - das vorher genannte Arbitrierungsverfahren CSMA/CA erkennt mehrere “unabsichtlich” gleichzeitig sendende Teilnehmer nicht während des Sendevorgangs (anders als CSMA/CD, welches mit WLAN allerdings nicht eingesetzt werden kann). Um Kollisionen durch gleichzeitig sendende Teilnehmer dennoch zu erkennen (und dann eine Sendewiederholung aufzulösen), sendet der Empfänger nach dem Empfang eines Pakets eine Antwort, welche den erfolgreichen Empfang bestätigt. Selbstverständlich nehmen auch diese Bestätigungen einen gewissen Zeitrahmen bei der Übertragung ein, sodass in dieser Zeit von keinem anderen WLAN-Teilnehmer gesendet werden kann.

Datenübertragungen, die nur der Übertragungs-Koordination dienen, werden auch “Protocol Overhead” genannt: Von Ihnen hat der Nutzer eines Netzwerks keinen direkten Nutzen. Dennoch sind sie zur geordneten Nachrichtenübermittlung notwendig. Da digitale Datenübertragungen im WLAN auf mehreren Protokoll-Schichten (logischen Ebenen) stattfinden, und jede Ebene eigenen Overhead zur Absicherung und Koordination der Übertragung mitbringt, summieren sich die für den Anwender “nicht-nutzbaren” Anteile einer Datenübertragung über die Ebenen hinweg auf - bis eine Anwendernachricht “Hallo” auf der höchsten Übertragungsschicht in einer vielfach so langen Nachricht auf unterster Übertragungsschicht (Physical Layer) resultiert.

Dieser Protocol-Overhead ist auch der Grund, wieso wir bei einer Gigabit-Leitung die volle Leistung scheinbar nie ausschöpfen können: Wer schon einmal eine große Datei über Gigabit-LAN auf einen anderen Rechner kopiert hat, wird festgestellt haben, dass die Datei nicht mit den maximalen 120 MB/s übertragen wird, sondern deutlich weniger. Tatsächlich ist die Leitung aber voll ausgelastet - und zwar mit einer Mischung aus Metadaten für die Übertragung (Protocol-Overhead) und den eigentlichen Nutzdaten (der Datei).

=> Neben der Nutzdaten müssen auch Steuerdaten übertragen werden

Sendewiederholungen durch Störquellen und schlechten Empfang

Bei schlechtem Empfang und daraus resultierender schlechter Verbindungsqualität müssen fehlerhafte oder unvollständige Datenpakete neu versendet werden. Das mindert den Datendurchsatz zwischen Sender und Empfänger und blockiert den Funkkanal, sodass auch andere Teilnehmer in dieser Zeit nicht senden können. Rauschen tritt auf, denn nicht-WLAN-Geräte im selben Frequenzbereich senden, wie es z.B. bei Bluetooth der Fall ist. WLAN-Chipsätze enthalten bereits leistungsstarke Filter, die das Rauschen “herausrechnen” sollen. Das gelingt aber nur bis zu einem bestimmten Punkt - irgendwann muss auch der Filter kapitulieren und ein ungestörter Empfang ist nicht mehr möglich. Eine große Rolle spielen auch Funk-Interferenzen, die beispielsweise durch die Raumgeometrie verursacht werden. Funkwellen werden von Wänden und anderen Objekten im Raum anteilig reflektiert, überlagern sich selbst, und verstärken oder vermindern damit ihre Energie abhängig vom Standort selbst. Im freien Feld wird man also immer bessere Übertragungsraten messen können, als in Gebäuden.

Marketing-Tricks

Der Käufer eines WLAN-Routers ist auf große Zahlen fixiert, deshalb versuchen Hersteller alles, um mit großen Zahlen zu locken. So wird von vielen Herstellern die Leistung aller verfügbaren WLAN-Betriebsmodi aufsummiert: Der Router kann zwar beide Frequenzbänder (2,4 GHZ und 5 GHz) dank zweier separater Funk-Transceiver problemlos gleichzeitig bedienen - aber kein Endgerät beherrscht die Aggregierung der beiden Frequenzbänder und kann deshalb nur entweder 2,4 GHz WLAN oder 5 GHz WLAN nutzen. Beides gleichzeitig funktioniert nicht.

Mittels MU-MIMO lassen sich zwischen zwei Teilnehmern zwar theoretisch sehr hohe Datenraten erreichen, doch nur dann, wenn ein WLAN-Client einige Streams für sich einnehmen kann. Das kann nur gelingen, wenn beide WLAN-Teilnehmer (Sender und Empfänger) über mehrere Antennen verfügen und MU-MIMO -fähig sind. Bisher sind allerdings nur sehr wenige MI-MIMO-fähige Geräte auf dem Consumer-Markt erhältlich. Zudem profitiert man von MU-MIMO nur, wenn sich entweder viele Geräte im WLAN befinden, oder ein Gerät mehrere Antennen besitzt und so mehrere Streams gleichzeitig verarbeiten kann.

Zusammenfassung

Hersteller berechnen die Übertragungsleistung für den Aufdruck auf der Verpackung rein theoretisch und ohne Berücksichtigung von real auftretenden Effekten wie Störungen in Form von benachbarten Funkstationen, Interferenzen oder sonstige Quellen. Um eine möglichst hohe Zahl aufdrucken zu können, werden sogar die Einzelleistungen der verbauten WLAN-Transceiver addiert, obwohl diese für Endgeräte wie z.B. ein Laptop nicht kombiniert nutzbar sind. Der neueste Liebling der Hersteller ist MU-MIMO: Damit lassen sich theoretisch viel höhere Datenraten zwischen WLAN-Teilnehmern erreichen. Allerdings sind Endgeräte wie Laptops, Smartphones und Tablets meist noch nicht MU-MIMO-fähig und profitieren nur eingeschränkt von der neuen Technik.

Lasst euch also nicht von theoretischen Werten im Datenblatt oder auf der Packung in die Irre führen: Die Tatsächlich erreichbaren Übertragungsraten sind allein technisch begründet schon deutlich geringer. Abzüglich der Marketing-bedingten Übertreibungen und Tricksereien bleibt dann meist nicht mehr viel übrig.

– WordPress Blogchart –

feininger-stats

Dieser Beitrag stützt sich auf den ersten Schritt, die verschwundene Ministatistik aus WordPress zurückzuholen bzw. Ersatz dafür zu schaffen. Ziel war es, ein kleines, grafisches Diagramm zu erzeugen, das man in das Menüpanel von XFCE4 wie es bei Xubuntu zum Einsatz kommt, integriert – mit möglichst wenig Arbeit, geringem Ressourcenverbrauch und Tools, die ich eh so rumliegen habe.

(Update: Bugfix und Erweiterung, Nachtrag)

Teilweise ist das auch gelungen.

Es gibt ein praktisches Grafikformat, XPM, bei dem man eine Textrepresentation der Grafik mit ein wenig Syntax dekoriert, und fertig ist das Bild. Wird von sehr vielen Programmen verstanden, ist prima um zu kontrollieren, ob alles an seinem Platz ist, auch aus einem Textfenster heraus, und es kann einigermaßen per Hand erzeugt werden, umso besser je kleiner es ist und je  weniger Farben man hat. Klein und schwarz/weiß sollte es eh werden – dafür könnte man auch XBM nehmen, aber das macht kaum einen Unterschied, nur dass der XBM-Eintrag bei Wikipedia nur eine Wurzel ist.

Man erinnert sich – meine Blogstatistik liegt als ~/.bloglog in solchen Daten vor:

185451 8 8 59 20:00 2017-01-10
185455 4 3 60 21:00 2017-01-10
185455 0 0 60 22:00 2017-01-10
185457 2 2 60 23:00 2017-01-10

und ich wollte die letzten 48 Stunden abbilden, also von den letzten 48 Zeilen der Datei die Spalte 2. Meine naive Idee war es, irgendein Icon in der Titelleiste von XFCE, dem Desktop von Xubuntu, einzubinden, und dieses rhythmisch mit einer selbstgemachten Grafik zu überschreiben. Im original Iconpath hat der ordinäre User keine Schreibrechte. Die Lösung ist dann nicht, sich solche Rechte einzuräumen. Als isolierte Lösung, die man nur selbst verwendet wäre das vielleicht kein Problem, aber vielleicht rollt das nächste Update die Rechte zurück (eher nicht). Oder man verbloggt die Lösung, sie greift um sich und schwupp-di-wupp ist eine Sicherheitslücke gerissen. Man kann aber einen Starter im XFCE-Menü anlegen, verknüpft ihn mit einem Programm das gar nichts macht, und ordnet diesem ein Icon zu, das man da platziert, wo man selbst Schreibrechte hat, also unter /home/saskia oder wie man gerade heißt.

Das funktionierte als Schritt eins, aber dann war Schluss mit lustig. Erst erhöhte ich die Höhe meiner Leiste von 24 auf 32 Pixel, weil 32 größer ist als 24. :) Dann machte ich aus der Kopie irgendeiner XPM-Datei eine Schwarz-Weiß-Grafik, was auch gelang, aber Änderungen an dieser wurden nicht bemerkt. Man musste die Eigenschaft des Starters aufrufen, dann, ohne was zu ändern „Speichern“ drücken, und erst dann wurde die geänderte Grafik auch verändert angezeigt.

toxic-stats

Und das zweite Ärgernis: Eine 3232 Grafik wurde schön angezeigt, aber eine 3248 Grafik nicht, wobei ich zwischenzeitlich noch in die übliche Grafikformatfalle tappte, x und y zu vertauschen – bei quadratischem Ausgangsmaterial passiert das leicht, und aus dem Matheunterricht kennt man das: erst die x-Achse, dann y. X ist ja auch im Alphabet vor Y. In der Textwelt ist es aber meist: Erst Zeile, dann Spalte – auch der Röhrenfernseher baut das Bild zeilenweise auf, so wie man einen Text schreibt. Physiker! Dann gibt es noch die Anomalie, dass der 0-Punkt oben liegt und nach unten die Werte größer werden – sehr unmathematisch das Ganze.

Also das 32*48 Pixelbild wurde schon angezeigt, aber so gestaucht, dass die 48er Breite auf 32 runtergerechnet wurde, so dass die Höhe nur noch 2/3 von 32 betrug, also ca. 20 Pixel, und da gehen natürlich manche Säulen des Säulendiagramms verloren.

blogchart

32*48

Jetzt gibt es viele Plugins, die alles mögliche in die Kopfzeile, die man auch an den Fuß des Bildschirms legen kann, malen, etwa eine CPU-Überwachung, die sogar sekündlich aktualisiert wird. Das sollte doch irgendwie gehen. Ich versuchte rauszufinden, wie solche Plugins heißen, was leider nicht so trivial ist. Die meisten tauchen in der Konfigurationsliste mit einem Namen auf, zu dem man kein Programm findet, weil die Liste übersetzt ist, während die Programmnamen englisch sind.

Dann hatte ich mit Pythonskripten gerechnet, weil allüberall die Linuxer gerne Python machen und Python ist ja auch nicht verkehrt, verglichen mit anderen P-Sprachen, wie PHP oder Perl, was auf dem Server manchmal eingesetzt wird, wobei Perl eigentlich ein Kuhdorf, 1,6km von Apach entfernt ist, und Apach ist kein Webserver, aber das führt hier zu weit. Nur wo wir dabei sind: Wer da wohnt, der sollte doch mal ein Foto machen von einem Bus vor dem Ortschild von Perl, und auf dem Bus müsste „Apach“ stehen, und man müsste es so beschneiden, dass der Betrachter glauben kann, da folge noch ein e. Oder umgekehrt vor dem Ortschild von Apach mit einem Bus nach Perl.

Zurück zum Thema: Ich fand also plugins, aber das waren .so-Dateien. Das deutet auf compilierten C- oder C++-Code hin, Sprachen, die ich zwar mal gelernt habe, aber die sind sehr systemnah, und bei Fehlern schmiert einem das halbe System ab.

Also kurz gegoogelt, und die Lösung rasch fast auf dem Präsentierteller bekommen: Das XFCE4-Genmon-Plugin. Mon für montags… – für monitoring, und gen für generisch. Eine Anleitung gefunden, auch hier wieder gesucht, wie das Teil auf deutsch heißt, ob es vielleicht schon unbemerkt installiert ist (ist es nicht), installiert sowie auch ein paar fertige Beispielexemplare, die ich dann aber gar nicht angeschaut habe, Befehl dazu:

apt-get install xfce4-genmon-plugin xfce4-goodies

Da haben sich gleich verschiedene Lösungen angeboten. Ich dachte, eine kl. Grafik, 32×48 will ich und etwas Text, nämlich den Maximalwert der letzten 48 Stunden und den letzten Messwert, der, da am Rand, oft schlecht zu sehen ist, und im Falle eines Ausreißers mit sagen wir 200 Abrufen, da werden die Striche so klein, dass man schlecht noch abschätzen kann, ob das jetzt 10 oder 20 Abrufe waren, und müsste 48 Stunden warten, bis der Peak ausgewandert ist.

Man braucht einfach nur ein Script zu schreiben, das eine XML-Datei erzeugt, und diese verweist auf eine Grafik, die entsprechend der Einstellungen aktualisiert wird. Mein Script nannte ich blogchart.sh und legte erst 3s fest, um schnell zu sehen, ob sich was tut, dann später 30s, damit ich Zeit hatte, die vom Script erzeugte Grafik noch zu sichern, bevor der nächste Lauf sie überschreibt, und am Ende 3600s, weil das eine Stunde ist, und sich so oft mein .bloglog ändert.

  • Befehl: blogchart.sh
  • [ ] Beschriftung:
  • Intervall(s): 3600
#!/bin/bash
#
#
# Erweiterung wird unten wechselnd angehängt (xpm/png) 
img=/home/stefan/.blogchart
# Bei mehr oder weniger als 48 Stunden hier anpassen (aber auch in der Funktion asciiart):
views=($(tail -n 48 ~/.bloglog | awk '{print $2}' | column -x))
# Debug:
# views=(5 4 10 8 6 6 5 4 4 3 5 0)

Der Bildnamensvorname mit Pfad taucht öfter auf, also legt man eine Variable an, um es später kurz zu haben.

Views nimmt die letzten 48 Zeilen aus ~/.bloglog und awk filtert daraus die die 2. Spalte. Das ganze wird von column dann in eine Serie von Werten nebeneinander gestellt, statt in 48 Zeilen, was beim Debugging störend ist. Die runden Klammern mit dem $ sorgen dafür, dass die Ausgabe des Befehls ausgewertet werden kann, und die runden Klammern darum wieder, machen aus den Werten ein Array, so wie zwei Zeilen tiefer zu sehen, nur dass es da nicht 48 sind. Es ist auch störend, wenn man was berechnet hat beim Debuggen und sich an Werte gewöhnt hat, und dann sind 60 Minuten um und man hat ganz andere Werte.

max () {
 maximum=0
 for view 
 do
   test $view -gt $maximum && maximum=$view
 done
 echo $maximum 
}
m=$(max ${views[@]})
# Avoid Div/0:
test $m -eq 0 && m=1

Jetzt brauchen wir das Maximum und – man glaubt es nicht – die Bash hat keine fertige Maximumsfunktion! Gut – so oft braucht man die auch nicht; ich habe nämlich auch keine.

Diese Form der For-Loop ist etwas überraschend. Normal sieht man sowas wie:

  • for obst in apfel birne banane
  • for i in 3 4 7
  • for (( x=0;  x<10; x+=1 ))

aber hier – woher? Nun, von den Funktionsparametern bzw. hier dem Array, das ich oben definiert habe und mit dem ich die Funktion aufrufe, also den Abrufzahlen pro Stunde.

Für die Debugwerte sollte das 10 ergeben und tut es auch. max ${views[@]} ist der Funktionsaufruf mit dem kompletten Array (@), m=$(…) die Zuweisung der Ausgabe (deswegen echo) an die neue Variable m. Bitte keine Backticks verwenden!

Den Maximalwert brauchen wir aus zwei Gründen: Einmal um ihn anzuzeigen, einmal um die Messwerte so zu strecken, dass der Maximalwert genau die volle Höhe einnimmt, und die anderen Werte werden dann so umgerechnet, dass diese proportional dazu kleiner sind, bis auf Rundungsfehler.

Das macht meine Funktion auf32:

auf32 () {
 m=$1
 shift
 # echo Parameter: $#
 # Bei anderer Imagehöhe als 32 hier anpassen: 
 for hour
 do
   echo -n $((hour*32/m))" "
 done
 echo 
}

normalized=$(auf32 $m ${views[*]})

Klein m ist der Maximalwert, den ich als ersten Parameter der Funktion übergebe und da auch genauso benenne. Man könnte auch von der inneren Funktion auf die äußere, bereits definierte Variable zugreifen, aber globale Variablen sind bekanntlich von Übel. Das shift schiebt alle Parameter um eins nach vorne, hat man den ersten noch nicht ergriffen ist er jetzt endgültig weg. Jetzt ist also der m-Wert fort und nur noch das Array bildet die Parameter.

Was ich eben noch view nannte, und in der Einzahl kein guter Name ist, aber views war schon belegt, nenne ich hier hour. Gemeint sind die views per hour, also 5, 4, 10 nach den Testwerten. Mit $((…)) kann man in der Bash etwas Ganzzahlarithmetik betreiben. Mathematiker vorsicht! hour32/m ist hier nicht das gleiche wie hour/m32. Hour ist maximal so groß wie m, viele Werte sind kleiner. 10/10 ist also 1, alle anderen Werte sind kleiner/gleich 1 aber größer/gleich 0, wenn kein Fehler aufgetreten ist, und werden zu 0 abgeschnitten. Nicht gerundet – abgeschnitten. 0,99 wird 0. Und das kann man gerne mit 32 multiplizieren, das bleibt 0. Aber multipliziert man zuerst, dann wird aus 5, 4, 10 – ähm, (128+32=160), 128, 320. Das jeweils durch 10 sind 16, 12, 32. So soll das sein. Wer unbedingt runden will addiert zwischendrin 5, also (hour*32+5)/m, Punkt vor Strich akzeptiert die Shell, ansonsten von links nach rechts.

Außer m wäre Null, das könnte bei schlechtbesuchten Blogs ja in 48 Stunden mal vorkommen, daher oben die Sicherung für Div/0-Fehler.

Das echo -n unterdrückt die neue Zeile nach echo, die Leerstelle muss sein, damit die Werte nicht aneinanderkleben (161232). Das Ergebnis speichere ich in normalized. Diesmal benutze ich den * für das ganze Array:

${views[*]}

nicht das @, wieso weiß ich nicht, eine Laune, hier macht es keinen Unterschied. Wo macht es einen Unterschied? Ich glaube bei Strings mit Leerstellen:

t201:~/bin > namen=(a "b b" ccc)
t201:~/bin > for s in "${namen[@]}"; do echo $s"-"; done 
a-
b b-
ccc-
t201:~/bin > for s in "${namen[*]}"; do echo $s"-"; done 
a b b ccc-

Macht das Sinn? Nein. Kann man sich das merken? Nein. Man kann es nur rasch ausprobieren, dann weiß man es wieder. Oder man benutzt es so oft, dass man es automatisch lernt. Sich hinsetzen und sowas lernen, ohne es sicher zu brauchen, da vermüllt man sich das Hirn. Das Bashmanual kann man auch nicht lesen – es ist zu lang, und da gibt es noch mehr solcher Merkwürdigkeiten, etwa 3 unterschiedliche ifs.

In normalized steht jetzt also (16 12 32 …). Prima. Wir kommen zur letzten Funktion, dem 2.letzten Block und 3.letzten Thema. Wir lassen nämlich das XML der Funktion erst weg und konzentrieren uns aufs grafisch/mathematische.

asciiart () {
 # Und hier Bildhöhe anpassen, Pixelzahl
 for row in {32..1}
 do
   echo -n '"'
   for traffic in ${normalized[@]}
   do
     test $traffic -ge $row && echo -ne "* " || echo -ne "  " # 2 Leerzeichen
   done
   echo '",'
 done
}

Hier wurde ich der Devise mit den globalen Variablen untreu, wie mir gerade auffällt (normalized) aber der Reihe nach. {32..1} erzeugt einfach eine Serie Zahlen von 32 bis 1 und merkt von selbst, dass es rückwärts geht, also 32 31 30 29 … 3 2 1 wird hier erzeugt. Für jede Zeile der Asciiartdatei gebe ich Gänsefüßchen aus. Und dann laufe ich durch meine normalisierten Werte und schaue, ob sie größer oder gleich der Zeilenzahl sind. Wenn ja gebe ich ein „* “ aus, sonst “  “ (2 Leerzeichen). Statt -ne müsste bei echo eigentlich -n reichen – e ist für extended characters oder sowas. Und nach jeder Zeile Gänsefüßchen zu, und Komma.

Jetzt müssen wir uns das XPM-Format genau ansehen. Es gibt einige Freiheiten, die man selbst nachschlagen kann. Ich erkläre nur das nötigste.

Es muss mit diesem XPM in einem C-artigen Kommentar beginnen (s.u.). Anfangs hatte ich darum aus Nachlässigkeit auch Gänsefüßchen – ein schwer zu findender Fehler! Dann eine C-style Stringdefinition. Muss man nicht kennen, kann man Zeichen für Zeichen übernehmen. Dann kommt, in Gänsefüßchen, Breite, Höhe (4832), Zeichenlänge pro Pixel (2) und Anzahl der Farben (2). Als Zeichenlänge würde 1 natürlich genügen für 0 oder 1, schwarz oder weiß, aber da die Schriftzeichen bei Bildschirmschrift ca. doppelt so hoch wie breit sind wirkt dann alles gestreckt. 2 ist also auch für uns nicht verkehrt. Unser Hintergrund soll weiß sein, das ist „. „-codiert (“  „, die Balken schwarz, dafür nehme ich ein „M “ („ „, das ziemlich viele Pixel bedeckt. Keine schlechte Idee, außer um darüber bei WordPress zu berichten, welches mehrere Leerzeichen in Folge eindampft – in Wirklichkeit habe ich zwei Leerzeichen und ein Sternchen benutzt aber das ist normalerweise ziemlich wumpe. Man hätte auch zwei M verwenden können – immerhin haben wir gesagt, Zeichenlänge 2, das ergibt bei 80 legalen Zeichen (a-zA-Z0-9 und einigen Sonderzeichen) 80*80 darstellbare Farben. Eine Darstellungsoption ist die bekannte Hexcodierung #(rr)(gg)(bb) für die rot/grün/blau-Werte von 00 über 99 bis ff. Das kleine M in den zwei Farbkodierungen steht für monochrom aber auch c sollte hier funktionieren für color.

Wie Sie sehen sehen Sie nichts. Ja doch, aber nicht 48 Spalten und 32 Zeilen – ich habe es gekürzt, der Übersichts halber, und zähle jetzt nicht nach, wie breit und hoch das Bild wirklich ist. Nach dem 5zeiligen Header folgen dann die Bildpunkte als Text. Übrigens wurde ja schon angedeutet, dass vielfarbige XPMs gibt und das System mit einigen schon ankommt. Oft wird die Zeichenkodierung so gewählt, dass Buchstaben mit vielen Pixeln auch entsprechend dunklen Farbwerten zugeordnet sind, bzw. man erzeugt die  Grafikdateien programmatisch. So kann man sich einige ansehen:

cat $(locate er.xpm) | less

aber das nur am Rande. XPMEXT bedeutet, dass es XPM-Extensions am Ende der Datei gibt, die muss man deklarieren, wie Kippen beim Zoll, wenn man sie nutzen will.

 

/* XPM */
static char *XPM_example[] = {
"48 32 2 2 XPMEXT",
". m #ffffff",
"M m #000000",
". . . . . . . . . M . . . . . . ",
". . . . . . . . . M . . . . . . ",
". . . . . . . . . M . M . . . . ",
". . . . . . . . . M . M . . . . ",
". . . M . . . . . M . M . . . . ",
". . . M . . . . . M . M . . . . ",
". . . M . . . . . M . M . . . . ",
". . . M . . . . . M . M . . . . ",
". . M M . . . . . M . M . . M . ",
". . M M M . . . . M . M M . M . ",
". . M M M . M M . M . M M M M . ",
". . M M M . M M . M . M M M M . ",
". . M M M M M M . M . M M M M . ", 
"XPMEXT author demystifikation.wordpress.com GPLv3",
"XPMENDEXT"
};

Jetzt sehen wir auch die Extensions. Wie man sieht überflüssiger Kokolores, aber er ist aus einem Grund praktisch. Später dazu.

Hier der Code im ganzen, der das XML erzeugt:

asciiart () {
 echo -e '/* XPM */'
 echo -e 'static char *XPM_example[] = {'
 # Erste Zahl ist Breite, zweite ist Höhe, also 48 32 für 2 Tage bei 32 Pixeln, sonst hier anpassen
 echo -e '"48 32 2 2 XPMEXT",'
 echo -e '"  m #ffffff",'
 echo -e '"* m #000000",'
 # Und hier Bildhöhe anpassen, Pixelzahl
 for row in {32..1}
 do
   echo -n '"'
   for traffic in ${normalized[@]}
   do
     test $traffic -ge $row && echo -ne "* " || echo -ne "  " # 2 Blanks!
   done
   echo '",'
 done
 echo '"XPMEXT author demystifikation.worpress.com GPLv3",'
 echo '"XPMENDEXT"'
 echo '};'
}

Oben Ausgabe des Headers, dann die besprochenen For-Loops, dann die extension die auch explizit und so beendet werden muss. Das Problem hier wäre, dass man ohne Extension nach dem letzen Anführungszeichen kein Komma braucht, um gültigen C-Code zu erzeugen, ja dass ein abschließendes Komma vor der geschweiften Klammer-Zu im XPM ungültig wäre. Das könnte man mit einer if-Abfrage abfangen, aber eine Abfrage, die 32x geprüft wird, um nur 1x anzuschlagen – das ist irgendwie eklig. Eigentlich nicht schlimm – der Prozessor rechnet das gerne und als es ins Gewicht fiel habe ich noch nicht gelebt, aber ich kann nicht anders. Es ist zusätzliche Komplexität, und Komplexität ist von Übel. Man kann nicht jede Komlexität vermeiden und sollte auch nicht, so einfach ist es auch nicht. Nein, es ist selbst wiederum komplex. Also wenn so eine Extension noch nachkommt, dann schadet das Komma nicht in der Loop sondern ist sogar nötig, und dafür lassen wir es in der letzten Zeile ganz unauffällig weg, ohne ein if zu benötigen.

Dennoch baut man ja bei solchen Strings, die man ausgibt, und die selbst der Maskierung bedürfen (Apostrophe) und Syntax klammern, die in Sonderfällen und Ausnahmen und Ausnahmen von den Ausnahmen – kurz und gut, mein Ergebnis war erst schrottig, dann wollten manche Programme das XPM anzeigen, andere nicht, dann war es ganz schrottig, dann wieder besser und man sucht sich einen Wolf. Man sollte mal einen XPM-Validator schreiben, denn ich habe zwischendurch einen gesucht, aber im Netz keinen gefunden.

Gimp wollte meine XPM-Files nicht öffnen, display, identify und andere Tools aus ImageMagick schon, der EOG-Viewer nicht aber Ristretto oder war es umgekehrt? Xpmtoppm hat auch nicht geklagt aber die, die rumgezickt haben, haben meist nicht verraten an welcher Stelle in der Datei sie stolpern. Einmal hieß es „zu wenig Pixeldata“ aber das war falsch. :)

Aber statt Testcases zu schreiben kann man auch über die Entwicklung bloggen. Da denkt man ja schneller, als man schreiben kann, und hat dann pro Satz ½ Satz Zeit, sich mit dem Inhalt zu befassen, über den man eigentlich gerne schnell wegginge, und in diesen Pausen findet man dann die Fehler. 3 Stück habe ich gefunden. Ich sollte gleich ein Buch schreiben und Seminare anbieten, BDD, blog-driven-development, der neue, heiße Scheiß!

Aber vorher binden wir noch Zutaten zu einem Menü zusammen, husch, husch!

# echo ${views[@]}
# echo $m
# echo ${normalized[*]}

asciiart > $img.xpm
# convert $img.xpm $img.png 
# n=${#views[*]}
# echo "<txt>Max: $m Last: ${views[n-1]}</txt>"
# übler hack, hier auf row aus der Schleife der Funktion zuzugreifen. 
echo "<txt>Max: $m Last: $row</txt>"
# echo "<img>$img.png</img>"
echo "<img>$img.xpm</img>"
echo "<tool>views: ${views[@]} normalized: ${normalized[@]} </tool>"

Ein paar auskommentierte Debugmeldungen, dann der große Moment, Aufruf von asciiart, Ausgabe der XPM-Datei nach $img.xpm. Zwischenzeitlich habe ich, weil das Menü mein xpm nicht fressen wollte, dieses mit convert, das mehr gierig als pedantisch ist, in png gewandelt, und das dann angezeigt. Jetzt , dank gefundener Fehler, geht auch xpm. Weitere Debugmeldungen, auskommentiert. Dann geht es weiter mit XML, wie es GenMon erwartet. Txt ist Text, der ausgegeben wird, im Bild unten Max: 24 Last: 11. Kommt auch von den Säulenhöhen hin. Dann mit img die eben erzeugte xpm-Datei, also der Pfad/Name dahin. Dann ein optionaler Tooltiptext. Auch mehr zu Debugzwecken.

blogchart

Zusätzlich kann man noch definieren, was bei Klick auf die Grafik passieren soll und was bei Click auf den Text (<click>, <txtclick>) und eine Progressbar kann es geben, mehr dazu beim Genmon-Link unten. Ich könnte noch die aktuelle Zahl vom Blogcounter abholen, für zwischen den vollen Stunden bei click hier, und bei click da die Grafik mit convert größer skalieren und mit display anzeigen.

Update 1: Eine vergrößerte Ansicht habe ich jetzt realisiert, und zwar mit ohne convert, das macht display  (auch im Paket ImageMagick, falls ich das noch nicht geschrieben habe) alleine, durch die Codezeile:

echo "<click>display -resize 480x320 $img.xpm</click>"

Das war ja einfach.

Und ein Hinweis noch: Zum Synchronisieren des Plugins mit der Abfrage der Werte durch cron, bei mir immer zur vollen Stunde, kann man in der Kommandozeile ein at-Kommando absetzen (at, wie das englische at in at 2pm oder at teatime), gibt man, z.B. für die 17:00 Uhr-Abfrage, das Kommando:

at 17:02
xfce4-panel --plugin-event=genmon-X:refresh:bool:true
(Ctrl-D)

ein. Statt X müsst Ihr einen Wert eingeben; wo der herkommt steht auf der genmon-Seite die unten verlinkt ist.

(end of update)

Aber irgendwo ist auch noch der Wurm drinnen. Der Maximalwert stimmt, aber das Log stimmt nicht mit den Werten überein, die aber unverdächtig wirken. Das werde ich noch suchen, wenn es nicht vorher ein Leser findet und im Kommentar erklärt. Sonst Updates hier, eher kein neuer Beitrag.  Schreibt einen Kommentar, wenn Ihr drauf wartet. 

Update 2: Dem column-Programm muss man den Schalter -x übergeben, sonst formatiert es die Zahlen 1 2 3 4 5, jeweils in einer Zeile übergeben, so:

1 4
2 5
3

statt so:

1 2
3 4
5

(end of update)

Und noch 2 Worte zu bekannten Schwächen: Wenn man den Rechner ausschaltet, dann legt er keine Messung an. Beim Anschalten haben sich dann vielleicht viele Visits angesammelt, aber auch über viele Stunden verteilt. Ich habe beschlossen die Zeit, obwohl sie mitprotokolliert wird, nicht zu berücksichtigen. Man könnte damit dann zwar einen breiten Block anlegen, und die Abrufe darauf verteilen, also nach 15 Stunden und 150 Aufrufen würde man einfach das Mittel nehmen, 10 pro Stunde. Das würde das Programm aber sehr aufblähen und kompliziert machen. Das Programm zeigt also in Wahrheit die letzten 48 Messpunkte an, nicht 48 Stunden.

Generell habe ich mir wenig Gedanken gemacht, was alles schief gehen kann, und wie man dann die Situation am besten rettet. Da das Programm noch ganz frisch ist, sollte sich das im Laufe der Zeit von selbst ergeben.

Und bedanken muss ich mich bei den Entwicklern von GenMon. Das ist ja ein superflexibles Tool und einfach zu verwenden. Die Doku könnte noch ausführlicher sein, aber der erste Eindruck ist Klasse!

Hilfreiche Links:

Nachtrag:

Jetzt, wo ich meine eigene Lösung fertig habe, finde ich den neuen Ort, an dem WordPress die Ministatistik versteckt hat!

Und zwar wenn man den Blog in der Leseansicht offen hat, nicht im Bearbeitenmodus ist, und dann links oben „Meine Webseite“ klickt, dann klappt das Seitenmenü auf, und oben steht „Statistik“, daneben ein Balkendiagramm. Das ist nicht nur eine Erinnerungsgrafik für die, die vergessen haben, wie eine Statistik aussieht, sondern das sind die aktuellen Werte d. letzten 48 Stunden. Um das zu erkennen muss man freilich die aktuellen Werte kennen – gut, das war früher auch so. Auch dass es als Schaltfläche diente, um zur Statistikseite zu kommen. Ein Maximalwert zur Orientierung fehlt jetzt, aber wenn man die Zahl des letzten Tages kennt, kann man es wohl ungefähr abschätzen. Meine Lösung hat den Vorteil die Werte anzubieten, und immer sichtbar zu sein, aber den Nachteil Platz im Menü zu fressen. Ein anderer Vorteil für mich: Ich weiß jetzt wie es geht, wenn ich nochmal etwas derartiges brauche.

wp-statistik

Wie rechts nochmal zu sehen ist, mit anderer Proportion, sind das die gleichen Daten. Das hätte einem aber auch wer sagen können!

Und hier noch der Code als kompletter Block, ohne Gewähr:

#!/bin/bash
#
# (C) GPLv3, user unknown
#
# Erweiterung wird unten wechselnd angehängt (xpm/png) 
img=/home/stefan/.blogchart
# Bei mehr oder weniger als 48 Stunden hier anpassen (aber auch in der Funktion asciiart):
views=($(tail -n 48 ~/.bloglog | awk '{print $2}' | column -x))
# Debug:
# views=(5 4 10 8 6 6 5 4 4 3 5 0)
#
max () {
 maximum=0
 for view 
 do
   test $view -gt $maximum && maximum=$view
 done
 echo $maximum 
}

m=$(max ${views[@]})
# Avoid Div/0:
test $m -eq 0 && m=1

auf32 () {
 m=$1
 shift
 # echo Parameter: $#
 # Bei anderer Imagehöhe als 32 hier anpassen: 
 for hour
 do
   echo -n $((hour*32/m))" "
 done
 echo 
}

normalized=$(auf32 $m ${views[*]})

asciiart () {
 echo -e '/* XPM */'
 echo -e 'static char *XPM_example[] = {'
 # Erste Zahl ist Breite, zweite ist Höhe, also 48 32 für 2 Tage bei 32 Pixeln, sonst hier anpassen
 echo -e '"48 32 2 2 XPMEXT",'
 echo -e '"  m #ffffff",'
 echo -e '"* m #000000",'
 # Und hier Bildhöhe anpassen, Pixelzahl
 for row in {32..1}
 do
   echo -n '"'
   for traffic in ${normalized[@]}
   do
     test $traffic -ge $row && echo -ne "* " || echo -ne "  " 
   done
   echo '",'
 done
 echo '"XPMEXT author demystifikation.worpress.com GPLv3",'
 echo '"XPMENDEXT"'
 echo '};'
}

# echo ${views[@]}
# echo $m
# echo ${normalized[*]}

asciiart > $img.xpm
# convert $img.xpm $img.png 
# n=${#views[*]}
# echo "<txt>Max: $m Last: ${views[n-1]}</txt>"
# übler hack, hier auf row aus der Schleife der Funktion zuzugreifen. 
echo "<txt>Max: $m Last: $row</txt>"
# echo "<img>$img.png</img>"
echo "<img>$img.xpm</img>"
echo "<tool>views: ${views[@]} normalized: ${normalized[@]} </tool>"
echo "<click>display -resize 480x320 $img.xpm</click>"

– WordPress Blogchart –

feininger-stats

Dieser Beitrag stützt sich auf den ersten Schritt, die verschwundene Ministatistik aus WordPress zurückzuholen bzw. Ersatz dafür zu schaffen. Ziel war es, ein kleines, grafisches Diagramm zu erzeugen, das man in das Menüpanel von XFCE4 wie es bei Xubuntu zum Einsatz kommt, integriert – mit möglichst wenig Arbeit, geringem Ressourcenverbrauch und Tools, die ich eh so rumliegen habe.

(Update: Bugfix und Erweiterung, Nachtrag)

Teilweise ist das auch gelungen.

Es gibt ein praktisches Grafikformat, XPM, bei dem man eine Textrepresentation der Grafik mit ein wenig Syntax dekoriert, und fertig ist das Bild. Wird von sehr vielen Programmen verstanden, ist prima um zu kontrollieren, ob alles an seinem Platz ist, auch aus einem Textfenster heraus, und es kann einigermaßen per Hand erzeugt werden, umso besser je kleiner es ist und je  weniger Farben man hat. Klein und schwarz/weiß sollte es eh werden – dafür könnte man auch XBM nehmen, aber das macht kaum einen Unterschied, nur dass der XBM-Eintrag bei Wikipedia nur eine Wurzel ist.

Man erinnert sich – meine Blogstatistik liegt als ~/.bloglog in solchen Daten vor:

185451 8 8 59 20:00 2017-01-10
185455 4 3 60 21:00 2017-01-10
185455 0 0 60 22:00 2017-01-10
185457 2 2 60 23:00 2017-01-10

und ich wollte die letzten 48 Stunden abbilden, also von den letzten 48 Zeilen der Datei die Spalte 2. Meine naive Idee war es, irgendein Icon in der Titelleiste von XFCE, dem Desktop von Xubuntu, einzubinden, und dieses rhythmisch mit einer selbstgemachten Grafik zu überschreiben. Im original Iconpath hat der ordinäre User keine Schreibrechte. Die Lösung ist dann nicht, sich solche Rechte einzuräumen. Als isolierte Lösung, die man nur selbst verwendet wäre das vielleicht kein Problem, aber vielleicht rollt das nächste Update die Rechte zurück (eher nicht). Oder man verbloggt die Lösung, sie greift um sich und schwupp-di-wupp ist eine Sicherheitslücke gerissen. Man kann aber einen Starter im XFCE-Menü anlegen, verknüpft ihn mit einem Programm das gar nichts macht, und ordnet diesem ein Icon zu, das man da platziert, wo man selbst Schreibrechte hat, also unter /home/saskia oder wie man gerade heißt.

Das funktionierte als Schritt eins, aber dann war Schluss mit lustig. Erst erhöhte ich die Höhe meiner Leiste von 24 auf 32 Pixel, weil 32 größer ist als 24. :) Dann machte ich aus der Kopie irgendeiner XPM-Datei eine Schwarz-Weiß-Grafik, was auch gelang, aber Änderungen an dieser wurden nicht bemerkt. Man musste die Eigenschaft des Starters aufrufen, dann, ohne was zu ändern „Speichern“ drücken, und erst dann wurde die geänderte Grafik auch verändert angezeigt.

toxic-stats

Und das zweite Ärgernis: Eine 3232 Grafik wurde schön angezeigt, aber eine 3248 Grafik nicht, wobei ich zwischenzeitlich noch in die übliche Grafikformatfalle tappte, x und y zu vertauschen – bei quadratischem Ausgangsmaterial passiert das leicht, und aus dem Matheunterricht kennt man das: erst die x-Achse, dann y. X ist ja auch im Alphabet vor Y. In der Textwelt ist es aber meist: Erst Zeile, dann Spalte – auch der Röhrenfernseher baut das Bild zeilenweise auf, so wie man einen Text schreibt. Physiker! Dann gibt es noch die Anomalie, dass der 0-Punkt oben liegt und nach unten die Werte größer werden – sehr unmathematisch das Ganze.

Also das 32*48 Pixelbild wurde schon angezeigt, aber so gestaucht, dass die 48er Breite auf 32 runtergerechnet wurde, so dass die Höhe nur noch 2/3 von 32 betrug, also ca. 20 Pixel, und da gehen natürlich manche Säulen des Säulendiagramms verloren.

blogchart

32*48

Jetzt gibt es viele Plugins, die alles mögliche in die Kopfzeile, die man auch an den Fuß des Bildschirms legen kann, malen, etwa eine CPU-Überwachung, die sogar sekündlich aktualisiert wird. Das sollte doch irgendwie gehen. Ich versuchte rauszufinden, wie solche Plugins heißen, was leider nicht so trivial ist. Die meisten tauchen in der Konfigurationsliste mit einem Namen auf, zu dem man kein Programm findet, weil die Liste übersetzt ist, während die Programmnamen englisch sind.

Dann hatte ich mit Pythonskripten gerechnet, weil allüberall die Linuxer gerne Python machen und Python ist ja auch nicht verkehrt, verglichen mit anderen P-Sprachen, wie PHP oder Perl, was auf dem Server manchmal eingesetzt wird, wobei Perl eigentlich ein Kuhdorf, 1,6km von Apach entfernt ist, und Apach ist kein Webserver, aber das führt hier zu weit. Nur wo wir dabei sind: Wer da wohnt, der sollte doch mal ein Foto machen von einem Bus vor dem Ortschild von Perl, und auf dem Bus müsste „Apach“ stehen, und man müsste es so beschneiden, dass der Betrachter glauben kann, da folge noch ein e. Oder umgekehrt vor dem Ortschild von Apach mit einem Bus nach Perl.

Zurück zum Thema: Ich fand also plugins, aber das waren .so-Dateien. Das deutet auf compilierten C- oder C++-Code hin, Sprachen, die ich zwar mal gelernt habe, aber die sind sehr systemnah, und bei Fehlern schmiert einem das halbe System ab.

Also kurz gegoogelt, und die Lösung rasch fast auf dem Präsentierteller bekommen: Das XFCE4-Genmon-Plugin. Mon für montags… – für monitoring, und gen für generisch. Eine Anleitung gefunden, auch hier wieder gesucht, wie das Teil auf deutsch heißt, ob es vielleicht schon unbemerkt installiert ist (ist es nicht), installiert sowie auch ein paar fertige Beispielexemplare, die ich dann aber gar nicht angeschaut habe, Befehl dazu:

apt-get install xfce4-genmon-plugin xfce4-goodies

Da haben sich gleich verschiedene Lösungen angeboten. Ich dachte, eine kl. Grafik, 32×48 will ich und etwas Text, nämlich den Maximalwert der letzten 48 Stunden und den letzten Messwert, der, da am Rand, oft schlecht zu sehen ist, und im Falle eines Ausreißers mit sagen wir 200 Abrufen, da werden die Striche so klein, dass man schlecht noch abschätzen kann, ob das jetzt 10 oder 20 Abrufe waren, und müsste 48 Stunden warten, bis der Peak ausgewandert ist.

Man braucht einfach nur ein Script zu schreiben, das eine XML-Datei erzeugt, und diese verweist auf eine Grafik, die entsprechend der Einstellungen aktualisiert wird. Mein Script nannte ich blogchart.sh und legte erst 3s fest, um schnell zu sehen, ob sich was tut, dann später 30s, damit ich Zeit hatte, die vom Script erzeugte Grafik noch zu sichern, bevor der nächste Lauf sie überschreibt, und am Ende 3600s, weil das eine Stunde ist, und sich so oft mein .bloglog ändert.

  • Befehl: blogchart.sh
  • [ ] Beschriftung:
  • Intervall(s): 3600
#!/bin/bash
#
#
# Erweiterung wird unten wechselnd angehängt (xpm/png) 
img=/home/stefan/.blogchart
# Bei mehr oder weniger als 48 Stunden hier anpassen (aber auch in der Funktion asciiart):
views=($(tail -n 48 ~/.bloglog | awk '{print $2}' | column -x))
# Debug:
# views=(5 4 10 8 6 6 5 4 4 3 5 0)

Der Bildnamensvorname mit Pfad taucht öfter auf, also legt man eine Variable an, um es später kurz zu haben.

Views nimmt die letzten 48 Zeilen aus ~/.bloglog und awk filtert daraus die die 2. Spalte. Das ganze wird von column dann in eine Serie von Werten nebeneinander gestellt, statt in 48 Zeilen, was beim Debugging störend ist. Die runden Klammern mit dem $ sorgen dafür, dass die Ausgabe des Befehls ausgewertet werden kann, und die runden Klammern darum wieder, machen aus den Werten ein Array, so wie zwei Zeilen tiefer zu sehen, nur dass es da nicht 48 sind. Es ist auch störend, wenn man was berechnet hat beim Debuggen und sich an Werte gewöhnt hat, und dann sind 60 Minuten um und man hat ganz andere Werte.

max () {
 maximum=0
 for view 
 do
   test $view -gt $maximum && maximum=$view
 done
 echo $maximum 
}
m=$(max ${views[@]})
# Avoid Div/0:
test $m -eq 0 && m=1

Jetzt brauchen wir das Maximum und – man glaubt es nicht – die Bash hat keine fertige Maximumsfunktion! Gut – so oft braucht man die auch nicht; ich habe nämlich auch keine.

Diese Form der For-Loop ist etwas überraschend. Normal sieht man sowas wie:

  • for obst in apfel birne banane
  • for i in 3 4 7
  • for (( x=0;  x<10; x+=1 ))

aber hier – woher? Nun, von den Funktionsparametern bzw. hier dem Array, das ich oben definiert habe und mit dem ich die Funktion aufrufe, also den Abrufzahlen pro Stunde.

Für die Debugwerte sollte das 10 ergeben und tut es auch. max ${views[@]} ist der Funktionsaufruf mit dem kompletten Array (@), m=$(…) die Zuweisung der Ausgabe (deswegen echo) an die neue Variable m. Bitte keine Backticks verwenden!

Den Maximalwert brauchen wir aus zwei Gründen: Einmal um ihn anzuzeigen, einmal um die Messwerte so zu strecken, dass der Maximalwert genau die volle Höhe einnimmt, und die anderen Werte werden dann so umgerechnet, dass diese proportional dazu kleiner sind, bis auf Rundungsfehler.

Das macht meine Funktion auf32:

auf32 () {
 m=$1
 shift
 # echo Parameter: $#
 # Bei anderer Imagehöhe als 32 hier anpassen: 
 for hour
 do
   echo -n $((hour*32/m))" "
 done
 echo 
}

normalized=$(auf32 $m ${views[*]})

Klein m ist der Maximalwert, den ich als ersten Parameter der Funktion übergebe und da auch genauso benenne. Man könnte auch von der inneren Funktion auf die äußere, bereits definierte Variable zugreifen, aber globale Variablen sind bekanntlich von Übel. Das shift schiebt alle Parameter um eins nach vorne, hat man den ersten noch nicht ergriffen ist er jetzt endgültig weg. Jetzt ist also der m-Wert fort und nur noch das Array bildet die Parameter.

Was ich eben noch view nannte, und in der Einzahl kein guter Name ist, aber views war schon belegt, nenne ich hier hour. Gemeint sind die views per hour, also 5, 4, 10 nach den Testwerten. Mit $((…)) kann man in der Bash etwas Ganzzahlarithmetik betreiben. Mathematiker vorsicht! hour32/m ist hier nicht das gleiche wie hour/m32. Hour ist maximal so groß wie m, viele Werte sind kleiner. 10/10 ist also 1, alle anderen Werte sind kleiner/gleich 1 aber größer/gleich 0, wenn kein Fehler aufgetreten ist, und werden zu 0 abgeschnitten. Nicht gerundet – abgeschnitten. 0,99 wird 0. Und das kann man gerne mit 32 multiplizieren, das bleibt 0. Aber multipliziert man zuerst, dann wird aus 5, 4, 10 – ähm, (128+32=160), 128, 320. Das jeweils durch 10 sind 16, 12, 32. So soll das sein. Wer unbedingt runden will addiert zwischendrin 5, also (hour*32+5)/m, Punkt vor Strich akzeptiert die Shell, ansonsten von links nach rechts.

Außer m wäre Null, das könnte bei schlechtbesuchten Blogs ja in 48 Stunden mal vorkommen, daher oben die Sicherung für Div/0-Fehler.

Das echo -n unterdrückt die neue Zeile nach echo, die Leerstelle muss sein, damit die Werte nicht aneinanderkleben (161232). Das Ergebnis speichere ich in normalized. Diesmal benutze ich den * für das ganze Array:

${views[*]}

nicht das @, wieso weiß ich nicht, eine Laune, hier macht es keinen Unterschied. Wo macht es einen Unterschied? Ich glaube bei Strings mit Leerstellen:

t201:~/bin > namen=(a "b b" ccc)
t201:~/bin > for s in "${namen[@]}"; do echo $s"-"; done 
a-
b b-
ccc-
t201:~/bin > for s in "${namen[*]}"; do echo $s"-"; done 
a b b ccc-

Macht das Sinn? Nein. Kann man sich das merken? Nein. Man kann es nur rasch ausprobieren, dann weiß man es wieder. Oder man benutzt es so oft, dass man es automatisch lernt. Sich hinsetzen und sowas lernen, ohne es sicher zu brauchen, da vermüllt man sich das Hirn. Das Bashmanual kann man auch nicht lesen – es ist zu lang, und da gibt es noch mehr solcher Merkwürdigkeiten, etwa 3 unterschiedliche ifs.

In normalized steht jetzt also (16 12 32 …). Prima. Wir kommen zur letzten Funktion, dem 2.letzten Block und 3.letzten Thema. Wir lassen nämlich das XML der Funktion erst weg und konzentrieren uns aufs grafisch/mathematische.

asciiart () {
 # Und hier Bildhöhe anpassen, Pixelzahl
 for row in {32..1}
 do
   echo -n '"'
   for traffic in ${normalized[@]}
   do
     test $traffic -ge $row && echo -ne "* " || echo -ne "  " # 2 Leerzeichen
   done
   echo '",'
 done
}

Hier wurde ich der Devise mit den globalen Variablen untreu, wie mir gerade auffällt (normalized) aber der Reihe nach. {32..1} erzeugt einfach eine Serie Zahlen von 32 bis 1 und merkt von selbst, dass es rückwärts geht, also 32 31 30 29 … 3 2 1 wird hier erzeugt. Für jede Zeile der Asciiartdatei gebe ich Gänsefüßchen aus. Und dann laufe ich durch meine normalisierten Werte und schaue, ob sie größer oder gleich der Zeilenzahl sind. Wenn ja gebe ich ein „* “ aus, sonst “  “ (2 Leerzeichen). Statt -ne müsste bei echo eigentlich -n reichen – e ist für extended characters oder sowas. Und nach jeder Zeile Gänsefüßchen zu, und Komma.

Jetzt müssen wir uns das XPM-Format genau ansehen. Es gibt einige Freiheiten, die man selbst nachschlagen kann. Ich erkläre nur das nötigste.

Es muss mit diesem XPM in einem C-artigen Kommentar beginnen (s.u.). Anfangs hatte ich darum aus Nachlässigkeit auch Gänsefüßchen – ein schwer zu findender Fehler! Dann eine C-style Stringdefinition. Muss man nicht kennen, kann man Zeichen für Zeichen übernehmen. Dann kommt, in Gänsefüßchen, Breite, Höhe (4832), Zeichenlänge pro Pixel (2) und Anzahl der Farben (2). Als Zeichenlänge würde 1 natürlich genügen für 0 oder 1, schwarz oder weiß, aber da die Schriftzeichen bei Bildschirmschrift ca. doppelt so hoch wie breit sind wirkt dann alles gestreckt. 2 ist also auch für uns nicht verkehrt. Unser Hintergrund soll weiß sein, das ist „. „-codiert (“  „, die Balken schwarz, dafür nehme ich ein „M “ („ „, das ziemlich viele Pixel bedeckt. Keine schlechte Idee, außer um darüber bei WordPress zu berichten, welches mehrere Leerzeichen in Folge eindampft – in Wirklichkeit habe ich zwei Leerzeichen und ein Sternchen benutzt aber das ist normalerweise ziemlich wumpe. Man hätte auch zwei M verwenden können – immerhin haben wir gesagt, Zeichenlänge 2, das ergibt bei 80 legalen Zeichen (a-zA-Z0-9 und einigen Sonderzeichen) 80*80 darstellbare Farben. Eine Darstellungsoption ist die bekannte Hexcodierung #(rr)(gg)(bb) für die rot/grün/blau-Werte von 00 über 99 bis ff. Das kleine M in den zwei Farbkodierungen steht für monochrom aber auch c sollte hier funktionieren für color.

Wie Sie sehen sehen Sie nichts. Ja doch, aber nicht 48 Spalten und 32 Zeilen – ich habe es gekürzt, der Übersichts halber, und zähle jetzt nicht nach, wie breit und hoch das Bild wirklich ist. Nach dem 5zeiligen Header folgen dann die Bildpunkte als Text. Übrigens wurde ja schon angedeutet, dass vielfarbige XPMs gibt und das System mit einigen schon ankommt. Oft wird die Zeichenkodierung so gewählt, dass Buchstaben mit vielen Pixeln auch entsprechend dunklen Farbwerten zugeordnet sind, bzw. man erzeugt die  Grafikdateien programmatisch. So kann man sich einige ansehen:

cat $(locate er.xpm) | less

aber das nur am Rande. XPMEXT bedeutet, dass es XPM-Extensions am Ende der Datei gibt, die muss man deklarieren, wie Kippen beim Zoll, wenn man sie nutzen will.

 

/* XPM */
static char *XPM_example[] = {
"48 32 2 2 XPMEXT",
". m #ffffff",
"M m #000000",
". . . . . . . . . M . . . . . . ",
". . . . . . . . . M . . . . . . ",
". . . . . . . . . M . M . . . . ",
". . . . . . . . . M . M . . . . ",
". . . M . . . . . M . M . . . . ",
". . . M . . . . . M . M . . . . ",
". . . M . . . . . M . M . . . . ",
". . . M . . . . . M . M . . . . ",
". . M M . . . . . M . M . . M . ",
". . M M M . . . . M . M M . M . ",
". . M M M . M M . M . M M M M . ",
". . M M M . M M . M . M M M M . ",
". . M M M M M M . M . M M M M . ", 
"XPMEXT author demystifikation.wordpress.com GPLv3",
"XPMENDEXT"
};

Jetzt sehen wir auch die Extensions. Wie man sieht überflüssiger Kokolores, aber er ist aus einem Grund praktisch. Später dazu.

Hier der Code im ganzen, der das XML erzeugt:

asciiart () {
 echo -e '/* XPM */'
 echo -e 'static char *XPM_example[] = {'
 # Erste Zahl ist Breite, zweite ist Höhe, also 48 32 für 2 Tage bei 32 Pixeln, sonst hier anpassen
 echo -e '"48 32 2 2 XPMEXT",'
 echo -e '"  m #ffffff",'
 echo -e '"* m #000000",'
 # Und hier Bildhöhe anpassen, Pixelzahl
 for row in {32..1}
 do
   echo -n '"'
   for traffic in ${normalized[@]}
   do
     test $traffic -ge $row && echo -ne "* " || echo -ne "  " # 2 Blanks!
   done
   echo '",'
 done
 echo '"XPMEXT author demystifikation.worpress.com GPLv3",'
 echo '"XPMENDEXT"'
 echo '};'
}

Oben Ausgabe des Headers, dann die besprochenen For-Loops, dann die extension die auch explizit und so beendet werden muss. Das Problem hier wäre, dass man ohne Extension nach dem letzen Anführungszeichen kein Komma braucht, um gültigen C-Code zu erzeugen, ja dass ein abschließendes Komma vor der geschweiften Klammer-Zu im XPM ungültig wäre. Das könnte man mit einer if-Abfrage abfangen, aber eine Abfrage, die 32x geprüft wird, um nur 1x anzuschlagen – das ist irgendwie eklig. Eigentlich nicht schlimm – der Prozessor rechnet das gerne und als es ins Gewicht fiel habe ich noch nicht gelebt, aber ich kann nicht anders. Es ist zusätzliche Komplexität, und Komplexität ist von Übel. Man kann nicht jede Komlexität vermeiden und sollte auch nicht, so einfach ist es auch nicht. Nein, es ist selbst wiederum komplex. Also wenn so eine Extension noch nachkommt, dann schadet das Komma nicht in der Loop sondern ist sogar nötig, und dafür lassen wir es in der letzten Zeile ganz unauffällig weg, ohne ein if zu benötigen.

Dennoch baut man ja bei solchen Strings, die man ausgibt, und die selbst der Maskierung bedürfen (Apostrophe) und Syntax klammern, die in Sonderfällen und Ausnahmen und Ausnahmen von den Ausnahmen – kurz und gut, mein Ergebnis war erst schrottig, dann wollten manche Programme das XPM anzeigen, andere nicht, dann war es ganz schrottig, dann wieder besser und man sucht sich einen Wolf. Man sollte mal einen XPM-Validator schreiben, denn ich habe zwischendurch einen gesucht, aber im Netz keinen gefunden.

Gimp wollte meine XPM-Files nicht öffnen, display, identify und andere Tools aus ImageMagick schon, der EOG-Viewer nicht aber Ristretto oder war es umgekehrt? Xpmtoppm hat auch nicht geklagt aber die, die rumgezickt haben, haben meist nicht verraten an welcher Stelle in der Datei sie stolpern. Einmal hieß es „zu wenig Pixeldata“ aber das war falsch. :)

Aber statt Testcases zu schreiben kann man auch über die Entwicklung bloggen. Da denkt man ja schneller, als man schreiben kann, und hat dann pro Satz ½ Satz Zeit, sich mit dem Inhalt zu befassen, über den man eigentlich gerne schnell wegginge, und in diesen Pausen findet man dann die Fehler. 3 Stück habe ich gefunden. Ich sollte gleich ein Buch schreiben und Seminare anbieten, BDD, blog-driven-development, der neue, heiße Scheiß!

Aber vorher binden wir noch Zutaten zu einem Menü zusammen, husch, husch!

# echo ${views[@]}
# echo $m
# echo ${normalized[*]}

asciiart > $img.xpm
# convert $img.xpm $img.png 
# n=${#views[*]}
# echo "<txt>Max: $m Last: ${views[n-1]}</txt>"
# übler hack, hier auf row aus der Schleife der Funktion zuzugreifen. 
echo "<txt>Max: $m Last: $row</txt>"
# echo "<img>$img.png</img>"
echo "<img>$img.xpm</img>"
echo "<tool>views: ${views[@]} normalized: ${normalized[@]} </tool>"

Ein paar auskommentierte Debugmeldungen, dann der große Moment, Aufruf von asciiart, Ausgabe der XPM-Datei nach $img.xpm. Zwischenzeitlich habe ich, weil das Menü mein xpm nicht fressen wollte, dieses mit convert, das mehr gierig als pedantisch ist, in png gewandelt, und das dann angezeigt. Jetzt , dank gefundener Fehler, geht auch xpm. Weitere Debugmeldungen, auskommentiert. Dann geht es weiter mit XML, wie es GenMon erwartet. Txt ist Text, der ausgegeben wird, im Bild unten Max: 24 Last: 11. Kommt auch von den Säulenhöhen hin. Dann mit img die eben erzeugte xpm-Datei, also der Pfad/Name dahin. Dann ein optionaler Tooltiptext. Auch mehr zu Debugzwecken.

blogchart

Zusätzlich kann man noch definieren, was bei Klick auf die Grafik passieren soll und was bei Click auf den Text (<click>, <txtclick>) und eine Progressbar kann es geben, mehr dazu beim Genmon-Link unten. Ich könnte noch die aktuelle Zahl vom Blogcounter abholen, für zwischen den vollen Stunden bei click hier, und bei click da die Grafik mit convert größer skalieren und mit display anzeigen.

Update 1: Eine vergrößerte Ansicht habe ich jetzt realisiert, und zwar mit ohne convert, das macht display  (auch im Paket ImageMagick, falls ich das noch nicht geschrieben habe) alleine, durch die Codezeile:

echo "<click>display -resize 480x320 $img.xpm</click>"

Das war ja einfach.

Und ein Hinweis noch: Zum Synchronisieren des Plugins mit der Abfrage der Werte durch cron, bei mir immer zur vollen Stunde, kann man in der Kommandozeile ein at-Kommando absetzen (at, wie das englische at in at 2pm oder at teatime), gibt man, z.B. für die 17:00 Uhr-Abfrage, das Kommando:

at 17:02
xfce4-panel --plugin-event=genmon-X:refresh:bool:true
(Ctrl-D)

ein. Statt X müsst Ihr einen Wert eingeben; wo der herkommt steht auf der genmon-Seite die unten verlinkt ist.

(end of update)

Aber irgendwo ist auch noch der Wurm drinnen. Der Maximalwert stimmt, aber das Log stimmt nicht mit den Werten überein, die aber unverdächtig wirken. Das werde ich noch suchen, wenn es nicht vorher ein Leser findet und im Kommentar erklärt. Sonst Updates hier, eher kein neuer Beitrag.  Schreibt einen Kommentar, wenn Ihr drauf wartet. 

Update 2: Dem column-Programm muss man den Schalter -x übergeben, sonst formatiert es die Zahlen 1 2 3 4 5, jeweils in einer Zeile übergeben, so:

1 4
2 5
3

statt so:

1 2
3 4
5

(end of update)

Und noch 2 Worte zu bekannten Schwächen: Wenn man den Rechner ausschaltet, dann legt er keine Messung an. Beim Anschalten haben sich dann vielleicht viele Visits angesammelt, aber auch über viele Stunden verteilt. Ich habe beschlossen die Zeit, obwohl sie mitprotokolliert wird, nicht zu berücksichtigen. Man könnte damit dann zwar einen breiten Block anlegen, und die Abrufe darauf verteilen, also nach 15 Stunden und 150 Aufrufen würde man einfach das Mittel nehmen, 10 pro Stunde. Das würde das Programm aber sehr aufblähen und kompliziert machen. Das Programm zeigt also in Wahrheit die letzten 48 Messpunkte an, nicht 48 Stunden.

Generell habe ich mir wenig Gedanken gemacht, was alles schief gehen kann, und wie man dann die Situation am besten rettet. Da das Programm noch ganz frisch ist, sollte sich das im Laufe der Zeit von selbst ergeben.

Und bedanken muss ich mich bei den Entwicklern von GenMon. Das ist ja ein superflexibles Tool und einfach zu verwenden. Die Doku könnte noch ausführlicher sein, aber der erste Eindruck ist Klasse!

Hilfreiche Links:

Nachtrag:

Jetzt, wo ich meine eigene Lösung fertig habe, finde ich den neuen Ort, an dem WordPress die Ministatistik versteckt hat!

Und zwar wenn man den Blog in der Leseansicht offen hat, nicht im Bearbeitenmodus ist, und dann links oben „Meine Webseite“ klickt, dann klappt das Seitenmenü auf, und oben steht „Statistik“, daneben ein Balkendiagramm. Das ist nicht nur eine Erinnerungsgrafik für die, die vergessen haben, wie eine Statistik aussieht, sondern das sind die aktuellen Werte d. letzten 48 Stunden. Um das zu erkennen muss man freilich die aktuellen Werte kennen – gut, das war früher auch so. Auch dass es als Schaltfläche diente, um zur Statistikseite zu kommen. Ein Maximalwert zur Orientierung fehlt jetzt, aber wenn man die Zahl des letzten Tages kennt, kann man es wohl ungefähr abschätzen. Meine Lösung hat den Vorteil die Werte anzubieten, und immer sichtbar zu sein, aber den Nachteil Platz im Menü zu fressen. Ein anderer Vorteil für mich: Ich weiß jetzt wie es geht, wenn ich nochmal etwas derartiges brauche.

wp-statistik

Wie rechts nochmal zu sehen ist, mit anderer Proportion, sind das die gleichen Daten. Das hätte einem aber auch wer sagen können!

Und hier noch der Code als kompletter Block, ohne Gewähr:

#!/bin/bash
#
# (C) GPLv3, user unknown
#
# Erweiterung wird unten wechselnd angehängt (xpm/png) 
img=/home/stefan/.blogchart
# Bei mehr oder weniger als 48 Stunden hier anpassen (aber auch in der Funktion asciiart):
views=($(tail -n 48 ~/.bloglog | awk '{print $2}' | column -x))
# Debug:
# views=(5 4 10 8 6 6 5 4 4 3 5 0)
#
max () {
 maximum=0
 for view 
 do
   test $view -gt $maximum && maximum=$view
 done
 echo $maximum 
}

m=$(max ${views[@]})
# Avoid Div/0:
test $m -eq 0 && m=1

auf32 () {
 m=$1
 shift
 # echo Parameter: $#
 # Bei anderer Imagehöhe als 32 hier anpassen: 
 for hour
 do
   echo -n $((hour*32/m))" "
 done
 echo 
}

normalized=$(auf32 $m ${views[*]})

asciiart () {
 echo -e '/* XPM */'
 echo -e 'static char *XPM_example[] = {'
 # Erste Zahl ist Breite, zweite ist Höhe, also 48 32 für 2 Tage bei 32 Pixeln, sonst hier anpassen
 echo -e '"48 32 2 2 XPMEXT",'
 echo -e '"  m #ffffff",'
 echo -e '"* m #000000",'
 # Und hier Bildhöhe anpassen, Pixelzahl
 for row in {32..1}
 do
   echo -n '"'
   for traffic in ${normalized[@]}
   do
     test $traffic -ge $row && echo -ne "* " || echo -ne "  " 
   done
   echo '",'
 done
 echo '"XPMEXT author demystifikation.worpress.com GPLv3",'
 echo '"XPMENDEXT"'
 echo '};'
}

# echo ${views[@]}
# echo $m
# echo ${normalized[*]}

asciiart > $img.xpm
# convert $img.xpm $img.png 
# n=${#views[*]}
# echo "<txt>Max: $m Last: ${views[n-1]}</txt>"
# übler hack, hier auf row aus der Schleife der Funktion zuzugreifen. 
echo "<txt>Max: $m Last: $row</txt>"
# echo "<img>$img.png</img>"
echo "<img>$img.xpm</img>"
echo "<tool>views: ${views[@]} normalized: ${normalized[@]} </tool>"
echo "<click>display -resize 480x320 $img.xpm</click>"

10. Januar 2017

Nightly-Versionen von Firefox haben bereits seit Version 44 einen JSON-Betrachter standardmäßig aktiviert, um JSON-Inhalte strukturiert darzustellen. Ab Firefox 53 gilt dies auch für die finale Version.

In der Nightly-Version von Firefox ist bereits seit längerer Zeit, genauer seit Version 44, ein Feature implementiert und standardmäßig aktiviert, welches überaus praktisch für alle ist, welche JSON-Daten im Browser betrachten wollen. Statt die Ausgabe – wie sie ist – als reinen Text darzustellen, werden die Daten in einer Baumstruktur dargestellt, welche Element für Element aufgeklappt oder per Suchfeld durchsucht werden kann. Mit einem Klick kann in einem zweiten Tab in die Textansicht gewechselt werden. Dort gibt es auch eine Schaltfläche, um die Textausgabe, welche möglicherweise minimiert an den Nutzer gesendet wird, formatiert darzustellen. Ein dritter Tab stellt die HTTP-Header der Anfrage dar.

In der Zwischenzeit gab es einige Bugfixes und Detail-Verbesserungen. Ab Firefox 53 steht der JSON-Betrachter auch in finalen Firefox-Versionen standardmäßig zur Verfügung. Wer nicht warten will, kann diesen bereits jetzt über about:config aktivieren, indem der Schalter devtools.jsonview.enabled per Doppelklick auf true geschaltet wird.

JSON-Betrachter Firefox 53

Der Beitrag Firefox 53: JSON-Betrachter erhält Einzug in finale Version erschien zuerst auf soeren-hentzschel.at.

9. Januar 2017

Firefox lädt seit Version 38 Adobe Primetime als Content Decryption Module für die Wiedergabe DRM-geschützter Inhalte im Web herunter. In Firefox 52 entfernt Mozilla die Unterstützung für Adobe Primetime.

Für die Nutzung von Streaming-Plattformen wie Netflix und Amazon Video waren früher NPAPI-Plugins wie Microsoft Silverlight notwendig. NPAPI-Plugins sind allerdings schlecht für die Stabilität sowie Sicherheit des Browsers. Außerdem müssen diese vom Nutzer erst von Hand installiert werden. Vor allem aber: ab Firefox 52 unterstützt Firefox keine NPAPI-Plugins (außer den Adobe Flash Player) mehr.

Auch in der HTML5-Welt gibt es einen entsprechenden Standard, welcher die Wiedergabe DRM-geschützter Videos ermöglicht. Dieser nennt sich Encrypted Media Extensions (EME) und erfordert zur Dekodierung der Videos ein sogenanntes Content Decryption Module (CDM). Seit Firefox 38 lädt Firefox automatisch das CDM Adobe Primetime herunter. Seit Firefox 47 unterstützt der Mozilla-Browser zusätzlich das CDM Google Widevine auf Windows und Apple macOS, seit Firefox 49 auch auf Linux.

Bereits vor vier Monaten ist eine Änderung im Entwicklungszweig von Firefox 52 gelandet, welche dafür sorgte, dass Adobe Primetime nicht mehr automatisch heruntergeladen wird, sondern nur noch, wenn eine Seite das Primetime-CDM anfordert. Nun wurden entsprechende Tickets in Mozillas Bugtracking-System Bugzilla angelegt, welche die komplette Entfernung der Unterstützung aus Firefox 52 zum Thema haben.

Gründe lassen sich in diesen Tickets zwar keine erfahren, es ist aber anzunehmen, dass alle wichtigen Streaming-Portale sowieso wegen Google Chrome schon Widevine unterstützen, welches von Firefox ebenfalls unterstützt wird, so dass die zusätzliche Primetime-Unterstützung weder für Content-Anbieter noch für Mozilla zu diesem Zeitpunkt noch einen realen Vorteil bietet. Auch wurde Primetime von Firefox ausschließlich auf Windows unterstützt und nie auf Apple macOS, Linux oder Android. Widevine wird auf allen Desktop-Plattformen unterstützt, die erste Unterstützung für Widevine in Firefox für Android wird in den nächsten Tagen folgen.

Der Beitrag Firefox 52: Mozilla entfernt Unterstützung für Adobe Primetime erschien zuerst auf soeren-hentzschel.at.

8. Januar 2017

 – WordPress Ministatistik, DIY – 

wp-mini-statistik

Vor 2-3 Tagen hat WordPress die Ministatistik, wie ich sie in etwa oben nachgemalt habe – einen Screenshot habe ich nicht – aus der Ansicht geworfen. Wer selbst keinen Blog hat, kennt das gar nicht – auch ich bekomme die nur auf meinem eigenen Blog angezeigt, nicht auf dem anderer Leute. Das war ein Minibalkendiagramm, das stündlich aktualisiert wurde, wenn man die Seite neu lud, und die letzten 48 h umfasste, erinnerte, je nach Besucherzahlen, manchmal an das Ciscologo, welches seinerseits auch an eine Hängebrücke erinnert.

Wer einen Premiumaccount hat, kann da vielleicht auch eigene Widgets platzieren. In dem von mir verwendeten 0-8-15-Layout im Free-Tarif war das allerdings keine Option die man aus-, abwählen oder platzieren konnte.

Ich habe es gleich schmerzlich vermisst. Bei den Einstellungsoptionen fand ich keinen passenden Ersatz. Unter Design/Widgets/Blogstatistik fand ich lediglich einen Zähler aller Besucher, der, wenn man die Überschrift und die Einheiten löscht, so aussieht:

zaehler

Den sehen jetzt alle, was mich nicht stört, außer der Platzverbrauch, aber man sieht natürlich nicht mehr wie viele pro Stunde da waren und muss die Zahl vom letzten Mal im Kopf haben, um daraus den jüngsten Verkehr abzuleiten. Nichts, womit ich mich belasten will, aber eine Basis um selbst was zu bauen.

Wer sein eigenes WordPressblog selbst hostet hat andere Möglichkeiten, aber da ich mich nicht um die Internas des Blogs kümmern will, absichern, Backups und das alles, muss ich mir anders behelfen.

Eine Webseite kann man auch programmgesteuert abrufen. Gut – das machen ja auch Firefox, Chromium, Safari und Opera, aber diese stellen sie auch grafisch dar. Man kann einfach den HTML-Code runterladen, und in diesem sieht der Zähler so aus (Zeilenumbrüche und Einrückung im Original anders):

<div id=“secondary“ class=“widget-area“ role=“complementary“>
<aside id=“blog-stats-4″ class=“widget widget_blog-stats“>

<h3 class=“widget-title“></h3>
<ul>
<li>184,914 </li>
</ul>
</aside>

Anhand der Zahl ist der Block leicht zu finden. Den Quellcode kann man sich auch im Browser ansehen, aber man will ja nicht stündlich die eigene Webseite manuell speichern, also das erledigt man mit wget:

wget https://demystifikation.wordpress.com/

für andere Webseiten eben mit einer anderen Adresse. Weil ich den Widget-Titel im Design gelöscht habe ist das leer bei mir. Gespeichert wird das runtergeladene unter index.html. Allerdings brauche ich gar nicht die ganze Datei sondern will da nur einen Teil aausfiltern, deswegen sage ich mit -O wo der Output hinsoll, und mit einem verlorenen Minuszeichen, dass es auf die Konsole ausgegeben werden soll.

wget -q https://demystifikation.wordpress.com/ -O -

Das -q steht für quiet und unterdrückt irgendwelche Statusmeldungen von wget, wieviel Prozent der Arbeit schon geleistet ist, und solchen Firlefanz.

Den Output filtere ich dann mit grep auf die Zeile, die den HTML-Code ‚<aside id=“blog-stats-4‘ enthält, wobei -A1 bewirkt, dass eine zusätzliche Zeile ausgegeben wird, und als zweiten Filter nutze ich sed, dem ich sage, dass ich vom Listitem nur die Folge an Ziffern und Kommazeichen will, und das Kommazeichen soll dann auch weg.

sed -nr "s/.*<li>([0-9,]+).<\/li>.*/\1/;s/,//p"

Wer oft HTML, XHTML und XML-Code parsen muss wird vielleicht lieber zu einem Tool wie xmlstarlet greifen, welches den Vorteil hat, robust gegenüber Zeilenumbrüchen zu sein oder dem Vorkommen von Suchbegriffen in Kommentaren, aber das ist hier nicht zu erwarten. Sollte sich das HTML ändern, dann womöglich auch gleich soviel, dass einem das auchnicht weiterhilft.

Im ganzen sieht die Kette dann so aus:

counter=$(wget -q https://demystifikation.wordpress.com/ -O - | grep -A1 '<aside id="blog-stats-4' | sed -nr "s/.*<li>([0-9,]+).<\/li>.*/\1/;s/,//p")

Jetzt steht in der Variablen counter nur noch die Zahl 184914 und gespeichert wurde gar nichts.

lastcount=$(< ~/.blogcounter)
increase=$((counter-lastcount))
#
old=$(date -r ~/.blogcounter +%s)
now=$(date +%s) 
timespan=$((now-old))
#
heat=$(test $timespan -ge 0 && echo $((increase*3600/timespan)) || echo "--")

Dann sage ich

  • lastcount soll der Inhalt der Datei ~/.blogcounter sein, eine versteckte Datei, die das Programm später selbst schreiben wird, so dass es beim ersten Mal einen Fehler meldet, weil die Datei nicht vorhanden ist.
  • increase ist einfach die Differenz von altem Counter und Istzustand
  • old ist der Zeitstempel der Datei Blogcounter in Sekunden seit dem 1.1.1970
  • timespan ist die Zeitdifferenz zu now, also jetzt

 

heat=$(test $timespan -gt 0 && echo $((increase*3600/timespan)) || echo "--")

Heat sollen die mittleren Besucher pro Stunde sein seit der letzten Protokollierung, also wenn nach 30 Minuten 10 gezählt wurden 20 und wenn die Messung ausgefallen ist (Rechner aus) eventuell 5, wenn es nach 2 h 10 waren.

Getestet wird, ob die Zeitspanne > (greater than) 0 ist, dann sei heat der Wert der Berechnung, sonst „–“ (Division durch Null vermeiden!).

Jetzt wird es ein wenig kompliziert – wieso?

Nun, einmal will ich das Programm nutzen, um nur die stündlichen Differenzen zu protokollieren. Andererseits will ich jederzeit abfragen können ohne etwas zu protokollieren, etwa weil ein Beitrag von einem Alphablogger verlinkt wird, und plötzlich 1000e Besuche bekommt, so dass ich im 10-Minutentakt nachsehe, was das Volk macht.

test 1$# -gt 10 && test $1 = "-w" && echo $counter > ~/.blogcounter \
|| echo -e "Anzahl Anstieg /h Intervall (min) Messpunkt\n-------------------------------------------------------"

Das test 1$# ist ein furchtbarer Hack. $# ermittelt, wieviele Argumente einem Skript übergeben wurden. Aus unerfindlichen Gründen ist das aber nicht 0, wenn es keine Argumente sind, sondern nix, leer, nada, Nil, void, „“. Und dann scheitert der Test. Also klebe ich eine 1 davor und tesst nicht auf größer als 0, sondern auf größer als 10. Eigentlich müsste es da was eleganteres geben.

Waren es mehr als 0 Argumente prüfe ich, ob der Inhalt des 1. Arguments „-w“ war (w wie write, schreiben). Mit mehr oder anderen Argumenten rechne ich übrigens nicht.

War auch dies prima, dann, und nur dann schreibe ich die aktuelle Zahl in die versteckte Datei, die oben bereits erwähnt wurde. Ansonsten gebe ich eine Überschrift aus.

echo -e "$counter $increase $heat $((timespan/60)) $(date '+%H:%M %F')"

So oder so gebe ich dann die Werte aus, Zählerstand, Differenz, Seitenaufrufe /h seit letzter Messung und das Datum. So sieht ein isolierter Scriptaufruf (blogcounter.sh) aus:

Anzahl Anstieg /h Intervall (min) Messpunkt
-------------------------------------------------------
185203 0        0        22       20:22 2017-01-08

Etwas müde, gerade?

Seit 20 Uhr 0 Besucher, das sind 0 pro Stunde, Messintervall sind 22 Minuten und gemessen heute um 20:22 Uhr.

Außerdem hat Linux ja einen cron-Daemon, der chronologisch Dienste verrichten kann, wenn man im sagt wann und was. Den stellt man so ein:

daemonen

hilfreiche Linuxdaemonen, im Hintergrund wirkend

 0 * * * * /home/stefan/bin/blogcounter.sh -w >> /home/stefan/.bloglog

Das heißt jeweils zur Minute 0, jede Stunde (*), jeden Tag der Woche, des Monats usw. soll das Skript oben, das bei mir unter /home/stefan/bin/blogcounter.sh liegt ausgeführt werden, und die Ausgabe an die Datei /home/stefan/.bloglog angehängt werden (die erstellt wird, wenn sie noch nicht existiert). Das -w unterdrückt die Ausgabe der Überschrift, die man nicht für jede Zeile im Log haben will, und sorgt dafür, dass der Wert auch in die Datei ~/.blogcounter geschrieben wird.

Und dann gibt es noch ein kleines Script bloglog.sh, das so aussieht:

#!/bin/bash
#
# Blogtrafficlog der letzten 48 Stunden ausgeben
#
echo -e "Anzahl Anstieg Heat(/h) Intervall (min) Messpunkt"
echo "-------------------------------------------------------"
tail -n 48 ~/.bloglog | tac

Tail gibt nur die letzten 48 Zeilen der Datei ~/.bloglog aus, tac ist das Gegenteil von cat und gibt die Zeilen in umgekehrter Reihenfolge aus, also die jüngsten zuerst. Je nach Bildschirm und Fontgröße empfiehlt es siich, die Zahl an die eigenen Bedürfnisse anzupassen.

Die Ausgabe von bloglog.sh sieht beispielsweise so aus:

Anzahl Anstieg Heat(/h) Intervall (min) Messpunkt
-------------------------------------------------------
185205  1  1 60 22:00 2017-01-08
185204  1  1 60 21:00 2017-01-08
185203 22 21 60 20:00 2017-01-08
185181  0  0 59 19:00 2017-01-08
185181  4  4 60 18:00 2017-01-08
185177 10 10 60 17:00 2017-01-08
185167  3  2 60 16:00 2017-01-08
185164  7  7 59 15:00 2017-01-08
185157  4  4 60 14:00 2017-01-08
185153  3  3 60 13:00 2017-01-08
185150 185150 187177 59 12:00 2017-01-08
 -185118 -183134 60 11:00 2017-01-08
185118 16 16 60 10:00 2017-01-08
185102  5  4 60 09:00 2017-01-08
185097  0  0 59 08:00 2017-01-08
185097  0  0 60 07:00 2017-01-08
...

Das genaue Layout kann mit WordPressmitteln nicht ohne übermäßigen Aufwand getreu wiedergegeben werden – ich denke so geht es.

Die zwei Zeilen, die hervortreten deuten darauf hin, dass der Counter um 11:00 nicht lesbar war, auf Null gesetzt wurde, so dass die Zahl einbrach um dann hochzuschnellen – ein Grund dafür ist mir nicht erkenntlich, aber es zeigt, dass das Skript insofern robust ist, als es 2 Stunden später wieder brav seinen Job tut.

Pro Stunde fallen ca. 25 Bytes Daten an, das macht 600 am Tag, rd. 220.000 im Jahr und in 100 Jahren 22 MB – dürfte also, selbst wenn es vergessen wird und ständig, über viele Systemaktualisierungen weiterläuft, nie Probleme verursachen.

Hier nochmal das ganze  blogcounter.sh-Skript am Stück:

#!/bin/bash 
#
# Blogcounter ermitteln
# Zahl erfassen
# Differenz zur letzten Messung berechnen
# Differenz ausgeben
# Zahl speichern
# Zeit der letzten Messung erfassen
# Anstieg ermitteln
# Hits pro Stunde ermitteln
#
counter=$(wget -q https://demystifikation.wordpress.com/ -O - | grep -A1 '<aside id="blog-stats-4' | sed -nr "s/.*<li>([0-9,]+).<\/li>.*/\1/;s/,//p")
lastcount=$(< ~/.blogcounter)
increase=$((counter-lastcount))
#
old=$(date -r ~/.blogcounter +%s)
now=$(date +%s) 
timespan=$((now-old))
#
heat=$(test $timespan -gt 0 && echo $((increase*3600/timespan)) || echo "--")
# only write to counter file if param -w was given
# allows for hourly logged values, triggered by cron (with -w) and
# intermediate views without logging 
test 1$# -gt 10 && test $1 = "-w" && echo $counter > ~/.blogcounter || echo -e "Anzahl Anstieg /h Intervall (min) Messpunkt\n-------------------------------------------------------"
#
# Ergebnisse loggen. Das ganze sollte per cron stündlich laufen. Mit e. Script
# die letzten 24 oder 48 Messungen anchauen.
#
# Crontabzeile: 
# 0 * * * * /home/stefan/bin/blogcounter.sh -w >> /home/stefan/.bloglog
#
echo -e "$counter $increase $heat $((timespan/60)) $(date '+%H:%M %F')"

Weiterführende Hilfe bekommt man zu den einzelnen Befehlen mit

  • man wget
  • man sed
  • man tail
  • man date
  • man bash
  • help test
  • man tac
  • man cron
  • man crontab

und zu allen Befehlen, außer test, (was ein Kommando der Bash ist) auch mit PROGRAMM –help.

 – WordPress Ministatistik, DIY – 

wp-mini-statistik

Vor 2-3 Tagen hat WordPress die Ministatistik, wie ich sie in etwa oben nachgemalt habe – einen Screenshot habe ich nicht – aus der Ansicht geworfen. Wer selbst keinen Blog hat, kennt das gar nicht – auch ich bekomme die nur auf meinem eigenen Blog angezeigt, nicht auf dem anderer Leute. Das war ein Minibalkendiagramm, das stündlich aktualisiert wurde, wenn man die Seite neu lud, und die letzten 48 h umfasste, erinnerte, je nach Besucherzahlen, manchmal an das Ciscologo, welches seinerseits auch an eine Hängebrücke erinnert.

Wer einen Premiumaccount hat, kann da vielleicht auch eigene Widgets platzieren. In dem von mir verwendeten 0-8-15-Layout im Free-Tarif war das allerdings keine Option die man aus-, abwählen oder platzieren konnte.

Ich habe es gleich schmerzlich vermisst. Bei den Einstellungsoptionen fand ich keinen passenden Ersatz. Unter Design/Widgets/Blogstatistik fand ich lediglich einen Zähler aller Besucher, der, wenn man die Überschrift und die Einheiten löscht, so aussieht:

zaehler

Den sehen jetzt alle, was mich nicht stört, außer der Platzverbrauch, aber man sieht natürlich nicht mehr wie viele pro Stunde da waren und muss die Zahl vom letzten Mal im Kopf haben, um daraus den jüngsten Verkehr abzuleiten. Nichts, womit ich mich belasten will, aber eine Basis um selbst was zu bauen.

Wer sein eigenes WordPressblog selbst hostet hat andere Möglichkeiten, aber da ich mich nicht um die Internas des Blogs kümmern will, absichern, Backups und das alles, muss ich mir anders behelfen.

Eine Webseite kann man auch programmgesteuert abrufen. Gut – das machen ja auch Firefox, Chromium, Safari und Opera, aber diese stellen sie auch grafisch dar. Man kann einfach den HTML-Code runterladen, und in diesem sieht der Zähler so aus (Zeilenumbrüche und Einrückung im Original anders):

<div id=“secondary“ class=“widget-area“ role=“complementary“>
<aside id=“blog-stats-4″ class=“widget widget_blog-stats“>

<h3 class=“widget-title“></h3>
<ul>
<li>184,914 </li>
</ul>
</aside>

Anhand der Zahl ist der Block leicht zu finden. Den Quellcode kann man sich auch im Browser ansehen, aber man will ja nicht stündlich die eigene Webseite manuell speichern, also das erledigt man mit wget:

wget https://demystifikation.wordpress.com/

für andere Webseiten eben mit einer anderen Adresse. Weil ich den Widget-Titel im Design gelöscht habe ist das leer bei mir. Gespeichert wird das runtergeladene unter index.html. Allerdings brauche ich gar nicht die ganze Datei sondern will da nur einen Teil aausfiltern, deswegen sage ich mit -O wo der Output hinsoll, und mit einem verlorenen Minuszeichen, dass es auf die Konsole ausgegeben werden soll.

wget -q https://demystifikation.wordpress.com/ -O -

Das -q steht für quiet und unterdrückt irgendwelche Statusmeldungen von wget, wieviel Prozent der Arbeit schon geleistet ist, und solchen Firlefanz.

Den Output filtere ich dann mit grep auf die Zeile, die den HTML-Code ‚<aside id=“blog-stats-4‘ enthält, wobei -A1 bewirkt, dass eine zusätzliche Zeile ausgegeben wird, und als zweiten Filter nutze ich sed, dem ich sage, dass ich vom Listitem nur die Folge an Ziffern und Kommazeichen will, und das Kommazeichen soll dann auch weg.

sed -nr "s/.*<li>([0-9,]+).<\/li>.*/\1/;s/,//p"

Wer oft HTML, XHTML und XML-Code parsen muss wird vielleicht lieber zu einem Tool wie xmlstarlet greifen, welches den Vorteil hat, robust gegenüber Zeilenumbrüchen zu sein oder dem Vorkommen von Suchbegriffen in Kommentaren, aber das ist hier nicht zu erwarten. Sollte sich das HTML ändern, dann womöglich auch gleich soviel, dass einem das auchnicht weiterhilft.

Im ganzen sieht die Kette dann so aus:

counter=$(wget -q https://demystifikation.wordpress.com/ -O - | grep -A1 '<aside id="blog-stats-4' | sed -nr "s/.*<li>([0-9,]+).<\/li>.*/\1/;s/,//p")

Jetzt steht in der Variablen counter nur noch die Zahl 184914 und gespeichert wurde gar nichts.

lastcount=$(< ~/.blogcounter)
increase=$((counter-lastcount))
#
old=$(date -r ~/.blogcounter +%s)
now=$(date +%s) 
timespan=$((now-old))
#
heat=$(test $timespan -ge 0 && echo $((increase*3600/timespan)) || echo "--")

Dann sage ich

  • lastcount soll der Inhalt der Datei ~/.blogcounter sein, eine versteckte Datei, die das Programm später selbst schreiben wird, so dass es beim ersten Mal einen Fehler meldet, weil die Datei nicht vorhanden ist.
  • increase ist einfach die Differenz von altem Counter und Istzustand
  • old ist der Zeitstempel der Datei Blogcounter in Sekunden seit dem 1.1.1970
  • timespan ist die Zeitdifferenz zu now, also jetzt

 

heat=$(test $timespan -gt 0 && echo $((increase*3600/timespan)) || echo "--")

Heat sollen die mittleren Besucher pro Stunde sein seit der letzten Protokollierung, also wenn nach 30 Minuten 10 gezählt wurden 20 und wenn die Messung ausgefallen ist (Rechner aus) eventuell 5, wenn es nach 2 h 10 waren.

Getestet wird, ob die Zeitspanne > (greater than) 0 ist, dann sei heat der Wert der Berechnung, sonst „–“ (Division durch Null vermeiden!).

Jetzt wird es ein wenig kompliziert – wieso?

Nun, einmal will ich das Programm nutzen, um nur die stündlichen Differenzen zu protokollieren. Andererseits will ich jederzeit abfragen können ohne etwas zu protokollieren, etwa weil ein Beitrag von einem Alphablogger verlinkt wird, und plötzlich 1000e Besuche bekommt, so dass ich im 10-Minutentakt nachsehe, was das Volk macht.

test 1$# -gt 10 && test $1 = "-w" && echo $counter > ~/.blogcounter \
|| echo -e "Anzahl Anstieg /h Intervall (min) Messpunkt\n-------------------------------------------------------"

Das test 1$# ist ein furchtbarer Hack. $# ermittelt, wieviele Argumente einem Skript übergeben wurden. Aus unerfindlichen Gründen ist das aber nicht 0, wenn es keine Argumente sind, sondern nix, leer, nada, Nil, void, „“. Und dann scheitert der Test. Also klebe ich eine 1 davor und tesst nicht auf größer als 0, sondern auf größer als 10. Eigentlich müsste es da was eleganteres geben.

Waren es mehr als 0 Argumente prüfe ich, ob der Inhalt des 1. Arguments „-w“ war (w wie write, schreiben). Mit mehr oder anderen Argumenten rechne ich übrigens nicht.

War auch dies prima, dann, und nur dann schreibe ich die aktuelle Zahl in die versteckte Datei, die oben bereits erwähnt wurde. Ansonsten gebe ich eine Überschrift aus.

echo -e "$counter $increase $heat $((timespan/60)) $(date '+%H:%M %F')"

So oder so gebe ich dann die Werte aus, Zählerstand, Differenz, Seitenaufrufe /h seit letzter Messung und das Datum. So sieht ein isolierter Scriptaufruf (blogcounter.sh) aus:

Anzahl Anstieg /h Intervall (min) Messpunkt
-------------------------------------------------------
185203 0        0        22       20:22 2017-01-08

Etwas müde, gerade?

Seit 20 Uhr 0 Besucher, das sind 0 pro Stunde, Messintervall sind 22 Minuten und gemessen heute um 20:22 Uhr.

Außerdem hat Linux ja einen cron-Daemon, der chronologisch Dienste verrichten kann, wenn man im sagt wann und was. Den stellt man so ein:

daemonen

hilfreiche Linuxdaemonen, im Hintergrund wirkend

 0 * * * * /home/stefan/bin/blogcounter.sh -w >> /home/stefan/.bloglog

Das heißt jeweils zur Minute 0, jede Stunde (*), jeden Tag der Woche, des Monats usw. soll das Skript oben, das bei mir unter /home/stefan/bin/blogcounter.sh liegt ausgeführt werden, und die Ausgabe an die Datei /home/stefan/.bloglog angehängt werden (die erstellt wird, wenn sie noch nicht existiert). Das -w unterdrückt die Ausgabe der Überschrift, die man nicht für jede Zeile im Log haben will, und sorgt dafür, dass der Wert auch in die Datei ~/.blogcounter geschrieben wird.

Und dann gibt es noch ein kleines Script bloglog.sh, das so aussieht:

#!/bin/bash
#
# Blogtrafficlog der letzten 48 Stunden ausgeben
#
echo -e "Anzahl Anstieg Heat(/h) Intervall (min) Messpunkt"
echo "-------------------------------------------------------"
tail -n 48 ~/.bloglog | tac

Tail gibt nur die letzten 48 Zeilen der Datei ~/.bloglog aus, tac ist das Gegenteil von cat und gibt die Zeilen in umgekehrter Reihenfolge aus, also die jüngsten zuerst. Je nach Bildschirm und Fontgröße empfiehlt es siich, die Zahl an die eigenen Bedürfnisse anzupassen.

Die Ausgabe von bloglog.sh sieht beispielsweise so aus:

Anzahl Anstieg Heat(/h) Intervall (min) Messpunkt
-------------------------------------------------------
185205  1  1 60 22:00 2017-01-08
185204  1  1 60 21:00 2017-01-08
185203 22 21 60 20:00 2017-01-08
185181  0  0 59 19:00 2017-01-08
185181  4  4 60 18:00 2017-01-08
185177 10 10 60 17:00 2017-01-08
185167  3  2 60 16:00 2017-01-08
185164  7  7 59 15:00 2017-01-08
185157  4  4 60 14:00 2017-01-08
185153  3  3 60 13:00 2017-01-08
185150 185150 187177 59 12:00 2017-01-08
 -185118 -183134 60 11:00 2017-01-08
185118 16 16 60 10:00 2017-01-08
185102  5  4 60 09:00 2017-01-08
185097  0  0 59 08:00 2017-01-08
185097  0  0 60 07:00 2017-01-08
...

Das genaue Layout kann mit WordPressmitteln nicht ohne übermäßigen Aufwand getreu wiedergegeben werden – ich denke so geht es.

Die zwei Zeilen, die hervortreten deuten darauf hin, dass der Counter um 11:00 nicht lesbar war, auf Null gesetzt wurde, so dass die Zahl einbrach um dann hochzuschnellen – ein Grund dafür ist mir nicht erkenntlich, aber es zeigt, dass das Skript insofern robust ist, als es 2 Stunden später wieder brav seinen Job tut.

Pro Stunde fallen ca. 25 Bytes Daten an, das macht 600 am Tag, rd. 220.000 im Jahr und in 100 Jahren 22 MB – dürfte also, selbst wenn es vergessen wird und ständig, über viele Systemaktualisierungen weiterläuft, nie Probleme verursachen.

Hier nochmal das ganze  blogcounter.sh-Skript am Stück:

#!/bin/bash 
#
# Blogcounter ermitteln
# Zahl erfassen
# Differenz zur letzten Messung berechnen
# Differenz ausgeben
# Zahl speichern
# Zeit der letzten Messung erfassen
# Anstieg ermitteln
# Hits pro Stunde ermitteln
#
counter=$(wget -q https://demystifikation.wordpress.com/ -O - | grep -A1 '<aside id="blog-stats-4' | sed -nr "s/.*<li>([0-9,]+).<\/li>.*/\1/;s/,//p")
lastcount=$(< ~/.blogcounter)
increase=$((counter-lastcount))
#
old=$(date -r ~/.blogcounter +%s)
now=$(date +%s) 
timespan=$((now-old))
#
heat=$(test $timespan -gt 0 && echo $((increase*3600/timespan)) || echo "--")
# only write to counter file if param -w was given
# allows for hourly logged values, triggered by cron (with -w) and
# intermediate views without logging 
test 1$# -gt 10 && test $1 = "-w" && echo $counter > ~/.blogcounter || echo -e "Anzahl Anstieg /h Intervall (min) Messpunkt\n-------------------------------------------------------"
#
# Ergebnisse loggen. Das ganze sollte per cron stündlich laufen. Mit e. Script
# die letzten 24 oder 48 Messungen anchauen.
#
# Crontabzeile: 
# 0 * * * * /home/stefan/bin/blogcounter.sh -w >> /home/stefan/.bloglog
#
echo -e "$counter $increase $heat $((timespan/60)) $(date '+%H:%M %F')"

Weiterführende Hilfe bekommt man zu den einzelnen Befehlen mit

  • man wget
  • man sed
  • man tail
  • man date
  • man bash
  • help test
  • man tac
  • man cron
  • man crontab

und zu allen Befehlen, außer test, (was ein Kommando der Bash ist) auch mit PROGRAMM –help.

Wer das hier liest, hat es wahrscheinlich schon bemerkt: Mein Blog sieht anders aus als vorher und manche Inhalte fehlen. Ich habe mir in den vergangenen Wochen ein neues Konzept überlegt, wie ich die Inhalte auf meinem Blog präsentieren will. Auch ein Refresh des Designs war schon länger geplant. Unter der Haube werkelt jetzt nicht mehr Wordpress, sondern nur noch ein einfacher Nginx-Webserver, der nichts anderes mehr tut, als statische HTML-Seiten auszuliefern. … aber eins nach dem anderen:

Überarbeitetes Blog-Design

Das bisherige Design wurde in großen Teilen beibehalten. Ich habe bisher viel positive Rückmeldung zu meinem selbst kreierten Design erhalten, sodass ich mich dazu entschieden habe, nur einen Feinschliff daran vorzunehmen, aber das bekannte Farbschema und das Layout beizubehalten. Ich bin ein Freund von einfachem, minimalistischem Design ohne Schnörkel. Weil immer “noch weniger” geht, habe ich einfach mal überprüft, wie ich die Seite noch leichtgewichtiger gestalten kann.

  • Der Header wurde um ein ganzes Menü und ein paar Menüpunkte erleichtert und tiefschwarz gefärbt. Damit besteht er jetzt nur noch aus dem Titel-Schriftzug und dem kleinen Hauptmenü.
  • Im Content-Bereich habe ich das Schriftbild komplett überarbeitet. Nur die Schriftart wurde beibehalten. Im Blogsatzstil wirkt der Text jetzt weniger zerpflückt und geschlossener. Die Schriftgröße habe ich nach oben korrigiert, sodass der Text auch auf kleineren Bildschirmen (z.B. 13” Ultrabook etc.) noch gut gelesen werden kann.

Unter der Haube: Verzicht auf Wordpress

Der Trend scheint ja derzeit wieder zurück zu statischen Seiten zu gehen - zumindest in einigen speziellen Bereichen des Webs. Nachdem das Thema auch an mir nicht vorbeigegangen ist, und ich z.B. trashserver.net und andere Microsites schon länger erfolgreich mit Hugo generieren lasse, habe ich abgewogen, ob ich nicht auch mein Blog umstellen sollte. Es gibt da nämlich ein paar Dinge, die mir an Wordpress nicht so gefallen:

  • Wordpress wird immer langsamer: Mit steigender Anzahl von Beiträgen, Kommentaren und Plugins wird der Dino des Blog-Universums immer “gemütlicher”. Was ihr am Frontend dank Memcache vermutlich nicht so sehr bemerkt habt, hat mich am Backend von Wordpress durchaus gestört. Sehr langsam war der Seitenwechsel beim Navigieren im Backend zwar nicht, aber doch deutlich träger, als früher. Ein paar Sekunden Wartezeit waren meistens schon nötig.

  • Security: Ich weiß - zum Thema “Wordpress Security” gibt es die verschiedensten Meinungen: Die einen können Wordpress nicht ausstehen, weil es ständig Sicherheitsprobleme gäbe - die anderen schwören darauf und sehen überhaupt keine Probleme, solange man fleißig Updates einspielt. Die ganze Wahrheit ist vermutlich tatsächlich, dass der Wordpress Core ziemlich sicher ist. Sehr viele (auch große Websites) setzen auf Wordpress als CMS. Wäre die Wordpress-Sicherheit tatsächlich so katastrophal, wie manche behaupten, würde des Web wohl anders aussehen. Allerdings kann man nicht leugnen, dass Wordpress auf der anderen Seite auch zu einem unsicheren Web beigetragen hat: Zu viele Seitenbetreiber kümmern sich nicht um Updates. Wordpress hat zwar mittlerweile eine Auto-Update-Funktion - die gibt es aber nicht für Plugins. Und Plugins sind die Hauptquelle von Sicherheitsproblemen. Mit steigender Anzahl von integrierten Plugins muss man sich auch um immer häufigere Updates kümmern, um nicht verwundbar zu bleiben. Das kostet zwar kaum Zeit, ist aber trotzdem lästig. Eigentlich will ich ja nur publizieren…

  • Theming und Anpassung: Wordpress Themes und -Plugins für persönliche Anpassungen werden in PHP programmiert. Mir gefällt weder PHP besonders gut, noch will ich mich groß damit beschäftigen, wie ich unter Wordpress dies oder jenes realisieren kann. Die Templating-Engine von Hugo gefällt mir deutlich besser.

In Zukunft werde ich diese Blog-Seiten also mit Hugo generieren und dann auf den Webserver hochladen. Hugo ist ein in Go entwickelter Static Site Generator, der sich zurecht immer größerer Beliebtheit erfreut. Hugo vor allem hier punkten:

  • Einfachheit: Hugo wird als einzelnes Executable heruntergeladen und kann direkt gestartet und genutzt werden. Auf dem Endgerät müssen keine speziellen Libraries oder Scriptsprachen-umgebungen vorhanden sein. Wer von Ruby, NodeJS und Python geplagt ist, weiß das zu schätzen ;-) Herunterladen - starten - funktioniert.

  • Geschwindigkeit: Ich habe es nicht selbst getestet, aber angeblich lassen sich mit Hugo innerhalb weniger Sekunden auch mehrere zehntausend Seiten generieren.

  • Go Template Engine: Für das Templating wird die integrierte HTML-Template-Engine von Go genutzt. Dank ihrer Einfachheit konnte ich auch als Einsteiger innerhalb kürzester Zeit ein funktionsfähiges Template entwickeln.

  • Live Preview: Das ließe sich vermutlich auch mit Wordpress realisieren, aber die Live-Preview Funktion von Hugo begeistert mich. Während an Theme und Inhalten geschrieben wird, kann man sich im Webbrowser sie Änderungen live anzeigen lassen. Vor allem während der Theme-Entwicklung ist das großartig!

Insgesamt macht Hugo einen sehr soliden Eindruck. Das Projekt wird vorbildlich betreut und ausreichend dokumentiert. Die Entwickler stellen zu Support-Zwecken sogar ein eigenes Forum bereit.

Durch die Nutzung von Hugo als Static Site Generator und dem daraus folgenden, neuen Workflow ergeben sich für mich folgende Vorteile:

  • Ich muss mich (so gut wie) nicht mehr um die Sicherheit meines Blogs kümmern: Was die Sicherheit angeht, muss ich nur noch sicherstellen, dass der Webserver korrekt konfiguriert und aktuell ist. CMS- und Plugin-Updates entfallen. Auch um Schlampereien im CMS-/Plugin-Code muss ich mir keine Gedanken mehr machen. Wenn eine kritische Sicherheitslücke in Wordpress weltweit Admins in Aufregung versetzt, kann ich gelassen bleiben.

  • Beiträge können komfortabel mit MarkDown verfasst werden: Für die Formatierung von Texten verwende ich gerne MarkDown. Das ermöglicht schnelles und bequemes Schreiben, ohne zu Formatierungszwecken ständig zur Maus greifen zu müssen (z.B. um die zu formatierenden Bereiche auszuwählen). Meine Beiträge kann ich von nun an in jedem einfachen Text-Editor verfassen. Aktuell nutze ich dafür den Code-Editor “Atom” (mit Markdown-Highlighting)

  • Der gesamte Blog-Inhalt kann via Git versioniert werden: Mein Blog ist nicht mehr mehr als ein Haufen Textdateien in einem Verzeichnis. Was bietet sich da mehr an, als das gesamte Blog einfach mit einem Versionskontrollsystem wie Git zu versionieren? So könnte ich ggf. alte Beiträge aus der Vergangenheit wieder zurückholen und hätte am Ende ein riesiges Archiv von allen jemals veröffentlichten Inhalten. Das gesamte Archiv könnte man z.B. auch interessierten Lesern auf GitHub öffentlich zum Download anbieten. Änderungen an Beiträgen wären jederzeit nachvollziehbar.

  • Nichts ist schneller als statische Seiten: Mein bisheriges Blog war dank Memcache schon ziemlich flott, aber mit statischen Seiten geht da noch mehr.

Hinter dem Umstieg steht allerdings noch ein ganz anderer Gedanke: “Back to the roots”. Das Internet war Anfangs nur statisch. Interaktionen mit einer Webpräsenz (abgesehen vom Seitenaufruf) waren nicht möglich. Wieso nicht dieses Format wiederentdecken und nutzen, wo es Sinn macht? Natürlich ist es gerade die Dynamik, die unser modernes Web so interessant macht. Der Benutzer kann über seinen Browser eigene Inhalte veröffentlichen und mit einer Webpräsenz interagieren. In meinem Fall reicht aber auch schon weniger aus, denn im Grunde will ich ja nur eins: Veröffentlichen.

Nachteile

Natürlich ergeben sich aus dem ganzen auch ein paar Nachteile. Sowohl für mich als Autor als auch euch als Leser.

Beitragsverwaltung

Eine Sammlung aus Textdateien und Verzeichnissen lässt sich nicht so schön durchsuchen und Filtern, wie das mit Daten in einer Datenbank möglich ist. Daraus ergibt sich möglicherweise ein etwas höherer Aufwand bei der Suche nach älteren Beiträgen oder dem allgemeinen “Housekeeping”. Mein Atom Editor stellt auf der anderen Seite aber auch mächtige Suchfunktionen bereit, sodass der Aufwand sich vermutlich doch in Grenzen hält.

Blog-Kommentare

Für euch ergibt sich derzeit noch ein anderer Nachteil: In der aktuellen Version meines Blogs sind weder alte Kommentare enthalten, noch neue vorgesehen. Es gibt keine Kommentarfunktion. Ich bin mir noch unsicher, ob eine Kommentarfunktion tatsächlich so essentiell für mein Blog ist. Feedback und Fragen kann ich immerhin auch als E-Mails entgegennehmen. Diese Konversationen wären dann aber nicht öffentlich einsehbar und die “Archiv-Funktion” des Kommentarbereichs würde wegfallen. Bereits gestellte Fragen würden dann vermutlich öfter gestellt werden. Der Leser kann ja nicht wissen, ob sich andere User schon zu einem Thema geäußert haben. So eine Kommentarfunktion kann manchmal sehr wertvoll sein, wie meine Mailserver-Beiträge beweisen. Dort wurden einige tolle Ideen eingebracht und Probleme gelöst.

Natürlich könnte ich einfach das nächstbeste JavaScript-basierte Kommentarsystem (wie z.B. Disqus) unter die Beiträge packen. Mehr als genug Blogger-Kollegen machen das so. Disqus sagt mir aber nicht besonders zu, genauso wie jede andere fremd gehostete Lösung. Wenn ich Kommentare hoste, dann soll das unter deutschem Datenschutz passieren, und unter meiner Kontrolle. Ich habe erfahren, dass man auch die freie Forensoftware “Discourse” nutzen kann, um eine Kommentarfunktion für statische Webpräsenzen zu realisieren. Das würde dann aber bedeuten, dass ich zusätzlich um die Sicherheit und Pflege einer weiteren Komponente auf meinem Server kümmern müsste. Auch nicht gut.

Beitragssuche

Wo ein Server keine Benutzerspezifischen Seiten ausliefert und eine zentrale Beitragsdatenbank hat, sind auch Suchanfragen nicht so einfach möglich. Es gibt zwar ein paar JavaScript-Lösungen, die versprechen, auch eine Suche für statische Seiten (direkt im Client-Browser) zu ermöglichen, aber das müsste ich erst noch testen. Eine andere Lösung wäre das einbinden einer fremden Suche, z.B. der DuckDuckGo Websuche. Derzeit denke ich noch über eine schöne Lösung nach.

Inhaltlich

Was die Inhalte angeht, soll der Fokus in Zukunft wieder auf längeren Meinungsartikeln und Anleitungen liegen - weniger auf Kurzmeldungen. Zuletzt waren eher kurze Beiträge in meinem Blog zu finden - auch, weil mir die Zeit gefehlt hat, mich ausführlicher mit komplexeren Themen auseinanderzusetzen. Ich versuche, Tempo aus meinen Veröffentlichungen zu nehmen und mich stattdessen auf wertvolle, langlebige Inhalte zu konzentrieren. Ganz nach dem Motto “Qualität statt Quantität”. Meine Seite sehe ich nun weniger als persönliches, typisches Blog für Statusupdates (denn für solche kurzlebigen Inhalte haben wir ja soziale Netzwerke), sondern mehr als eine Mischung aus Magazin und Wiki. Ein Werk, das Wissen und Meinung vermitteln soll.

Der Umzug

Die beliebtesten und meiner Meinung nach wertvollsten Beiträge aus meinem alten Blog habe ich manuell hierher übernommen und in Markdown-Textdateien verwandelt, sodass sie auch hier zur Verfügung stehen. In den meisten Fällen hat sich die URL geändert. Sobald die Suchmaschinen die neuen Seiten in ihren Index aufgenommen haben, sollten sie wieder einfach auffindbar sein. Alle anderen Beiträge habe ich nicht übernommen. Entweder, weil sie nicht wirklich relevant waren, weil sie veraltet waren, oder weil sie mir einfach nicht gefallen haben.

Die alte Blog-Version vom 05.01.2017 habe ich mithilfe des Wordpress-Plugins “Simply Static” als Archiv aus HTML-Dateien exportiert und auf legacy.thomas-leister.de hochgeladen. Dort bleiben euch alle vorherigen Inhalte zumindest für einige Zeit noch erhalten.

Eure Meinung?

Ich habe lange gezögert und war hin- und hergerissen, was meinen “Blog-Reset” angeht. Letztendlich habe ich mich doch dazu entschieden, einiges anders zu machen. Daraus ergeben sich verschiedene Vor- und Nachteile. Einige davon habe ich zuvor schon aufgeführt. Jetzt würde mich eure Meinung interessieren: Sind die Änderungen ein Schritt in die richtige Richtung, oder ein Irrweg? Wie gefällt euch mein neuer Blog? Ist eine Kommentarfunktion wirklich essentiell, oder kann auch darauf verzichtet werden?

Schreibt mir an info [ett] thomas-leister.de!

7. Januar 2017

Ich arbeite privat und Beruflich seit mehr als 2 Dekaden mit Unix, da gibt es halt kleine Tools, die einem in Fleisch und Blut übergegangen sind.

dd ist so ein Tool, klar, kennt jeder, der schon ein wenig mit Linux unterwegs ist. Häufig wird es benutzt, um Abbilder auf USB Sticks zu kopieren, blöd ist nur, dass man keinen Fortschritt sieht, man muss sich halt gedulden.

So sieht das ungefähr aus.

dd if=Superlinux.iso of=/dev/sdc bs=8M

Doch es lohnt sich alle paar Versionen mal wieder die Man Pages zu studieren, denn seit der Version 8.24 hat dd den Parameter status um progress erweitert.

Nun ist es bequem möglich, den Fortschritt zu beobachten, mit dem oflag=direct wird die Schreiboperation auch nicht gebuffert, d.h. Wenn dd sagt, es ist fertig, kann man den Stick entfemen und muss nicht erst auf das Ende der Schreiboperation warten.

 

 

dd if=Superlinux.iso of=/dev/sdc bs=8M status=progress oflag=direct 

Hinweis: Debian Jessie beinhaltet dd in Version 8.23, dort existiert progress noch nicht.

Noch ein Hinweis, mit etwas Mühe ist es auch in den älteren Versionen den Progress abzufragen, man kann von einem anderen Prozess aus den Fortschritt abzufragen

 

kill -USR1 <prozessnummer des dd>
PS: Ja, ich weiß, mit dd kann man noch viel mehr machen, zum Beispiel Code Conversion, ASCII to EBCDIC oder Byte Order tauschen usw. Zockertown ist keine Lehranstalt, sondern eine Gedankenstütze für den Autor, die zufällig im Web frei verfügbar ist wink

Meine Owncloud-Installation hat sich wirklich bewährt. Es ist für mich die Lösung, mit der ich meine Kontakte und Kalender abgleiche und mit der ich bestimmte Dateien immer in Reichweite habe. Allerdings war das Update immer eine Katastrophe. Nachdem fast das ganze Owncloud-Team abgesprungen ist, um Nextcloud zu forken, habe ich mir das mal angeschaut. Jetzt bin ich umgestiegen.

In der Praxis

Ich finde es großartig mit Nextcloud oder Owncloud zu arbeiten. Dateien einfach freigeben zu können ist ziemlich praktisch. Für meine SH:Z-Kolumnen habe ich der zuständigen Redakteurin einfach einen Link gegeben, unter der sie die fertig Kolumne immer finden kann.

Neulich sollte mir eine Gruppe von Leuten größere Dateien zuschicken. Bevor mir diese Dateien das Mail-Postfach vollmachen, habe ich denen ein Verzeichnis für Uploads freigegeben. Die Dateien werden dann automatisch auf meinen Rechner synchronisiert.

Über das „Federation“-System kann man Verzeichnisse zwischen Owncloud/Nextcloud-Instanzen teilen. Dieses System funktioniert zum Beispiel auch mit Pydio-Installationen. Auch das benutze ich in einem Fall und das funktioniert grandios – als wäre es ein Verzeichnis bei mir.

Migration zu Nextcloud

„Nextcloud ist ein vom ownCloud-Gründer Frank Karlitschek gegründeter Fork von ownCloud, der am 2. Juni 2016 bekannt gegeben wurde. Karlitschek verließ 5 Wochen zuvor das von ihm gegründete Unternehmen ownCloud aufgrund von Meinungsverschiedenheiten über den Kurs von ownCloud. Nextcloud ist noch recht neu, bietet aber einige Funktionen an, welche ownCloud nur in der Enterprise-Version anbietet.“ – Wikipedia

Nextcloud ist mit dem Code von Owncloud 9 gestartet, mittlerweile ist Nextcloud 11 erschienen. Um von OwnCloud 9.0.5 auf Nextcloud umzusteigen muss man auch erst einmal Nextcloud 9 installieren. Ich habe ohnehin schon länger das Datenverzeichnis aus dem OwnCloud-Verzeichnis heraus gelegt. Das hat die Updates extrem vereinfacht. Es gibt also:

/daten
/owncloud

Ich habe dazu ein Verzeichnis /nextcloud angelegt und die Owncloud-Config ins Nextcloud-Verzeichnis kopiert. Wenn ich dann meine Domain auf dieses Verzeichnis umschalte, begrüßt mich nach ein paar Sekunden der Nextcloud-Updater. Der läuft erfreulicherweise problemlos durch. Ich kann mich in Nextcloud einloggen und die Sync-Apps sowohl für Dateien als auch für CalDav/CardDav auf dem Smartphone und dem Rechner laufen einfach weiter – der Code bei Nextcloud 9 ist fast noch der gleiche wie bei Owncloud.

In der Administration kann man jetzt das nächste Update aufrufen und so auf Nextcloud 10 aktualisieren. Auch das läuft zum ersten Mal problemlos. Wie auch schon bei Owncloud, muss ich nach dem Systemupdate die Apps neu aktivieren. Die Apps sind auch noch ziemlich die gleichen, wie bei Owncloud. Ein nettes, neues Gimmick ist die Möglichkeit die Nextcloud-Installation optisch relativ einfach anzupassen. Das ging bisher nur in der Enterprise-Version von OwnCloud.

Insgesamt scheint Nextcloud aber problemloser zu laufen als Owncloud. Mit Nextcloud 11 ist auch noch einmal die Sicherheit überarbeitet worden und die Apps können direkt über einen App-Store installiert werden.

Von Owncloud auf Nextcloud umstellen

6. Januar 2017

Gegen Ende letzten Jahres gab es noch ein paar Änderungen an der Security Distributionen Front. Aber zunächst möchte ich ein neues Security OS vorstellen. 

DracOS 2.1 - Leak

Neu im Sicherheitsbunde ist ein indonesisches Security OS. 

DracOS ist ein Penetration OS, welches auf Linux from Scratch aufbaut. Der regelmäßige Leser erinnert sich vielleicht daran (Artikel).
Es verwendet die Kommandozeile in Verbindung mit den Dynamic Windows Manager. Das heißt ihr solltet fit auf der CLI sein, wenn ihr die Distribution verwendet oder es eben werden.

In der aktuellen Version 2 gibt es noch keinen Paketmanager, dieser soll aber folgen.
Wie bei anderen Distribution sind jede Menge Tools zur Informationsgewinnung, Sicherheitslückenfindung oder Malware Analyse vorinstalliert.

Details zu allen Programmen lassen sich hier finden. DracOS Codename "Leak" wurde bereits im Oktober 2016 veröffentlicht und wird stets weiter entwickelt.

 

Installation Dracos 2.1

Die Installation erfolgt über git und den Installer DRACER oder ganz normal via ISO Datei

sudo apt-get install squashfs-tools rsync
git clone https://github.com/Screetsec/super-dracos
cd super-dracos
sudo chmod +x DracosInstaller.sh
sudo ./DracosInstaller

[02]  CREATE PARTITION WITH FDISK
[03]  START INSTALL DRACOS

dracos-dracer

Ich habe eine Installation zu Testzwecken via ISO realisiert, diese ist einfach via VirtualBox oder VMware möglich.

Erste Schritte mit DracOS

Nach einer Installation via VirtualBox muss zunächst ein Login erfolgen.
Hierzu wird der Login "root" und das Passwort "toor" eingegeben.

Danach wird schlicht das Terminal angezeigt, für den Start der GUI muss "startx" eingegeben werden.

Auch nach dem Start der Oberfläche ist weiterhin die Tastatur das Hauptbewegungsmittel, da es sich bei DracOS wie schon erwähnt um eine CLI Steuerung handelt.

Wichtige Tastatur Shortcuts für die Bedienung sind

Menü öffnen windows + shift + d
Browser öffnen windows + shift + l
Screenshot printscreen
Terminal öffnen windows + shift + enter
Dateimanager öffnen windows + shift + c
Fenster verschieben windows + left click
Fenstergröße anpassen windows + right click

Zusätzlich dazu kann auch das Fenster Layout geändert werden

Null windows + f
Monocle windows  + m
Tile windows + t
Apples Grid windows + g


Fazit

DracOS bringt frischen Wind in die Security OS Szene, mit seinem LFS Ansatz ist es eine gelungene Abwechslung zu herkömmlichen Distributionen. Tools sind zahlreich vorhanden und das OS benötigt nicht viele Ressourcen.

DracOS



Parrot Security OS 3.3

Das bereits vor zwei Monaten vorgestellte Sicherheits OS Parrot Security wurde in Version 3.3 veröffentlicht.

Parrot-SecurityDie größten Änderungen der neuen Version dürfte der Wechsel zum Kernel 4.8, GCC 6.2 und PHP7 darstellen.
Des weiteren wurden fast alle der integrierten Security Tools aktualisiert.

 

Parrot Sec




BlackArch Linux 2016.12.29

Ebenfalls kurz vor Weihnachten wurde die neueste Version von BlackArch veröffentlicht.

Die auf ArchLinux basierende Distribution, mit stolzen 6.3 GB an Daten, wurde im Zuge des Rolling Releases auf 2016.12.29 aktualisiert.

BlackArch-Linux

Auch hier wurde der Kernel auf 4.8.13 aktualisiert, sowie viele Programme. Laut Changelog sind über 100 neue Tool hinzugekommen.

BlackArch bietet nun auch eine offizielle Unterstützung für VirtualBox und VMware, hierzu wird nun ein OVA Image bereitgestellt.

Black Arch




Fehlt nur noch der Überblick

Gesamtübersicht der bereits erwähnten Security Systeme

Name Version Tools Besonderes Basis GUI
Autopsy 4.0 ??? The Sleuth Kit Windows  
BackBox 4.7 70+ eigenes Repo Ubuntu Xfce
BackTrack 5 300+ out of date Ubuntu Gnome
BlackArchLinux 2016.12.29 1500+ ArchLinux ArchLinux Gnome
CaINE 5 100+ WinUFO Ubuntu Mate
DracOS 2.1 100+ CLI LFS DWM
DEFT Zero RC1 250+ Dart2 Lubuntu Lxde
Kali Linux 2016.2 300+ ARM fähig Debian Multi
LionSec 5.0 ???   Ubuntu  
Matriux v3 RC1 300+ out of date Debian Gnome
NST 24 ??? Server integriert Fedora  
NetSecLOS 6.0 50+   OpenSuse Lxde
Paladin 6.0 30+   Ubuntu  
Parrot Security 3.3 700+ Cloud fähig Debian Jessie MATE
Pentoo 2015.0 RC5 ??? 64bit Gentoo Xfce
Ronin   150+ out of date Lubuntu Lxde
Sans SIFT 3.0 20+   Ubuntu  

5. Januar 2017

Nach dem durch die Treiberverbesserungen der dritte Teil gut lief, startete ich den vierten in der Erwartung, wieder etwas warten zu müssen. Dem war nicht so. Saints Row 4 läuft mit dem freien Radeon-Treiber noch besser als der dritte Teil und sieht gleichzeitig besser aus. Ein toller Einstieg ins Spiel!

Saints Row 4 ist Saints Row, nur komplett durchgedreht. Ich schrieb über den zweiten, dass es absurd sei, über den dritten, dass es noch absurder sei, und der vierte toppt nochmal alles. Komplett abgehobene Story, die dem Spieler Superfähigkeiten gibt, was eine hervorragende Idee ist, denn als Superheld durch die Stadt zu sprinten oder zu fliegen und Gegner mit Eisbällen einzufrieren oder mit Telekinese Panzer durch die Luft zu werfen macht eine Menge Spaß. Tatsächlich passen im Kontext der absurden Story viele Nebenmissionen viel besser in die Logik des Spiels als bei den Vorgängern.

Nachteil des Ganzen: Vehikel werden unnötig, und die totale Überlegenheit noch krasser. Da kommen dann zwar stärkere Feinde, aber nach ein paar Upgrades können die schnell nicht mehr mithalten. Es spielt sich zwar immer noch toll, ist voller guter Ideen (der Sidescroll-Fighter, die Mass-Effekt-Parodie, Anspielungen auf They Live), die Rollenspielelemente motivieren, die Inszenierung ist klasse und der Ausgang der Story, den wollte ich dann schon sehen. Es hätte bei mir eine sehr gute Bewertung bekommen und ist absolut spielenswert.

Trotzdem reicht es jetzt auch. Das nächste Spiel muss etwas anspruchsvoller sein.

Nachdem vor wenigen Tagen OpenELEC 7.0 veröffentlicht worden ist und damit Kodi 16.1, Bluetooth Audio Support und OpenVPN in das Media System Einzug gehalten hat, ist der Fork LibreELEC mit der Version (Jarvis) v7.0.3 nachgezogen. 

openelec

Download OpenELEC 7.0

LibreELEC

LibreELEC

LibreELEC hatte im Vergleich zum Original schon im Mai 2016 auf Kodi 16.1 aktualisiert. Das Libre Embedded Linux Entertainment Center hat damit die letzte Version des siebener Zweigs veröffentlicht und arbeitet bereits an Version 8.0.
Wer die aktuell im Betastadium befindliche Version testen möchte, kann nun direkt im Update Channel auf LibreELEC 8.0 umschalten. Da einige Addons mit der neuen Version noch nicht funktionieren, ist hier allerdings Vorsicht geboten.

LibreELEC

Wechsel von OpenELEC auf LibreELEC

Hierzu muss lediglich die aktuelle .tar Datei des gewünschten Systems in den Update Ordner des bestehenden Systems kopiert werden, nach einem Neustart wird das Update erkannt und automatisch installiert.

Download LibreELEC

LibreELEC

Info: Die neueste LibreELEC 7.0.3 Version benötigt 215MB und passt somit in alte OpenELEC Boot Partitionen mit 230MB.

LibreELEC USB-SD Creator

Der SD bzw. USB Creator wurde ebenfalls bereits im letzten Jahr veröffentlicht. Die letzte Version 1.2 im Oktober. Das Tool erlaub es mit wenigen Klicks verschiedene Systeme (Raspberry Pi, x68_64, WeTek, Slice oder Cubox) mit LibreELEC zu bespielen.

LibreELEC-USB-SD-Creator

Es läuft unter Linux, macOS und Windows und bietet euch die aktuelle finale und beta Version zum Download an. Offline können natürlich auch andere Images verwendet werden.  

Download LibreELEC USB-SD Creator

LIBRE ELEC SD Creator
Ein wirkliches praktisches Tool, welches sicherlich vielen das Bespielen von SD Karten vereinfacht.

© bluedesign / Fotolia.com

Seit ziemlich genau 10 Jahren nutze ich Linux als primäres Desktopbetriebssystem. Anfangs aus Neugier und Spaß an der steilen Lernkurve, später aus Überzeugung ein qualitativ hochwertig(er)es System zu nutzen. Selbst den harten Umstieg auf KDE 4 konnte ich noch verwinden. Damit ist zum Jahreswechsel 2016 auf 2017 Schluss. 

Nachdem bereits im Sommer das mobile Arbeitsgerät durch ein MacBook Air ersetzt wurde, verdrängte ein Apple-Produkt nun auch den, in die Jahre gekommenen, Desktop-PC. Linux spielt bei mir weiterhin eine wichtige Rolle. Sowohl als Serversystem, als auch für spezielle Einsatzbereiche und nicht zuletzt als virtuelle Maschine für einige spezielle Programme, die es nur für Linux gibt - aber es nicht mehr das Hauptsystem.

Wer regelmäßig diesen Blog hier verfolgt, dürfte davon nicht sonderlich überrascht sein. Die letzten 1,5 Jahre lesen sich aus der Rückschau wie eine Artikelserie unter dem Leitmotiv „Frustration“ - auch wenn die Abkehr von Linux weder intendiert, noch zwangsläufig war.

Alles begann mit dem vollkommen amateurhaft vollzogenen Umstieg des KDE-Projekts von Plasma 4 auf Plasma 5 (Kritik Teil I, Teil II, Teil III). Die Desktopoberfläche (immerhin der Hauptberührungspunkt mit dem System) versagte dem Anwender regelmäßig den Dienst. Selbst nach Jahren der Entwicklung könnte ich aus dem Stehgreif eine Liste von katastrophalen Fehlfunktionen und nervigen Problemen auflisten. Dass die Entwickler Verantwortungs-Pingpong für das Desaster spielen, hilft einem als Anwender überhaupt nicht. Parallel zum Desktop brach auch die Distributionsbasis weg. KDE hatte stabilen Systemen anfänglich regelrecht den Kampf angesagt. Erst sehr spät ruderte man ein wenig zurück, Ausgang bisher ungewiss. Wer kein rollendes System wollte, wurde faktisch vor die Tür gesetzt. Die Qualität stabiler Distributionen wie Kubuntu spricht Bände. Plasma und die integrierte Intelgrafik vertragen sich zudem subjektiv immer schlechter, was äußerst ärgerlich ist, wenn man in vielen Jahren des Linux-Einsatzes eine Intel-zentrierte Hardware angehäuft hat. Neuinstallationen wurden immer mehr zum Glückspiel. Konfigurationen in der xorg.conf wieder zur Normalität und das im Jahr 2016.

Natürlich ist der Desktop bei Linux austauschbar. Dutzende selbstständige Projekte, Forks, Abspaltungen und Totgeburten bieten sich dem potenziellen Anwender an. Nur bin ich als Anwender halt nicht umsonst bei Plasma gelandet. Weder möchte ich einen funktional verkümmerten Desktop (z.B. Unity, GNOME), noch eine konservierte Anwendungsumgebung des letzten Jahrtausends (z.B. MATE, Xfce) einsetzen. Alle diese Projekte haben sicherlich ihre Zielgruppen - zu denen ich aber scheinbar nicht gehöre. Zudem ist meine Bereitschaft persönlichen Anwendungsbedürfnisse hinter ideologischen Projektausrichtungen zurück zu stellen tendenziell rückläufig.

Die wachsende Unzufriedenheit mit Desktop und Distribution führt zu einer stärkeren Evaluierung des Programmumfeldes in dem ich arbeite. Hier lautet die bittere Erkenntnis, dass sich die Welt weiter gedreht hat, nur bei Linux nicht. Entweder fehlt es schlicht an alternativen Lösungen zu den großen proprietären Platzhirschen, oder die vorhandenen Programme sind funktional rückständig. Es sei denn man ist ein Anhänger des Arguments, dass man eh einen vollkommen falschen Arbeitsansatz hätte und lediglich die richtige Arbeitsweise erlernen müsse. Stattdessen werden von den Entwicklern regelmäßig mobile Traumlandschaften generiert und gleichzeitig die x.te Portierung der genutzten Groupware auf die aktuelle Toolkitversion mit einer Fehlerorgie bezahlt, da Entwickler rar gesät sind. Das passt einfach nicht mehr zusammen.

MacOS hat viele Nachteile. Das Betriebssystem ist hochgradig geschlossen gegen Änderungen von Dritten (gefühlt deutlich mehr als Windows) und wird im stillen Kämmerlein entwickelt. Zudem gibt es Gerüchte, dass Apple sein Engagement hier deutlich zurück fährt. Selbst wenn letzteres zutreffen mag, kann ich mit dem aktuellen Stand aber bereits sehr gut arbeiten. Ein Zustand, den Linux in den letzten Jahren nie erreichte, dort spielte immer die Hoffnung auf eine Verbesserung in der nächsten, übernächsten oder überübernächsten Version eine Rolle um bei der Stange zu bleiben.

Linux kann auf dem Desktop für viele Anwender immer noch funktionieren. Wünsche und Anforderungen an ein Desktopbetriebssystem sind hochgradig individuell. Ich für meinen Teil habe aber schlichtweg die Lust verloren.

© bluedesign / Fotolia.com

Seit ziemlich genau 10 Jahren nutze ich Linux als primäres Desktopbetriebssystem. Anfangs aus Neugier und Spaß an der steilen Lernkurve, später aus Überzeugung ein qualitativ hochwertig(er)es System zu nutzen. Selbst den harten Umstieg auf KDE 4 konnte ich noch verwinden. Damit ist zum Jahreswechsel 2016 auf 2017 Schluss. 

Nachdem bereits im Sommer das mobile Arbeitsgerät durch ein MacBook Air ersetzt wurde, verdrängte ein Apple-Produkt nun auch den, in die Jahre gekommenen, Desktop-PC. Linux spielt bei mir weiterhin eine wichtige Rolle. Sowohl als Serversystem, als auch für spezielle Einsatzbereiche und nicht zuletzt als virtuelle Maschine für einige spezielle Programme, die es nur für Linux gibt - aber es nicht mehr das Hauptsystem.

Wer regelmäßig diesen Blog hier verfolgt, dürfte davon nicht sonderlich überrascht sein. Die letzten 1,5 Jahre lesen sich aus der Rückschau wie eine Artikelserie unter dem Leitmotiv „Frustration“ - auch wenn die Abkehr von Linux weder intendiert, noch zwangsläufig war.

Alles begann mit dem vollkommen amateurhaft vollzogenen Umstieg des KDE-Projekts von Plasma 4 auf Plasma 5 (Kritik Teil I, Teil II, Teil III). Die Desktopoberfläche (immerhin der Hauptberührungspunkt mit dem System) versagte dem Anwender regelmäßig den Dienst. Selbst nach Jahren der Entwicklung könnte ich aus dem Stehgreif eine Liste von katastrophalen Fehlfunktionen und nervigen Problemen auflisten. Dass die Entwickler Verantwortungs-Pingpong für das Desaster spielen, hilft einem als Anwender überhaupt nicht. Parallel zum Desktop brach auch die Distributionsbasis weg. KDE hatte stabilen Systemen anfänglich regelrecht den Kampf angesagt. Erst sehr spät ruderte man ein wenig zurück, Ausgang bisher ungewiss. Wer kein rollendes System wollte, wurde faktisch vor die Tür gesetzt. Die Qualität stabiler Distributionen wie Kubuntu spricht Bände. Plasma und die integrierte Intelgrafik vertragen sich zudem subjektiv immer schlechter, was äußerst ärgerlich ist, wenn man in vielen Jahren des Linux-Einsatzes eine Intel-zentrierte Hardware angehäuft hat. Neuinstallationen wurden immer mehr zum Glückspiel. Konfigurationen in der xorg.conf wieder zur Normalität und das im Jahr 2016.

Natürlich ist der Desktop bei Linux austauschbar. Dutzende selbstständige Projekte, Forks, Abspaltungen und Totgeburten bieten sich dem potenziellen Anwender an. Nur bin ich als Anwender halt nicht umsonst bei Plasma gelandet. Weder möchte ich einen funktional verkümmerten Desktop (z.B. Unity, GNOME), noch eine konservierte Anwendungsumgebung des letzten Jahrtausends (z.B. MATE, Xfce) einsetzen. Alle diese Projekte haben sicherlich ihre Zielgruppen - zu denen ich aber scheinbar nicht gehöre. Zudem ist meine Bereitschaft persönlichen Anwendungsbedürfnisse hinter ideologischen Projektausrichtungen zurück zu stellen tendenziell rückläufig.

Die wachsende Unzufriedenheit mit Desktop und Distribution führt zu einer stärkeren Evaluierung des Programmumfeldes in dem ich arbeite. Hier lautet die bittere Erkenntnis, dass sich die Welt weiter gedreht hat, nur bei Linux nicht. Entweder fehlt es schlicht an alternativen Lösungen zu den großen proprietären Platzhirschen, oder die vorhandenen Programme sind funktional rückständig. Es sei denn man ist ein Anhänger des Arguments, dass man eh einen vollkommen falschen Arbeitsansatz hätte und lediglich die richtige Arbeitsweise erlernen müsse. Stattdessen werden von den Entwicklern regelmäßig mobile Traumlandschaften generiert und gleichzeitig die x.te Portierung der genutzten Groupware auf die aktuelle Toolkitversion mit einer Fehlerorgie bezahlt, da Entwickler rar gesät sind. Das passt einfach nicht mehr zusammen.

MacOS hat viele Nachteile. Das Betriebssystem ist hochgradig geschlossen gegen Änderungen von Dritten (gefühlt deutlich mehr als Windows) und wird im stillen Kämmerlein entwickelt. Zudem gibt es Gerüchte, dass Apple sein Engagement hier deutlich zurück fährt. Selbst wenn letzteres zutreffen mag, kann ich mit dem aktuellen Stand aber bereits sehr gut arbeiten. Ein Zustand, den Linux in den letzten Jahren nie erreichte, dort spielte immer die Hoffnung auf eine Verbesserung in der nächsten, übernächsten oder überübernächsten Version eine Rolle um bei der Stange zu bleiben.

Linux kann auf dem Desktop für viele Anwender immer noch funktionieren. Wünsche und Anforderungen an ein Desktopbetriebssystem sind hochgradig individuell. Ich für meinen Teil habe aber schlichtweg die Lust verloren.

4. Januar 2017

Timestamps innerhalb von X Tagen

Für ein Kundenprojekt musste ich herausfinden, welche Timestamps, die in einem Array hinterlegt sind, innerhalb der letzten 7 Tage liegen. Um diese eigentlich sehr einfache Aufgabe zu lösen, nutze ich die PHP eigne Funktion strtotime(). Folgendes Snippet zeigt die Lösung:


$my_dates = array('1483523798', '1483437398', '1481622998');
$inside7Days = array();

for ($i = 0; $i < count($my_dates); ++$i) {
    if ($my_dates[$i] > strtotime('7 days ago')) {
        array_push($inside7Days, $my_dates[$i]);
    }
}

var_dump($inside7Days);

Die Variable $my_dates beinhaltet die zu kontrollierenden Timestamps. Mit einer einfach IF Abfrage kontrollieren wir, ob die Timestamps größer sind als der Timestamp for 7 Tagen, der durch die PHP Funktion strtotime genereiert wird:

strtotime('7 days ago')

Zum Schluss lassen wir uns noch das Array ausgeben, was die entsprechenden Timestamps beinhaltet:

var_dump($inside7Days);

Und das war es auch schon. Die Dauer lässt sich natürlich wunderbar anpassen durch die Benutzung der strtotime() Funktion.

Timestamps innerhalb von X Tagen

Für ein Kundenprojekt musste ich herausfinden, welche Timestamps, die in einem Array hinterlegt sind, innerhalb der letzten 7 Tage liegen. Um diese eigentlich sehr einfache Aufgabe zu lösen, nutze ich die PHP eigne Funktion strtotime(). Folgendes Snippet zeigt die Lösung:


$my_dates = array('1483523798', '1483437398', '1481622998');
$inside7Days = array();

for ($i = 0; $i < count($my_dates); ++$i) {
    if ($my_dates[$i] > strtotime('7 days ago')) {
        array_push($inside7Days, $my_dates[$i]);
    }
}

var_dump($inside7Days);

Die Variable $my_dates beinhaltet die zu kontrollierenden Timestamps. Mit einer einfach IF Abfrage kontrollieren wir, ob die Timestamps größer sind als der Timestamp for 7 Tagen, der durch die PHP Funktion strtotime genereiert wird:

strtotime('7 days ago')

Zum Schluss lassen wir uns noch das Array ausgeben, was die entsprechenden Timestamps beinhaltet:

var_dump($inside7Days);

Und das war es auch schon. Die Dauer lässt sich natürlich wunderbar anpassen durch die Benutzung der strtotime() Funktion.

Der ownCloud-Fork Nextcloud verfügt ebenfalls über eine Kalender-App. Wollte man unter ownCloud ein ICS-Datei in den Kalender importieren, so musste man diese hochladen und die Datei über die Dateiansicht von ownCloud importieren. Versucht man dies unter Nextcloud, wird man feststellen, das statt eines Importes der Texteditor geöffnet wird.

Die Einstellungen der Kalender-App

Der Grund dafür ist, das der Import von ICS-Dateien unter Nextcloud mittlerweile anders gelöst ist. Der Umweg über den Upload entfällt; stattdessen kann die ICS-Datei direkt über die Einstellungen der Kalender-App importiert werden.