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.

Keine Kommentare:

Kommentar veröffentlichen