Mittwoch, 1. April 2015

Wie ich mal auf ClientsFromHell.net navigieren wollte

Update 2015-04-06

Looks like Firefox 37.0 changed strings used in KeyEvent.key, specifically "Right" is now "ArrowRight" and "Left" is now "ArrowLeft".
So the corresponding switch-case blocks need to be adjusted to
      case "ArrowRight": // as of Firefox 37.0
      case "Right": // pre Firefox 37.0

and
      case "ArrowLeft": // as of Firefox 37.0
      case "Left": // pre Firefox 37.0




English below.

Deutsch

clientsfromhell.net sammelt seltsame, lustige, selten unerwartet logische und zumeist unvernünftige, jedenfalls unterhaltsame Dialoge zwischen Klienten und Dienstleistern.
Ich glaube, schonmal auf der Seite gewesen zu sein, erinnere mich aber an deutlich weniger Inhalt, muß also schon ein paar Jahre her sein. Nun hat die Seite aber jede Menge Unterhaltung zu bieten. Was fehlt, ist simple Navigation.
Jede Geschichte hat eine "Einzelseite" (für Kommentare und) mit drei buttons: "Previous", "Next" und "Next Random Client Story". Leider sind diese buttons nicht an Tasten gebunden, so daß man jeweils den mouse cursor zum gewünschten button bewegen und darauf klicken muß (oder ziemlich oft Tabulator und dann Enter drücken). Ein unerträglicher Zustand für mich. Zugegeben ich würde mich vielleicht noch durch 20 bis 40 Seiten klicken, irgendwann aber bringt mich dieser einfache Umstand von der Seite weg.

Glücklicherweise hatte ich genügend Erfahrung mit JavaScript, um die entsprechende Änderungen in greifbarer Nähe zu sehen. Eine Stunde später stand das Skript. Zugegeben mein Bruder, der mich wieder zu der Seite gebracht hatte, brauchte etwa 10 Minuten weniger. Hier jedenfalls eine Lösung.

Hinweis 1: Für nicht angemeldete Nutzer der Seite wird auf jeder Seite um Anmeldung geworben *hust* NoScript *hust*. Die Werbung läßt sich mit Esc für die einzelne Seite schließen oder für 30 Tage über einen Link auf der Werbung.
Hinweis 2: Man sollte nur solche Skripte ausführen, deren Inhalt und Funktionsweise man versteht. Andernfalls kompromittiert man die eigene Datensicherheit.

Hat man GreaseMonkey im Browser installiert, kann man auf eine der oben gegebenen Beispielseiten gehen, über das GreaseMonkey-Menü ein neues Skript anlegen, die Zielseiten auf alle Einzelseiten, http://clientsfromhell.net/post/*, setzen und das folgende Skript einfügen. Danach speichern und eine Einzelseite neu laden.
Das Skript enthält noch ein bißchen Müll, der vielleicht zur Entwicklung in andere Richtungen nützlich ist.

// ==UserScript==
// @name        Navigation ClientsFromHell.Net
// @namespace   www.dauth.de
// @include     http://clientsfromhell.net/post/*
// @version     1
// @grant       none
// ==/UserScript==

console.log("LOADING Navigation ClientsFromHell.Net");
/**/
document.onkeydown = function(e) {
    e = e || window.event;
    //console.log("Key pressed: ("+e.which+","+e.keyCode+","+e.key+")");
    //pressedKey = e.which || e.key; // MSIE support
    switch(e.key){
      case "Right":
      case "n":
        url=document.getElementById("nextPost");   
        break;
      case "Left":
      case "p":
        url=document.getElementById("prevPost");   
        break;
      case "r":
        url=document.getElementById("randomPost");
    }
    window.location.href=url;
};
/**/
console.log("LOADED Navigation ClientsFromHell.Net");


English

clientsfromhell.net collects strange, funny, seldom unexpected logical and mostly unreasonable, in any case entertaining dialogues between clients and service providers.
I believe I've seen the site before but remember substantially fewer content. So I guess, it's been some years. Now the page offers a huge amount of entertainment. What's missing is easy navigation.
Every anecdote has their own "post page" (allowing for commentary and) with three buttons: "Previous", "Next" and "Next Random Client Story". Unfortunately those are not bound to keys o you have to move the mouse cursor to the esired button and click (or hit Tab a lot of times then Enter). For me, that's an unacceptable situation. Admittedly, I may still go through 20 to 40 pages but at some point I'd leave because of the hassle.

