Payback-Punkte auszahlen lassen

Jaja…Datenschutz…Payback ist der Teufel…whatever.
Und die Sachen im Prämienshop sind überteuerter Crap…gut…DAS stimmt allerdings. 😀

Aber: Wusstest ihr schon, dass man sich gesammelte Payback-Punkte auch auf sein ganz normales Girokonto auszahlen lassen kann?
Geht ganz simpel. Einfach diesen Link aufrufen, IBAN angeben. Fertig.

Die Punkte werden dann in Euro umgerechnet (1 Payback-Punkt = 0,01€) und binnen 7 Tagen auf euer Konto überwiesen.
Einzige kleine Einschränkung: Es müssen hierbei mindesten 200 Payback-Punkte „ausgezahlt“ werden.

Konservativ-liberal zu sein nervt.

Die Geschichte um #Artikel 13 unter Federführung von CDU-Mann Axel „Ich habe mehr Follower als du“ Voss, hat mir mal wieder gezeigt, dass es keine passende Partei für mich gibt.
Mein Problem ist, dass ich zu spezifischen politischen Themen, sehr spezifische Standpunkte habe, die in Summe nicht zueinander zu passen zu scheinen.
Ich betrachte mich als „wertkonservativ“. Ich mag zB Traditionen und Brauchtum und ja, ich mag auch Deutschland (auch wenn ich die Formulierung für relativ platt halte). Ich vertrete die Meinung, dass Menschen, die in dieses Land kommen, sich den Gepflogenheiten hier anzupassen haben – und nicht umgekehrt.
Andererseits bin ich Nerd. Ich mag Technik und Fortschritt. Ich liebe Popkultur und alles was dazu gehört. Konservative Parteien machen sich gerade bei solchen Themen aber regelmäßig lächerlich.
Ich bin für einen „starken Staat“, der Recht und Gesetz auch durchsetzt.
Ich bin auf den einzelnen Bürger bezogen aber wiederum sehr liberal. Ich glaube fest daran, dass jeder sein Leben so leben soll, wie er es mag. Dass jeder jeden lieben oder heiraten soll, wen er mag und das jeder „rumlaufen“ soll, wie er mag.
Ich mag Natur, Landschaftlich und Tiere, aber ich hasse die Grünen und diese ganze politische Ecke, weil sie ihr ideologisches Eigeninteresse viel zu oft über rationale Lösungsmöglichkeiten hinweg erheben.
Ich bin für eine liberale Wirtschaftspolitik, aber auf Basis des Prinzips einer sozialen Marktwirtschaft.
Ich bin gegen den Atomausstieg, weil ich nur so eine kleine Restchance sehe etwaige Klimaziele, Versorgungssicherheit und Preisgestaltung unter einen Hut zu kriegen. Ich bin für ein gesamteuropäisches Energie-Konzept, ohne ideologisch motivierte, nationale Alleingänge.
Ich bin gegen Tempolimit und Fahrverbote, aber für ein sinnvolles Gesamt-Verkehrskonzept, welches Alternativen zum „Autofahren“ attraktiver macht als heute, ohne das Autofahren dabei zwanghaft unattraktiv zu machen.
Ich erwarte von einem Land wie Deutschland, dass es hier flächendeckend schnelles Internet gibt, das es sich für Meinungs- und Kunstfreiheit einsetzt (online wie offline) und das es versucht einen positiven Einfluss in der Welt zu nehmen, ohne dass es sich dabei ein ums andere Mal als moralisch überlegene Instanz aufspielen muss.
Ich bin großer Fan der „europäischen Idee“, aber längst kein Fan (mehr) der EU.

Diese Liste ließe sich noch nahezu beliebig fortsetzen.
Und wen soll ich jetzt wählen?
Eben.

Trolled by Telekom. Again.

Die Telekom und mich verbindet eine seit Jahren andauernde Feindschaft.
Zurück geht das Ganze auf die frühen „Nuller-Jahre“ des neuen Jahrtausends, wo sich der quasi Monopolist geweigert hatte DSL beim Haus meiner Eltern zu schalten, obwohl es schon damals technisch möglich gewesen wäre. Aber da man ja grundsätzlich nur an Ignoranten oder Honks gerät, wenn man versucht mit diesem Laden zu kommunizieren, endete die Geschichte seinerzeit mit einem Rauswurf aus dem T-Punkt. 😀

Nun…wie dem auch sei, irgendwann wurde DSL dann doch geschaltet (oh Wunder) und der Speed steigert sich im Laufe der Jahre von „DSL Light“ über dann 150 kb/s und einige Aufs uns Abs auf nun 45MBit.
What a time to be alive! – 45MBit im Hochtechnologieland Deutschland!

