// ==UserScript==
// @name heise
// @namespace heise
// @include https://www.heise.de/*
// @include https://heise.de/*
// @version 1.3
// @author Torsten Tränkner
// @grant GM_xmlhttpRequest
// @grant GM_log
// ==/UserScript==
// last update: 2018-03-24
// global counter to know that all files were downloaded
var downloadCounter = 0;
// number of files that need to be downloaded to get all ratings
var numberOfFilesToDownload = 0;
// string with downloaded ratings
var globalRatingsString = "";
// an array with rating that shall be downloaded
var loadedRatings = {};
// map of positive and negative ratings for the news
var ratingsPerNews = {};
// ratings of 10000 news stored in one file
var CLUSTER_SIZE = 10000;
/**
* insert a new HTML element after a reference node
*/
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode,
referenceNode.nextSibling);
}
/**
* Prepare an array with ratings that shall be downloaded.
*/
function prepareRatingsToDownload(webpage_id, object) {
// webpage ids are collected in bigger files (cluster)
// so that only a few files are loaded
webpage_filename = webpage_id - (webpage_id % CLUSTER_SIZE);
// check if already loaded
if (! (webpage_filename in loadedRatings)) {
loadedRatings[webpage_filename] = webpage_filename;
numberOfFilesToDownload++;
}
}
/**
* Scan through all news links and pass the link to an inner function.
*
* innerFunction - can be "prepareRatingsToDownload" or "addRating" to the news
*/
function scanLinks(innerFunction) {
var objects = document.evaluate(
"//a[contains(@href, '/meldung/')]", document, null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < objects.snapshotLength; i++) {
news_link = objects.snapshotItem(i);
// the news number / webpage id has 7 digits and is written before ".html"
// e.g. -1234567.html
if (news_link.href.match(/.*\/meldung\/.*-[0-9]{7}\.html.*/)) {
// filter the news id from the URL
var regular_expression = /.*-([0-9]{7})\.html.*/g;
var match = regular_expression.exec(news_link.href);
var webpage_id = match[1];
// pass it to the inner function
innerFunction(webpage_id, news_link);
}
}
}
/**
* Adds the rating below the news block as colored HTML div bar.
*
* webpage_id - the number of the news
* news_link - the link / HTML block of the news message
*/
function addRating(webpage_id, news_link) {
like = 0;
dislike = 0;
if (webpage_id in ratingsPerNews) {
rating = ratingsPerNews[webpage_id].split(",");
like = parseInt(rating[0]);
dislike = parseInt(rating[1]);
}
var newDiv = document.createElement("div");
sum = like + dislike;
// alert("sum: " + sum + " " + like);
// display a rating bar below the news link
if (sum != 0) {
positivePercentage = (like * 100) / sum;
// display a green and a red bar for the ratings
newDiv.innerHTML =
// red bar at the right side
"
" +
// green bar at the left side
"
" +
"" +
// show the numbers of the ratings below the bar
like + "
" +
dislike + "
";
} else {
// a yellow bar to indicate the news has not been rated
newDiv.innerHTML = "";
}
newDiv.style.width = "100%";
insertAfter(newDiv, news_link);
}
/**
* Display the ratings in HTML
*/
function displayRatings() {
// alert("displayRatings:\n" + globalRatingsString);
var lines = globalRatingsString.split("\n");
for (index = 0; index < lines.length - 1; ++index) {
singleWords = lines[index].split(" ");
// add positive and negative ratings to a map
ratingsPerNews[singleWords[0]] = singleWords[1] + "," + singleWords[2];
}
// go through all links and add the rating below
scanLinks(addRating);
}
/**
* Load the files that contain the ratings.
*/
function loadRatings(webpage_filename) {
// this is the server where to download the ratings
url = "https://www.torsten-traenkner.de/bewertungen/get.php?id=" + webpage_filename;
GM_xmlhttpRequest({
method: "GET",
url: url,
timeout: 7000,
onload: function(response) {
// alert("loaded");
loaded = false
if ((response.readyState == 4) && (response.status == 200)) {
globalRatingsString = globalRatingsString + response.responseText;
}
downloadCounter++;
if (downloadCounter == numberOfFilesToDownload) {
displayRatings();
}
},
onerror: function(response) {
alert("Download of ratings failed: " + response);
downloadCounter++;
if (downloadCounter == numberOfFilesToDownload) {
displayRatings();
}
},
ontimeout: function(response) {
alert("Download of ratings timed out after 7 seconds.");
downloadCounter++;
if (downloadCounter == numberOfFilesToDownload) {
displayRatings();
}
}
});
}
// add a rating option to the article
if (window.location.href.match(/.*\/meldung\/.*-[0-9]{7}\.html.*/) ||
window.location.href.match(/.*\/artikel\/.*-[0-9]{7}\.html.*/))
{
// alert("URL matched");
var regular_expression = /.*\/meldung\/.*-([0-9]{7})\.html.*/g;
var match = regular_expression.exec(window.location.href);
var webpage_id = match[1];
// create iframe for the rating
var newIframe = document.createElement("iframe");
newIframe.setAttribute("src",
"https://www.torsten-traenkner.de/bewertungen/?webpage_id=" + webpage_id);
newIframe.setAttribute("scrolling", "yes");
newIframe.style.border = "1px solid black";
newIframe.style.width = "500px";
newIframe.style.height = "400px";
var objects = document.evaluate(
"//*[@class='beitragsfooter']", document, null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var firstObject = objects.snapshotItem(0);
firstObject.parentNode.insertBefore(newIframe, firstObject);
}
// show the ratings
else if ( (window.location.href.match(/heise.de[/]$/)) ||
(window.location.href.match(/heise.de\/.*[/]?seite=[0-9]*$/)) ||
(window.location.href.match(/heise.de\/thema\/[^/]*$/)) ||
(window.location.href.match(/heise.de\/.*[/]$/)) )
{
// alert("heise");
// scan through all links and prepare the download of the ratings
scanLinks(prepareRatingsToDownload);
for (var key in loadedRatings) {
if (loadedRatings.hasOwnProperty(key)) {
// load ratings and display them if all ratings are downloaded
loadRatings(key);
}
}
}