Fortunately, I'm familiar enough with JavaScript to believe the necessary changes wihtin my reach. An hour later the script was done. I have to admit, my brother, being the one to bring me back to the CFH, finished 10 minutes earlier. anyway, here's my solution.

Hint 1: If your not signed in you'll see an ad asking you to join on every page *cough* NoScript *cough*. You can close the ad per page by pressing Esc or for 30 days altogether by clicking a link in the ad.
Hint 2: Do not run script you don't understand. Otherwise you may be compromising your personal data.

If you have GreaseMonkey installed in your Browser you can go to one of the example pages above, use the GreaseMonkey menu to create a new script, change the target/included pages to all post pages, http://clientsfromhell.net/post/*, and paste the script above. Then save and reload a post page.
The script contains a bit of litter that may be useful to develop in other directions.

Freitag, 5. Dezember 2014

Wie ich mal ein Firefox downgrade für Flash durchführte (Ubuntu 12.04)

Deutsch

English version below.

Problem

Vor ein paar Tagen hat sich Firefox auf die Version 34.0 geupdated und seitdem keine Flash-Inhalte mehr geladen. Das heißt kein Youtube-Videos mehr und keine Zeitverschwendung für dumme kleine Flash-Spiele. Dafür aber Zeitverschwendung für die Recherche, was eigentlich los ist - immernoch ungeklärt - und was man dagegen tun kann.

Adobe bietet eine Seite zum Testen des Flash players. Springt oben auf der Seite eine Flash-Kiste rum, funktioniert der Flash player. Die Animation ist kurz, also sollte man die Seite beim Draufschauen nochmal laden.

Ich habe über die Addon-Seite von Firefox nach updates für Erweiterungen und plugins gesucht und gefundenes installiert. Zu dem habe ich testweise alle Blocker deaktiviert, ohne Erfolg.

Es sei erwähnt: Updates erhöhen die Sicherheit.

Ein downgrade ist also nur bedingt zu empfehlen. Zweck und Problem von Sicherheit-updates ist das Einschränken von Funktionalität. Ein Sicherheitsmodell, das wesentliche Funktionen, wie Zugriff auf Youtube-Videos, abstellt, wird dennoch im echten Leben keinen Bestand haben.

Versuche

Die Idee war nun, die alte Version von Firefox wieder zu installieren. Das soll laut Internet ohne Deinstallation von Firefox gehen, also bei Erhaltung der Profile, Lesezeichen usw.

Fehlversuch: apt-get & apt-show-versions

Über apt-get kann man Pakete bestimmter Versionen installieren, vorausgesetzt, man weiß, wie die Version zu bennen ist, und die Version steht apt-get auch zur Verfügung. Im Falle eines Doppelpositiv kann man zur Installation folgenden Befehl verwenden:
sudo apt-get install firefox=<version>


Über das Programm apt-show-versions kann man sich anzeigen lassen, welche Versionen zur verfügung stehen.

In meinem Fall steht aber überall nur noch die aktuelle Version bereit:
~$ apt-show-versions -a -p firefox

firefox 34.0+build2-0ubuntu0.12.04.1 install ok installed
firefox 34.0+build2-0ubuntu0.12.04.1 precise          de.archive.ubuntu.com
firefox 34.0+build2-0ubuntu0.12.04.1 precise-security security.ubuntu.com
firefox/precise uptodate 34.0+build2-0ubuntu0.12.04.1

Fehlversuch: synaptic

Synaptic bietet über das Menü Package die Option "Force Version", allerdings auch nur mit verfügbaren Versionen, also für mich wieder 34 - siehe auch hier.

Erfolgsversuch: download & dpkg

Letztendlich habe ich mir ein Debian package von sourceforge.net (bietet fast alle Firefox releases) runtergeladen und installiert:
sudo dpkg -i firefox-mozilla-build_33.1.1-0ubuntu1_i386.deb
Nun kann ich Flash-Inhalte wieder abspielen. Nur wie bekomme ich jetzt mit, ob Version 34 endlich Flash-fit ist?