Nun hat die Telekom zu ihrem neusten Troll-Move ausgeholt.
In der Gegend wurde VDSL mit bis zu 250MBit ausgebaut. Die Verfügbarkeit endet allerdings EXAKT neben meinem Haus. Das direkte Nachbarhaus kann diesen Tarif bestellen und bekommen, ich aber nicht.
Komisch nur, dass beide Häuser am selben Kabel hängen. Das weiß ich so genau, weil ich genau das schon damals, bei meinem ersten „Krieg“ gegen T-Offline herausgefunden hatte.
Diesen Umstand versuche ich nun gegenüber der Telekom zu kommunizieren – natürlich bisher erfolglos über die Hotline
…Doch schon bald werde ich in „meinen“ geliebten T-Punkt zurückkehren und es erneut versuchen. Genau so wie damals, vor fast 20 Jahren schon mal…

RBTV Forum – User mute/ignore

Hier nun ein kleines Script, welches es ermöglicht User im Rocketbeans-Forum zu „muten“.
Das Script basiert auf einer Version dieser Vorlage.
Ich weise rein obligatorisch darauf hin, dass ich keinerlei Verantwortung für die Nutzung des Scripts übernehme.

Anleitung

Download und Installation von Tampermonkey
(Achtung: Greasemonkey funktioniert zB NICHT!)

Firefox:
https://addons.mozilla.org/de/firefox/addon/tampermonkey/

Chrome (ungetestet):
https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=de

Dann ein neues Script erstellen:

1.png

Dort folgenden Code einfügen:

// ==UserScript==
// @name        rbtv_user_mute
// @namespace   someName
// @include     https://forum.rocketbeans.tv/*
// @version     0.2
// @grant       none
// ==/UserScript==

/*
* Hides user on discourse software.
* Known bugs:
*  - After a click on the "replied to" button (top right) the post is made visible again.
*/

/*
* Patch for GM_getValue and GM_SetValue support for chrome
* credits to: www.devign.me/greasemonkey-gm_getvaluegm_setvalue-functions-for-google-chrome/
*/
if (!this.GM_getValue || (this.GM_getValue.toString && this.GM_getValue.toString().indexOf("not supported")>-1)) {
    this.GM_getValue=function (key,def) {
        return localStorage[key] || def;
    };
    this.GM_setValue=function (key,value) {
        return localStorage[key]=value;
    };
    this.GM_deleteValue=function (key) {
        return delete localStorage[key];
    };
}

