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…

Ich und die…Schilddrüse

Nachdem ich mich entschlossen habe auf dieser Seite auch über privates zu schreiben, beginne nun direkt mit dem ersten Teil einer laaangen Fortsetzungsgeschichte. 😀
Es geht dabei um meine Schilddrüsen-Unterfunktion und den „etwas“ steinigen Weg bis zu dieser Diagnose. Und selbst nach der Diagnose gabs noch die ein oder andere Überraschung – und es gibt sie bis heute.

Teil 1 – Niemand weiß nix genaues.

Es ist das Jahr 2013. Ich bin Ende 20 und mir gehts so weit gut. Ein paar Kilos zu viel auf der Wage, eine Brille – das wars an gesundheitlichen „Problemen“.
Irgendwann, ich kann nicht mehr genau sagen wann und wie, fiel mir auf, dass ich Probleme mit dem Sehen bekam. Zumindest dachte ich das zu diesem Zeitpunkt noch. Irgendwie hatte ich Schwierigkeiten Dinge zu fokussieren, egal ob beim Lesen oder beim Autofahren. Das ging dann erst mal ein paar Monate so.  Irgendwann bin ich dann zum Augenarzt. „Alles in Ordnung. Nur Ihre Sehstärke passt nicht mehr ganz. Gehen Sie mal zum Optiker und lassen Sie sich eine neue Brille machen.“
Das fand ich direkt zu Beginn irritierend, weil ich schon häufiger zuvor neue Brillen gebraucht habe in meinem Leben und das hier fühlte sich irgendwie „anders“ an.
„Sei’s drum“, dachte ich mir und bin zum Optiker. Neue Brille, neue Stärke, alles klar.
Von wegen…mit der neuen Brille fühlte sich alles noch seltsamer an. „Da gewöhnen Sie sich dran.“ hieß es vom Optiker. „Das passiert oft bei neuen Stärken.“ Mhm…wie gesagt…ich hatte schon mehrere „neue“ Stärken erlebt und das hier war definitiv was anderes. Aber wer weiß? Vielleicht war diesmal nur der Sprung größer und ich gewöhne mich wirklich noch daran?
Nun, ich verrate nicht zu viel, wenn ich sage: Ich habe mich NICHT dran gewöhnt…im Gegenteil.
Aber dazu mehr im nächsten Teil. 😉

Old School Schlager!

Ich hör‘ ja nun nahezu jede Art von Musik und ja auch Schlager. Neben „Malle-Party-Schlager“ auch klassischen Schlager. Von 195X bis heute…

Ich gebe auch nur noch exakt NULL FUCKS was die Meinung des Rests der Menschheit dazu anbelangt.

Daher kommt hier nun eine Liste mit richtig geilem Shit aus der Mottenkiste meines Schlager-Ordners auf der Festplatte.
Die Liste ist komplett random. hf

Caterina Valente – Wo Meine Sonne Scheint
Frank Farian – Rocky (Was wird aus Jenny?)
Freddy Quinn – Die Gitarre Und Das Meer
Nino de Angelo – Jenseits von Eden
Nina und Mike – Fahrende Musikanten
Peter Alexander – Schwarzes Gold
Peter Cornelius – Du entschuldige
Peter Orloff – Königen der Nacht
Roger Whittaker – Albany
Tommy Steiner – Die Fischer von San Juan
Volker Lechtenbrink – Ich mag