English

Problem

A few days ago Firefox updated to version 34.0 and doesn't load Flash content since. So no Youtube videos and no wasting time on silly Flash games. Instead wasting time on searching for what is going on - still unclear - and what canbe done about it.

Adobe offers a Flash player test. If Flash player is working correctly you should see a Flash box jumping around the top of the page. The animation is quite short so it may be necessary to reload the page while looking at it.

I searched for updates for extensions and plugins on Firefox's addon page and installed what turned up. Additionally, I deactivated all blockers, to no avail.

Let it be said: Updates increase security.

A downgrade is not generally advisable. Purpose and problem of security updates is restricting functionality. However, a security model that deactivates widely used functionality, e.g. access to Youtube videos, will not prevail in real life.

Attempts

Now the idea was to simply install the previous verion of Firefox. According to the Internet, this can be done without deinstalling the installed version of Firefox and should retain profiles, bookmarks etc.

Fail: apt-get & apt-show-versions

With apt-get you can set the version of a package to install, given you know the version identifier and apt-get has access to that version. In case of a double positive the following command installs the specified version:
sudo apt-get install firefox=<version>

The program apt-show-versions lists available versions.

In my case I have access only to the newest release candidate:
~$ apt-show-versions -a -p firefox

firefox 34.0+build2-0ubuntu0.12.04.1 install ok installed
firefox 34.0+build2-0ubuntu0.12.04.1 precise          de.archive.ubuntu.com
firefox 34.0+build2-0ubuntu0.12.04.1 precise-security security.ubuntu.com
firefox/precise uptodate 34.0+build2-0ubuntu0.12.04.1

Fail: synaptic

Via the menu Package synaptic offers the option "Force Version", again only for available version, so 34 in my case - see here.

Success: download & dpkg

In the end I downloaded a Debian package from sourceforge.net (offering almost all Firefox releases), then installed it using dpkg:
sudo dpkg -i firefox-mozilla-build_33.1.1-0ubuntu1_i386.deb
Now Flash content is available again. But how do I know when version 34 is fit for Flash?

Dienstag, 2. September 2014

Wie ich einmal (vielleicht) das lästige Problem der Synergy sticky keys löste

Es ist schon relativ spät, nicht ganz drei Uhr morgens, als ich mir überlege, noch eine Portion Koffein und Zucker zu mir zu nehmen und einen Report für die Arbeit fertigzuschreiben. Da plötzlich taucht mal wieder das vermaledeite Synergy-Problem der sticky keys auf. Ein Zustand, den ich bis heute nur durch einen Neustart des betroffenen Ubuntu-Rechners beheben konnte.

Wie gesagt, wollte ich gerade wieder losarbeiten und hatte entsprechend viele Fenster offen sowie ein VPN und zwei SSH-Sitzungen laufen. "Viele Fenster offen?" höre ich Euch sagen, "Das habe ich auch, wenn der Tag lang ist." Aber es geht nicht um die bloße Anzahl. Der Zustand der Arbeitsoberfläche enthält all die kleinen Hinweise, die sich bei kontinuierlicher Arbeitsweise ergeben, um eben diese langfristig zu ermöglichen. Hatte mich gerade wer gefragt, wie schwer es wäre, diese oder jene Webseite "schnell zu bauen", bringt mich danach das simple Drücken von Alt+Tab wieder in den vorherigen Gedanken zurück. Und genau das ist es, was einem so erbarmungslos durch einen Neustart genommen ist. Hmm, vielleicht sollte ich mich mal nach Sitzungsspeichern umsehen...

Was ist Synergy?

Worum geht's eigentlich? Synergy ist ein phantastisches input device sharing tool, d.h. ich kann mit einem Satz Tastatur und Maus alle meine Rechner am Schreibtisch - drei Maschinen, auf denen zwei bis drei verschiedene Betriebssysteme laufen - bedienen und das bedeutet, es ist viel mehr Platz, um endlos Papier zu verteilen.
Synergy läuft auf Linux, Windows und Mac und ist kostenlos, bittet aber um Spenden. Ich rate dazu, das tool erstmal auszuprobieren und wenn man es nach ein paar Monaten noch benutzt, kann man mal bilanzieren und sich beantworten, wieviel Zeit und Streß man sich gespart hat (oder auch nicht) und entsprechend spenden (oder auch nicht).