$(document).ready(function(){
  // After how long we try to update the user name. (Only relevant for the settings UI)
  var GET_USER_DATA_AFTER = 60*60;
  // Hide the full post like it was never there.
  var HIDE_FULL_POST = false;
  var HIDE_AVATAR = true;
  var HIDE_NAME = false;
  // Ad a butotn to hidden posts (if HIDE_FULL_POST == false) to temporary show the post.
  var ADD_TMP_SHOW_BUTTON = true;
  // Icons to use
  var ICON_MUTE = "fa-microphone-slash";
  var ICON_UNMUTE = "fa-microphone";
  var ICON_TMP_SHOW = "fa-eye";
  var ICON_TMP_HIDE = "fa-eye-slash";
  // Styles to use for the buttons
  var BTN_STYLE = "background: none; font-size: 1.3em; vertical-align:top; border:none;";
  var GR_COOKIE_NAME = 'rbtv_user_mute';

  var hide_ids = $.parseJSON(GM_getValue(GR_COOKIE_NAME, '{}'));

  function gen_prefixed_css(data, prefixes, values){
     // ahhhhhh
    var ret = "";
    for(i=0; i<prefixes.length; ++i){
      var tmp = data;
      for(j=0; j<values.length; ++j){
        // js... why is everything so complicated ?
        tmp = tmp.split(values[j]).join(prefixes[i]);
      }
      ret += tmp;
    }
    return ret;
  }
  // inject CSS "MutationObserver" (see http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/)
  var css = document.createElement('style');
  css.type = 'text/css';
  document.body.appendChild(css);
  css.innerHTML = gen_prefixed_css("@keyframes nodeInserted { from {outline-color: #fff} to {outline-color: #000} }\n", ['keyframes', '-webkit-keyframes'], ['keyframes']) +
    "article[data-user-id] {" +
    gen_prefixed_css("animation: nodeInserted 0.01s;\n", ['animation', '-webkit-animation'], ['animation']) +
    "}\n";
  console.log(css.innerHTML);
  document.addEventListener('animationstart', handle_post, true);
  document.addEventListener('mozAnimationstart', handle_post, true);
  document.addEventListener('webkitAnimationstart', handle_post, true);

  function hide_post(article){
    if(HIDE_FULL_POST){
      article.parentNode.style.display = "none";
      return;
    }
    article = $(article);
    if(HIDE_AVATAR) article.find('.topic-avatar').css('visibility', 'hidden');
    if(HIDE_NAME) article.find('.names').hide();
    article.find('.contents').hide();
    article.find('.mute_btn').attr('title', 'Stummschaltung aufheben.').find('i').removeClass(ICON_MUTE).addClass(ICON_UNMUTE);
    if(ADD_TMP_SHOW_BUTTON) article.find('.show_post_btn').show();
  }

  function unhide_post(article){
    article = $(article);
    article.find('.topic-avatar').css('visibility', 'visible');
    article.find('.names, .contents').show();
    article.find('.mute_btn').attr('title', 'User stumm schalten.').find('i').removeClass(ICON_UNMUTE).addClass(ICON_MUTE);
    if(ADD_TMP_SHOW_BUTTON) article.find('.show_post_btn').attr('title', "Show post.").hide();
  }

  function handle_post(event){
    if (event.animationName != 'nodeInserted') return;
    var post = event.target;
    var user_id = parseInt(post.getAttribute('data-user-id'));
    var _btn_title = "User stumm schalten.";
    var _btn_class = ICON_MUTE;
    if(hide_ids[user_id]){
      var user_name = $(post).find('.username a').text();
      // Update our cached names.
      if(! $.isArray(hide_ids[user_id]) || hide_ids[user_id][0] != user_name){
        console.log("Update username for", user_id, user_name);
        hide_ids = $.parseJSON(GM_getValue(GR_COOKIE_NAME, '{}')); // in case another tab changed it
        hide_ids[user_id] = [user_name, new Date().getTime() / 1000];
        GM_setValue(GR_COOKIE_NAME, JSON.stringify(hide_ids));
      }
      if(HIDE_FULL_POST){
        hide_post(post);
        return;
      }
      _btn_title = "Stummschaltung aufheben."
      _btn_class = ICON_UNMUTE;

    }
    // Add buttons
    var node = $(post);
    if(node.find('.mute_btn').length > 0) return;
    var btn = $('<button title="'+_btn_title+'" style="'+BTN_STYLE+'" class="mute_btn"><i class="fa '+_btn_class+'"></i></button>');
    btn.insertBefore(node.find('.post-date').last());
    if(ADD_TMP_SHOW_BUTTON){
      var btn_tmp = $('<button title="Show post." style="display:none; '+BTN_STYLE+'" class="show_post_btn"><i class="fa '+ICON_TMP_SHOW+'"></i></button>');
      btn_tmp.click(function(){
        if(this.title == "Show post."){ // dirty
          node.find('.contents').show()
          this.title = "Hide post.";
          btn_tmp.find('i').removeClass(ICON_TMP_SHOW).addClass(ICON_TMP_HIDE);
        }else{
          node.find('.contents').hide()
          this.title = "Show post.";
          btn_tmp.find('i').removeClass(ICON_TMP_HIDE).addClass(ICON_TMP_SHOW);
        }
      });
      btn_tmp.insertBefore(btn);
    }
    btn.click(on_mute_user);
    if(hide_ids[user_id])hide_post(post);
  }

  function on_mute_user(evt){
    var article = $(this).parents('article');
    // We don't handle the case of multiple authors of a post (wiki).
    var username = article.find('.username a').text();
    var user_id = parseInt(article[0].getAttribute('data-user-id'));
    var _question = "Mute ";
    var _func = hide_post;
    if(hide_ids[user_id]){
      _question = "Stummschaltung aufheben ";
      _func = unhide_post;
    }
    if (confirm(_question + username + " ?")){
     hide_ids = $.parseJSON(GM_getValue(GR_COOKIE_NAME, '{}')) // in case another tab changed it
     if(hide_ids[user_id]) delete hide_ids[user_id];
     else hide_ids[user_id] = [username, new Date().getTime() / 1000];
     GM_setValue(GR_COOKIE_NAME, JSON.stringify(hide_ids));
     jumpToPost(article[0].getAttribute('data-post-id'));
     $('article[data-user-id="'+user_id+'"]').each(function(_,a){_func(a)});
    }
    return false;
  }

  function jumpToPost(postid){
    var topic = Discourse.__container__.lookup('controller:topic');
    topic._jumpToPostId(postid);
  }
  /*
  * UI stuff follows
  */
  Discourse.PageTracker.current().on('change', function(url){
    setup_settings_ui();
  });
  function _lookup_user(user_id, user, cb){
    // TODO: Does the store cache data ? Or is there some user cache somewhere we can use ?
    var user_id = user_id;
    var user_name = user[0];
    if(user_name.length == 0){
      cb(user_id, "", -1, false);
      return false;
    }
    var age = (new Date().getTime() / 1000) - user[1];
    if(age <= GET_USER_DATA_AFTER){
      cb(user_id, user_name, age, true);
      return;
    }
    var store = Discourse.__container__.lookup('store:main');
    a = store.find('user', user_name).catch(function(){
      // Prevent error report from being generated
      console.log('lookup_user', user_id, "Invalid username");
      // TODO: we could search the first x pages of the user endpoint
      // to see if we find the user.
      cb(user_id, user_name, age, false);
    }).then(function(data){
      if(data.id === user_id){
        cb(user_id, user_name, 0, true);
        return;
      }
      cb(user_id, user_name, age, false);
    });
  }

  function setup_settings_ui(){
    if(!window.location.pathname.match('/preferences(/account/?)?$') ) {
      return;
    }
    var settings_pane = $('.pref_cfg_mute_user');
    var blocked_count = Object.keys(hide_ids).length;
    var box;
    if(settings_pane.length > 0){
      settings_pane.attr('data-user-count', blocked_count).find('select').html("");
      box = settings_pane.find('select');
    }else{
      settings_pane = $('<div class="pref_cfg_mute_user control-group" data-user-count="'+blocked_count+'"></div>');
      settings_pane.insertBefore($('.save-button').last());
      box = $('<select size="5"></select>');
      var btn_del = $('<button class"btn-secondary btn ember-view">Unhide</button>');
      var btn_import = $('<button class"btn-secondary btn ember-view">Import</button>');
      var btn_export = $('<button class"btn-secondary btn ember-view">Export</button>');
      settings_pane.append('<label class="control-label">Muted user</label>');
      settings_pane.append(btn_import, btn_export, '</br>', box, '</br>', btn_del);
      btn_import.click(on_import);
      btn_export.click(function(){
        hide_ids = $.parseJSON(GM_getValue(GR_COOKIE_NAME, '{}')) // in case another tab changed it
        var data = JSON.stringify(hide_ids);
        prompt("Select all and copy the data:", data);
        return false;
      });
      btn_del.click(function(){
        var selected = box.val();
        if(selected != -1){
          selected = parseInt(selected);
          var option = box.find('option:selected');
          if (confirm("Unmute " + option.text())){
            hide_ids = $.parseJSON(GM_getValue(GR_COOKIE_NAME, '{}')) // in case another tab changed it
            delete hide_ids[selected];
            GM_setValue(GR_COOKIE_NAME, JSON.stringify(hide_ids));
            option.remove();
          }
        }
        return false;
      });
    }
    hide_ids = $.parseJSON(GM_getValue(GR_COOKIE_NAME, '{}')) // in case another tab changed it
    for(var i in hide_ids){
      i = parseInt(i);
      if(! $.isArray(hide_ids[i])){
        hide_ids[i] = ["", new Date().getTime() / 1000]
      }
      var option = $('<option value="'+i+'">Loading info</option>');
      box.append(option);
      _lookup_user(i, hide_ids[i], function(user_id, user_name, age, success){
        var now = new Date().getTime() / 1000;
        hide_ids[user_id] = [user_name, now-age];
        GM_setValue(GR_COOKIE_NAME, JSON.stringify(hide_ids));
        option = box.find('option[value="'+user_id+'"]');
        if(!success){
          option.text("User id: " + user_id);
          // TODO: Ask if we should crawl the first x userpages via the API to find the username.
          last_seen = age >= 60*60 ? parseInt(age/60/60) + " hours ago" : parseInt(age/60) + " minutes ago";
          if(user_name.length) last_seen += " as user " + user_name;
          option.css('color', 'red').attr('title', "Couldn't find username.\nLast seen "+last_seen+".\nSimply continuing to browse might fix this.");
        }else{
          option.text(user_name);
        }
      });
    }
  }

  function on_import(){
    hide_ids = $.parseJSON(GM_getValue(GR_COOKIE_NAME, '{}')) // in case another tab changed it
    var data = prompt("Paste your exported data:");
    if(!data || data.length < 5) return false;
    var data = $.parseJSON(data);
    for(var i in data){
      i = parseInt(i);
      if(data.hasOwnProperty(i)){
        var old_data = hide_ids[i];
        if(!old_data)
          hide_ids[i] = data[i];
        else{
          if( !$.isArray(data[i]) || old_data[1] >= data[i][1] )
            hide_ids[i] = old_data;
          else
            hide_ids[i] = data[i];
        }
      }
    }
    GM_setValue(GR_COOKIE_NAME, JSON.stringify(hide_ids));
    setup_settings_ui();
    return false;
  }
});