Zur Einrichtung installiert man das Programm in derselben Version und der jeweiligen Architektur entsprechend auf allen gewünschten Rechnern (eines LANs), sucht sich einen von diesen als server-Rechner aus, startet das Programm überall, ordnet auf dem server die Rechner virtuell nebeneinander oder übereinander an und verbindet die client-Rechner mit dem server. Fertig.

Ich bin im prinzip so begeistert, daß ich mich zur (geringfügigen) finanziellen Unterstützung des Projektes überredet habe.

Ein, nicht immer ganz flüssiges, aber trotzdem sehr praktischen feature ist die Übertragung von Zwischenspeichern. Texte, die man auf einem der Rechner per Strg+C in den Zwischenspeicher kopiert, kann man auf einen anderen Rechner per Strg+V einfügen.

Übrigens werden die Eingabegeräte der clients nicht einfach lahmgelegt. Trägt man einen client laptop mal von der Haupttastatur weg, kann man einfach am client weitertippen.

Sticky Keys

Ganz streßfrei ist Synergy allerdings nicht, sonst wäre es nicht zu diesen Zeilen gekommen. Sporadisch und unvermittelt tritt bei mir das Problem auf, daß sich einer der client-Rechner einbildet, eine der Metatasten wäre gedrückt. Es ist nicht konsistent dieselbe Taste und das Problem tritt immer erst nach einer ganzen Weile auf, d.h. im Abstand von Tagen oder Wochen.
Drückt man die "hängende" Taste, so springt das Problem manchmal zu einer anderen Taste. Ich denke, die Problemtasten beschränken sich auf:
Capslock, Strg_L/Ctrl_L, Strg_R/Ctrl_R, Shift_R, Shift_L, Alt_R, AltGr/Alt_R, Menu (quasi die Rechtsklicktaste).
Symptome des Problems (bei Ubuntu 12.04) beinhalten
  • die Unmöglichkeit, KeyEvents von Tasten in Verbindung mit Shift auszulösen (?),
  • die Unmöglichkeit, KeyEvents von Tasten ohne Verbindung mit Shift auszulösen (Shift down?),
  • Flimmern der Fenstermenüleiste, da der WindowManager meint, Tastaturkürzel zu empfangen (Alt down),
  • Verschieben von Fenstern durch DragEvents (Alt down) und
  • maßloses Markieren durch DragEvents der Maus (Strg/Ctrl down).

Kapitulation

Um die Problemtaste weiterspringen zu lassen, muß man ab und zu beide Tasten einer Art gleichzeitig dürcken, zum Beispiel beide Shift-Tasten. Landet man in dem Zustand, daß AltGr/Alt_L als gedrückt gilt, so kann man wenigstens bei tatsächlich gedrückter AltGr/Alt_L-Taste alle Klickaktionen durchführen, wie etwa Fenster schließen, Dateien speichern (nicht jedoch den Namen ändern) und den Neustart initiieren.
Dies war bisher die einzige und dem langen Drücken der Power-Taste noch vorzuziehende Methode für mich, das System wieder in einen nutzbaren Zustand zu versetzen.

Intuition/Haltlose Gerüchte

Ich habe das Gefühl, daß sticky keys nur auftreten, nachdem die client-Maschine wieder aus dem sleep mode erwacht. Zudem vermute ich, daß das Laden von einem oder mehreren Firefox-Profilen vielleicht zum Auftauchen des Problems beiträgt.

Gelöst(?)

Als nun also das Problem wieder auftrat, brachte ich mal wieder genug Energie auf, um dieses immerhin schon seit mehreren Jahren bekannte Problem zu erforschen und habe nach einfachen InputEvent listening devices gesucht, also Programmen, die mir mitteilen, wenn zum Beispiel ein KeyEvent (per Tastatur) oder MouseEvent (per Maus) ausgelöst wird. So stieß ich auf xev, einen event listener für X-Systeme wie zum Beispiel Ubuntu.

xev wies mich sofort nach dem Starten (mühsames Zusammenkopieren der drei Buchstaben und von Return in einen Terminal) darauf hin, daß unentwegt Alt_L aka AltGr gedrückt wurde, auch ohne einen Finger an irgendeiner Taste. Da man ja lösungsorientiert denken soll,verstand ich die Angaben einfach mal als Aufforderungen und drückte, nach und nach wasauchimmer xev mir als Taste in den Terminal warf, ab und zu auch mit der zugehörigen Zwillingstaste zusammen und manchmal gedankenverloren unterbrochen durch Drücken auch noch nicht genannter Tasten wie Capslock und Menu (Taste mit dem Symbol eines Drop-Down-Menüs). Auf diese Weise änderten sich die angegebenen KeyEvents und nach weniger als drei Minuten hatten sich plötzlich alle sticky keys gelöst und ich konnte wieder normal tippen auch ohne Neustart.

Ich weiß nicht, ob es zur Lösung beigetragen hat, daß ich zwischendurch die meisten Anwendungen (z.B. alle Firefox-Fenster) geschlossen habe. Das einfache Weiterarbeiten hatte sich damit jedenfalls schon erledigt.

Vorbereitung

Um beim nächten Mal besser reagieren zu können, habe ich mir auf dem Desktop ein Verzeichnis cd-xev angelegt und die ausführbare Datei terminal-vom-Desktop:

#!/bin/bash
cd cd-xev
/usr/bin/gnome-terminal

Wenn ich die Datei ausführe, öffnet sie einen bash-Terminal vom Verzeichnis cd-xev aus, wodurch ich mir einfach per Maus das Kommando xev zusammenklicken kann, um dann wie oben beschrieben die Lösung nochmal zu versuchen.

Synergy-Hinweise

Seit irgendwann kann Synergy nicht mehr mit client-Rechnern umgehen, deren gesendeter Name mit einer Nummer beginnen. Sinnvollerweise kann man im Synergy des clients den Anmeldenamen anpassen.

Beim Rechnerwechesel kann es zu Problemen kommen, wenn man noch Metatasten drückt, wann man also zum Beispiel bei gedrückter Taste Strg den Mauszeiger zu einem anderen Rechner zieht. Ich rate entsprechend davon ab.

Ich hoffe, das hilft.

English (short)

Synergy Sticky Keys

Client machines in a Synergy setup may experience sticky key, i.e. even though no key is touched the machine constantly gets KeyEvents from one of
Capslock, Strg_L/Ctrl_L, Strg_R/Ctrl_R, Shift_R, Shift_L, Alt_R, AltGr/Alt_R, Menu (basically the right-click key, has drop-down menu symbol).

Symptoms (on Ubuntu 12.04) include:
  • impossibility to execute KeyEvents in connection with Shift (?),
  • impossibility to execute KeyEvents without connection to Shift (Shift down?),
  • flickering window menu bar, since the WindowManager "receives" shortcuts (Alt down),
  • moving windows on DragEvents (Alt down) and
  • greedy marking on DragEvents (Strg/Ctrl down).

Solved(?)

Run xev, an event listener for X systems like Ubuntu. Keep pressing the key xev reports as being pressed already. The key that's perceived as constantly pressed should change. It may be necessary to press the meta key's twin key as well at the same time. From time to time also press those meta keys that haven't appeared yet, e.g. Capslock und Menu.
When my machine normalized its key events I had also closed most of my applications, specifically all Firefox windows. So this may also have had an effect.

Prepare

When this started today I had already a hard time running xev, since I had to find and mark the required letters with the mouse and paste them into a terminal as well as an easier to find Return/linebreak.
In order to react in an easier fashion the next time the problem occurs I created a directory cd-xev on my Desktop and an executable file terminal-from-Desktop:
#!/bin/bash
cd cd-xev
/usr/bin/gnome-terminal

I hope this will help.

Montag, 1. September 2014

Wie ich mal ein GreaseMonkey-Skript für Steam search results schrieb


Update [2014-09-27]

Steam hat mittlerweile das Design umgestellt, so daß discounts für Suchergebnisse automatisch angezeigt werden. Das Skript hier könnte man nun so anpassen, daß es die discounts nach Prozent einfärbt wie unten beschrieben.