Speichern.

Wenn alles geklappt hat, dann solltet ihr bei nächsten Aufruf des Forums das sehen:

2.png

Ihr könnt User nun innerhalb eines Threads durch Klick auf das durchgestrichene Mikrofon forenweit muten.

3.png

Die Beiträge des entsprechenden Users werden nun nicht mehr angezeigt.

4.png

Ein Klick auf das Auge zeigt einen einzelnen Beitrag an, ein Klick auf das Mikrofon hebt die Stummschaltung des Users komplett auf.

Ich und die…Schilddrüse

Teil 2 – Es ist Krebs!

Wie schon angedeutet: Die Sache mit den Sehstörungen wurde nicht besser…
Irgendwie wurde es sogar immer schlimmer. Ich war mega unkonzentriert, habe Sachen umgestoßen die rumstanden…es fühlte sich an, wie als ob man ca. 5 Bier intus hätte. Man KANN zwar irgendwie noch alles machen, aber man muss sich schon sehr darauf konzentrieren.
Beim Autofahren hatte ich manchmal das Gefühl gar nichts mehr um mich rum wahrzunehmen und fast einzuschlafen…auch eher so suboptimal, wenn man ein Fahrzeug führt.

Jedenfalls wurde es mir zu bunt. Ich habe mich also zum Hausarzt gekrüppelt. Dort alles geschildert und hin und her und dann meinte der so: „Hm das gefällt mir alles nicht so wirklich. Da müssen wir mal ein MRT vom Kopf machen…nicht das da irgendwas ist.“
-.-
Als medizinisch-interessierter Laie wusste ich natürlich sofort was der meinte: Hirntumor!!
So was will man natürlich NICHT hören. Ich also panisch versucht einen MRT-Termin zu bekommen… „Jaaaaa…dauert 3 Monate.“
Ähm….Verzeihung…aber so eine Wartezeit kann irgendwie nicht sinnvoll sein bei einem Verdacht auf einen Hirntumor.
“ „Jaaaaa…es dauert trotzdem 3 Monate.“