Steam has changed the design so that discounts for search results are directly shown. The script here can be adapted to recolour discount displays according to percentages and the colour keys given below.


Deutsch

Motivation

Ich ziehe derzeit, da ich Null Zeit zum Spielen habe, einige Energie daraus, mir wenigstens ab und zu auf Steam Spiele zu kaufen. Da ich fast nur Spiele kaufe, die im Preis heruntergesetzt sind, finde ich mich immer mal wieder auf der Suchseite von Steam wieder. Im Preis heruntergesetzte Suchergebnisse werden dort mit zwei Preisen angegeben, dem durchgestrichenen Normalpreis und dem heruntergesetzten. Doch welche lohnen sich?

Ein Rabatt von 50% oder weniger ist häufig für alle möglichen Spiele zu sehen, 75% und mehr für interessante Spiele sind dagegen eher selten. Dieser Hinweis auf die Seltenheit des Angebotes steht aber nicht direkt zur verfügung. Stattdessen muß man die beiden Preise verrechnen, von denen einer auch noch schwerer lesbar gemacht wurde.

Warum steht nicht einfach der Rabatt da? Hmm, warum schreibe ich mir nicht die Rabatte dazu? Dann könnte man das gleich weiterverteilen.

Aufgabe

Schreibe ein GreaseMonkey-Skript (JavaScript), daß die Anzeige um die Rabatte erweitert und einfärbt, um schnell zu erkennen, wie lukrativ und selten ein Angebot ist.
Weil ich mich nicht damit beschäftigen wollte, die Ladezustände von selbstaktualisierten Seiten zu erkennen, habe ich entschieden, daß ich nur einen Button auf der Suchseite haben will, über den ich die Rabatte zu den Suchergebnissen hinzufügen kann.

Probleme

Ich habe das Skript stückweise in Firebug 2.0.3 zusammengeschrieben und dann in ein GreaseMonkey-Skript (2.2) gegossen. Dabei bin ich als GM newbie auf das Problem gestoßen, daß GM seine Fehlermeldungen nicht einfach in die Firebug-Konsole schmeißt, wodurch ich zunächst nur feststellen konnte, daß mir Funktionalität fehlt, nicht aber was das eigentliche Problem ist oder an welcher Stelle es auftritt.
Es stellt sich heraus, daß GM Fehler an die Firefox-Fehlerkonsole weitergibt, die man in Firefox über das Kürzel CTRL+SHIFT+J öffnen kann.


Das code-Problem bestand darin, daß in der Firebug-Konsole für strings die Methode strip() existiert, nicht aber in GM. Dort heißt die Methode trim() (steht auch in Firebug bereit).

GM-Skript

Der Knopf

Der Ansicht der Suchseite wird oben links ein Knopf hinzugefügt, auf dem einfach ein Prozentzeichen zu sehen ist.
Der Knopf ist "an den Bildschirm geheftet" (style.position="fixed"), wodurch er auch beim scrollen an seiner Position bleibt.
Durch das Klicken des Knopfes werden, die gerade gezeigten Suchergebnisse durchlaufen und soweit nötig um den kolorierten Rabatt erweitert. Da beim scrollen zum Seitenende unter Umständen weitere Ergebnisse geladen werden, muß man den Knopf nochmal betätigen, um auch dort die Rabatte zu sehen.
Ich empfehle, zum Seitenende zu scrollen, bis Steam keine Ergebnisse mehr nachlädt und dann den Knopf zu drücken.

Die Rabatte sind nach subjektiv gewählten Prozentbereichen koloriert.
ProzentbereichBasis16-CodeFarbeFarbname
[0,49]#b0aeacLight grey (Steam default)
(49,64]#FF4500Orange red
(64,74]#FFFF00Yellow
(74,79]#00FF00Lime (was #00FFFF Aqua)
(79,89]#00FFFFAqua (was #0000FF Blue)
(89,100]#8B008BDark magenta
Hier nochmal alle Farb-codes am Beispiel:

Skript

Zur Verwendung des Skriptes installiert man GreaseMonkey im Firefox geht dann über das GM-Menü auf die Skripteverwaltung und paßt das folgende Skript ein:

// ==UserScript==
// @name        Steam Search with Discount Percentages
// @namespace   www.dauth.de
// @description Enhance Steam search results with color-coded discount percentages.
// @include     http://store.steampowered.com/search/*
// @version     1
// @grant       none
// ==/UserScript==

// include     http://store.steampowered.com/search/?sort_by=Name&sort_order=ASC&category2=29&specials=1


/**
 * Add a button that adds color-coded discount percentages to Steam's search results.
 *
 * Not wanting to figure out how to react to page changes like they happen with Steam's
 * search results I decided to add a button to the search page that enhances the price
 * data with the discount percentage and color-codes it for easy reference.
 *
 * The simple HTML button is added to the top left of the Firefox screen space thus not
 * moving when the page is scrolled. Click the button to update discount percentages
 * after the page has updated which usually happens when scrolling to the bottom.
 *
 * See color codes below.
 *
 * @author valentin dauth
 * @version 2014-09-01
 */

/**
 * Colors corresponding to percentage p of deal:
 * p in [0,49]: #b0aeac Light grey (Steam default)
 *     (49,64]: #FF4500 Orange red
 *     (64,74]: #FFFF00 Yellow
 *     (74,79]: #00FF00 Lime (was #00FFFF Aqua)
 *     (79,89]: #00FFFF Aqua (was #0000FF Blue)
 *    (89,100]: #8B008B Dark Magenta
 *
 * @param {number} percentage The discount percentage.
 * @return {string} Hexadecimal color code for given percentage.
 * @see http://www.w3schools.com/tags/ref_colornames.asp
 */
var percentageColors = {'49':'#FF4500','64':'#FFFF00','74':'#00FF00','79':'#00FFFF','89':'#8B008B'};
function getPercentageColor(percentage) {
 var color = '#b0aeac';
 for (c in percentageColors){
   if ( percentage>c ) {
   color=percentageColors[c];
  };
 };
 return color;
};

/**
 * Find prices on the steam search page and calculate percentage of deal.
 * Then color-code percentage and add it to the price data.
 * Also change styles to make room for the percentage.
 */
function addColoredPercentages(){
 var prices = document.querySelectorAll("div.search_price");
 var hiLoPrices,percentage,color,percentageSpan,text;
 for (var p=0;p%lt;prices.length;p++) {
  hiLoPrices = prices[p].textContent.replace(/[€$£]/g,'').replace(',','.','g').trim().split(' ');
  // Asserting situation.
  if ( !prices[p].style || // Skip non-HTML-tag
   prices[p].getElementsByTagName("strike").length==0 || // No struck-out price, no deal
   prices[p].textContent.indexOf('%')>=0 || // Skip previously handeled
   hiLoPrices.length<2 ) {  // Skip if no two prices
    continue;
  };

  // If deal, find percentage. Color percentage, default Steam text color.
  percentage = (100-parseFloat(hiLoPrices[1])/parseFloat(hiLoPrices[0])*100).toFixed(1);
  color = getPercentageColor(percentage);
  
  // Add information to page.
  prices[p].style.marginTop = "5px"; // Make space for percentage
  percentageSpan = document.createElement('span');
  percentageSpan.style.color = color;
  text = document.createTextNode(percentage+'%');
  percentageSpan.appendChild(text);
  prices[p].appendChild(percentageSpan);
 };
};

/**
 * Create button fixed to screen as opposed to page, clicking displays 
 * colored percentages.
 */
function createButton(){
 var button = document.createElement('button');
 button.id = 'getPercentageButton';
 button.style.cssText += "position:fixed;top:5px;left:5px";
 var text = document.createTextNode('%');
 button.appendChild(text);
 document.getElementsByTagName('body')[0].appendChild(button);
 document.getElementById("getPercentageButton").onclick = addColoredPercentages;
 
};

// MAIN: Execute creation of button.
createButton();
 

English

Motivation

Having no time at the moment to actually play games, I still draw a bit of energy from simply buying games on Steam. I almost exclusively buy discounted games and so I often peruse Steam's search page. Discounted games are displayed with two prices there, one being the struck-out standard price and one being the discounted price. But which discounts are actually a good deal?