Gut…in den drei Monaten hatte ich so mittelmäßig viel Spaß am Leben.
Was das MRT für bahnbrechende Erkenntnisse brachte, das erfahren wir im nächsten Teil.
Spoiler: GAR KEINE!!

Ich bin ein schlechter Mensch.

(vielleicht)

Als Standard-Konsum-Opfer habe ich natürlich AmazonPrime. Und auch wenn die Qualität der Lieferungen durch den neuen hauseigenen Zustelldienst „AmazonLogistics“ ein mitunter lächerlich schlechtes Niveau erreicht hat, ist das Gesamtpaket „Prime“ in meinen Augen immer noch attraktiv.

Nun bekommt man im Rahmen von Prime ja auch einen „Gratis Twitch-Sub“ pro Monat. Den hat natürlich bisher safe RBTV von mir bekommen.
Allerdings geht dies nun nicht mehr, weil Twitch bzw. letztlich wohl Amazon dahinter „aus Gründen“ nur noch Subs für Twitch-exklusive Streams zulässt – und das ist RBTV nun mal nicht. Naja. Schade.

Es stellt sich nun also die Frage, wer bekommt meinen gratis Twitch-Sub?
Die Antwort: Niemand. (Bisher).
Nun gibt es sicherlich genügend Streamer und Projekte, die ich im Prinzip gut finde und die eine Unterstützung verdient hätten. Bonjwa, Hauke, Lara, ganz viele RBTVler und Ex-RBTVler und noch viele mehr.
Und jetzt kommt meine Portion Wahnsinn ins Spiel: Ich mag die zwar alle, ich möchte aber eigentlich nicht, dass die (zu) erfolgreich werden mit ihren Kanälen. Oo
Warum? Weil ich die eigentlich lieber alle bei RBTV sehen würde.
Ja, auch Bonjwa, wobei zu dem Thema irgendwann nochmal ein eigener Artikel kommt.

Nun sitze ich also auf meinem Twitch-Sub und wünsche all den Streamern nur das Beste, behalte meinen Sub aber, weil ich die lieber alle „zentral“ bei RBTV hätte und nicht auf ihren eigenen Kanälen.

Ist das sehr böse?
Ich weiß es doch auch nicht…