A discount of 50% or less is relatively often seen for most of Steam's games while 75% and more for those game one is interested in are rather rare. Now the actual discount isn't displayed in search results thus requiring the user to process both displayed prices one of which is also made harder to read. All this even though discount is an important hint I often use to dismiss current offers.

Now, why aren't discounts simply displayed with results? Wait, why don't I add them? That could also be useful for others.

Task

Produce a GreaseMonkey script (JavaScript) that enhances displayed items by adding discounts and colouring them for easy distinction of rare deals.
Since I didn't want to deal with loading states of a page that self-updates I decided to simply add a button to the page that would add discounts to search results.

Problems

I pieced the script together in Firebug 2.0.3 and combined it to a GreaseMonkey script (2.2). As a GM newbie I was stumped by the fact that GM doesn't propagate it's error messages to the Firebug console, so that it took me some time to realize missing functionality and even then I didn't know what the actual problem was or where it originated.
Turns out, GM posts error to the Firefox error console, accessible from within Firefox by hitting the shortcut CTRL+SHIFT+J.


The actual problem with the code resulted from Firebug console offering strip() for strings but GM doesn't. Instead GM has trim() (also available in Firebug).

GM Script

The Button

The view of the search page is enhanced by a button in the top left featuring just a percent symbol.
The button is "fixed to the screen" (style.position="fixed"), i.e. scrolling the page doesn't move the button from its position.
Clicking the button will sort of parse current search results and add the colour-coded discounts where applicable. Since scrolling to the bottom of the pagemay lead to more results being loaded the button may require additional clicks to enhance previously hidden results.
I advise to scroll to the bottom of the page until Steam is done loading all results and then clicking the button.
 
Colouring of percentages follows subjectively chosen percentage ranges.
Percentage RangeBase16 CodeColourColour Name
[0,49]#b0aeac
Light grey (Steam default)
(49,64]#FF4500
Orange red
(64,74]#FFFF00
Yellow
(74,79]#00FF00
Lime (was #00FFFF Aqua)
(79,89]#00FFFF
Aqua (was #0000FF Blue)
(89,100]#8B008B
Dark magenta
Here's an example with all colour codes:

Script

To use the script install GreaseMonkey in Firefox and using the GM menu go to script management and fit in the script given in the subsection "Skript" of the German part above.

Dienstag, 16. April 2013

Wie ich mal einen Blog erstellte

Anlaß:
Wie so oft kam die blog-Idee aus den Kreisen, in welchen man sich mit anderen Menschen aufhält, und scheiterte, was sollte man auch anderes erwarten, daran, daß die Wunschadresse schon vergeben war. Nicht genutzt, aber vergeben. Tja, in dieser Gesellschaft leben wir. Kontakt ließ sich mit dem vermuteten Inhaber auch nicht aufnehmen. Zugegeben, ich schau bisher auch nur selten bei gmail rein.
Wie dem auch sei, (for a given value of) heute wurde ich nochmal auf mein doch schon etwas zurückliegendes Vorhaben aufmerksam gemacht und ohne mich auf das Abenteuer blog letztendlich einzulassen, wollte ich diesen Start schonmal hinter mich bringen.

Grund:
Tritt man aus der Illusion des Eigenen in die reale oder digitale Welt der Anderen, ist man zwangsläufig mit Situationen und Abläufen konfrontiert, die einem absurd erscheinen müssen. Ob man nun selbst den Sinn nicht erkennen kann oder die anderen sich tatsächlich dem Unsinn ergeben haben, spielt weniger die Rolle als vielmehr die Chance, dem Fehltritt eine Weisheit oder eine ganze Geschichte zu entlocken.
Lösbare und unlösbare Fragen wie "Warum schneidet man mit der Stoffschere kein Papier?" oder "Warum rundet Python3 die Zahl 0.5 auf 0, aber 1.5 auf 2?" bringen mich zum Grübeln, Nachforschen und schließlich mal zur Erkenntnis oder mal vor Verzweiflung laut Auflachen.

Hier also nehme ich mir Platz, erfahrenes aufzuschreiben, bevor ich es zwangsläufig wieder vergesse, und daraus kurze Aufschreie oder interessante Geschichten oder auch nichts weiter werden zu lassen.

wim