Endlich habe ich da eine Lösung für 3 Funktionen, die ich schon lange bei GMail vermisse!

Boomerang ist eine Erweiterung für Chrome und Firefox und Google Mail User werden sie lieben!
Leider gibt es 2 Voraussetzungen: Google Mail muss auf englisch eingestellt sein. Und man muss einmalig (bei der ersten Aktion mit Boomerang) den Zugriff des Dienstes auf das eigene GMail Konto zulassen.
Dann kann es losgehen.

Was bietet Boomerang?

Ich zeige hier die 3 von mir heiß ersehnten Features. Boomerang kann sicher noch ein wenig mehr, schaut dazu auf die Homepage.

Emails später versenden

Das ist überhaupt die beste Funktion! Boomerang fügt in GMail einen „Send Later“ Button ein.
Dieser ermöglicht das Absenden einer Mail zu einem fest definierten Zeitpunkt, X Stunden/Tage später oder zu einem zufälligen Zeitpunkt.
Die Angabe eines ganz bestimmten Zeitpunktes sollte am interessantestens sein und ist einfach und verständlich gemacht. Die Handhabung der Funktion ist also ein Kinderspiel.
Getestet, works!

Emails später nochmal empfangen

Wie oft habe ich mir überlegt wie ich Mails, die in meinem Posteingang immer weiter nach unten rutschen, wieder nach oben holen kann. Bei 20-40 Mails am Tag verschwindet eine bestimmte Mail in kürzester Zeit aus dem Blickfeld des Posteingangs. Man kann sie labeln, mit Sternchen markieren aber im Posteingang wieder nach oben holen, den aktuellen Zeitstempel aufdrücken, das geht nicht.
„Return to inbox“ also, die Funktion ist jetzt gegeben und ist ein Traum.
Wie bei „Send Later“ wählt man bei empfangenen Mails aus, wann diese Nachricht nochmal in den Posteingang flattern soll.

Emails nochmal empfangen wenn […]

Ist praktisch das Gleiche wie der vorherige Punkt, allerdings ist die Funktion beim Versenden möglich. Mails werden nochmal nach oben geholt wenn entweder keine Antwort auf diese Mail kommt oder selbst wenn eine eintrifft. Finde ich sehr praktisch wenn ich auf wichtige Mails innerhalb von 1, 2 Wochen eine Antwort erwarte und die dann aus dem Blickfeld verschwinden nach 2, 3 Tagen. So werde ich 100%ig erinnert nach einer oder zwei Wochen wenn keine Antwort kam.


Fazit: Also Leute, ein Traum. Das Plugin wird hoffentlich iirgendwann mal auch auf das deutsche Google Mail eingestellt, bis dahin ist das für mich ein verträgliches Opfer für diese wunderbaren Funktionen.

Sooo, gestern ist mein aktuelles Gewinnspiel abgelaufen und ich habe die Gewinner direkt ermittelt. Es gibt 2 Gewinner für die 2 angekündigten Gewinne: die Tastatur und die DVD.
Es gab 17 Teilnehmer, davon 2 mit doppelter Gewinnchance. Rein in die Random.org Liste, rütteln, schütteln und die Gewinner siiiind:

1. Michael – Tastatur
2. Catrin – DVD

So ihr Beiden, Adresse zu mir und dann kommt bald Post 😉

Ich danke euch allen für die vielen Tipps, Meinungen und so, das wird mir bei der Vollendung des Designs sehr helfen. Bis das Design mit dem neuen Namen online geht wird aber wahrscheinlich ein wenig Zeit vergehen. Einige private Zeitfresser kommen mir momentan in den Weg. Aber es eilt ja nicht.

Bis dahin!

Ich kam letztens einfach nicht umher meinen alten C# Ordner zu durchstöbern. Ich hatte mich damals wenige Wochen mit C# beschäftigt. Also beschäftigt im Sinne von: Einsteigerkurse in der S-Bahn lesen, paar Tutorials im Netz und los gehts 😀
Ein Projekt hatte ich damals tatsächlich realisieren wollen. Ein kleines Programm, mit dem ich eine kleine Investition rechtfertigen und strategisch präsentieren konnte.
Damals wollte ich mir nämlich einen Kaffeevollautomaten kaufen, der gerade im Angebot war. Solch ein Gerät ist ja nicht gerade günstig, also habe ich die Ersparnisse, die mit so einem Gerät möglich sind, versucht einfach zu verdeutlichen.

Und somit, let me proudly introduce to you:

Kaffe-Kalkulator

DIE Rechtfertigung, wenn es um den Kauf eines Kaffeevollautomaten geht!

Der Sinn dieser Software ist einfach: sie soll die Rechenarbeit bei der Frage „Lohnt sich der Kauf eines Kaffeevollautomaten?“ für euch erledigen.
Das Programm fragt nach einigen Grundangaben aus denen dann ein kurzer Infotext gebastelt wird.

Simple thing, huh?! 🙂

Wie gesagt war das ein recht kurzer Abstecher in die C# Welt, der Code ist jetzt also nicht sonderlich cool.
Ich habe mich gestern und heute kurz damit beschäftigt und den Code stark gereinigt und umgeschrieben, Funktionen geschrieben, Fehler abgefangen, Code gekürzt und sowas. Aber mittlerweile würde ich einige Schritte anders realisieren (Stichwort „.“ bei Kaffeebohnenpreis und MaskedTextBoxes) und würde auch einige andere Details ändern (z.B. variabler durchschnittlicher Verbrauch von Kaffeebohnen pro Tasse (ist ja je nach Tassengröße unterschiedlich)) aber wichtig ist das alles nicht. Dazu müsste das Programm grundlegend umgestaltet werden und so viel Langeweile habe ich ja nun auch wieder nicht. Es funktioniert grundlegend und erfüllt seine Aufgabe mit Stolz. 🙂

Code

Code anzeigenDen Code könnt ihr bequem mit den Links/Rechts Pfeiltasten horizontal bewegen.

public partial class Main : Form
    {
        // Variablen einzeln setzen, für Kommentare
        const char nl = (char)10; // Zeilenumbruch als Konstante
        double PrUn = 0; // Preisunterschied zwischen eigenem und alternativem Kaffee
        double PrKa = 0; // Preis der eigenen Tasse
        double PrAlKa = 0; // Preis des altern. Kaffees
        double MaxKaBo = 0; // maximale Anzahl der Tassen pro voller Kaffeebohnenpackung
        double DuVeKaBo = 20; // Durchschnittlicher Kaffeebohnenverbrauch pro Tasse
        double KaAuBezWo = 0; // Anzahl an Wochen die man braucht um mit dem Preisunterschied den Kaffeevollautomaten zu bezahlen
        bool empty = true; // Felder leer?
        
        public Main() {
            InitializeComponent();
        }

        void btnBerechne_Click(object sender, EventArgs e) {
            try {
                // Setze intern berechnete Variablen zurück
                initReset(false, true);
                // GET: Preis des alternativen Kaffees
                PrAlKa = checkPrAlKa();

                if (PrAlKa == 0 || checkEmpty() == true)
                    emptyErr();
                else {
                    if (checkNegative() == true) showStats("negative");
                    else showStats("positive");
                }
            }
            catch {
                unknownErr();
            }
        }

        void negativeErr() {
            lblStatistik.Text = "Die berechnete Statistik zeigt, dass du mit deinen Angaben keinen Gewinn machen würdest. Der Kaffee deines Vollautomaten ist teurer als der Kaffee, den du dir im Laden kaufst.";
            gbxStatistik.Visible = true;
        }

        void emptyErr() {
            lblStatistik.Text = "Fehler bei der Eingabe. Es wurden nicht alle Felder ausgefüllt.";
            gbxStatistik.Visible = true;
        }

        void unknownErr() {
            lblStatistik.Text = "Ein unbekannter Fehler ist aufgetreten... sorry...\nPrüfe deine Eingaben, irgendetwas stimmt hier nicht ;)";
            gbxStatistik.Visible = true;
        }

        double checkPrAlKa() {
            switch (cbxPrAlKa.Text) {
                case "": { return 0; break; }
                case "0,50€ - Berlin Ost billig": { return 50; break; }
                case "0,80€ - Berlin West billig": { return 80; break; }
                case "1,00€ - Berlin Mitte billig": { return 100; break; }
                case "1,30€ - Berlin Mitte normal": { return 130; break; }
                case "2,00€ - Berlin Mitte teuer": { return 200; break; }
                case "3,50€ - Berlin Fucking Luxus": { return 350; break; }
                case "6,00€ - Scheiße wo trinkst du Kaffee?!": { return 600; break; }
                default: { return 0; break; }
            }
        }

        bool checkEmpty() {
            // CHECK: leere Eingaben
            if (tbxAnKaWo.Text == "" || tbxMeKaBo.Text == "" || tbxPrKaAu.Text == "" || tbxPrKaBo.Text == "")
                return true;
            else
                return false;
        }

        bool checkNegative() {
            // CALC: Preis der eigenen Tasse in Cent
            PrKa = (((double.Parse(tbxPrKaBo.Text) * 100) / double.Parse(tbxMeKaBo.Text)) * DuVeKaBo);
            // CALC: Preisunterschied zwischen eigenem und alternativem Kaffee
            PrUn = PrAlKa - PrKa;
            // CALC: maximale Anzahl der Tassen pro voller Kaffeebohnenpackung beim angegebenen Durchschnittsverbrauch pro Tasse
            MaxKaBo = Math.Round((double.Parse(tbxMeKaBo.Text) / DuVeKaBo), 1);
            // CALC: Anzahl an Wochen die man braucht um mit dem Preisunterschied den Kaffeevollautomaten zu bezahlen
            KaAuBezWo = double.Parse(tbxPrKaAu.Text) / (PrUn * double.Parse(tbxAnKaWo.Text));
            // PRINT: Preis der eigenen Tasse in €
            tbxPrTaKa.Text = Math.Round((PrKa / 100), 2).ToString();
            // PRINT: Preisunterschied zwischen eigenem und alternativem Kaffee in €
            tbxPrUn.Text = Math.Round((PrUn / 100), 2).ToString();

            if (PrUn < 0) return true;
            else return false;
        }

        void showStats(string pon) {
            if (pon == "positive") {
                // PRINT: Statistiktext
                lblStatistik.Text = tbxMeKaBo.Text
                    + "g Kaffeebohnen kosten " + tbxPrKaBo.Text
                    + " €. Für eine kleine Tasse werden " + DuVeKaBo
                    + "g Kaffeebohnen verbraucht, mit den " + tbxMeKaBo.Text
                    + "g Kaffeebohnen lassen sich also bis zu " + MaxKaBo
                    + " Tassen machen." + nl
                    + "Eine Tasse Kaffee zu Hause kostet nur " + tbxPrTaKa.Text
                    + " € ! Günstig, oder?! Und dann noch lecker Kakao drin, hhmmmm lecker." + nl
                    + "Wenn ein gekaufter Kaffee in der Stadt " + Math.Round((PrAlKa / 100), 2)
                    + " € kostet, ist ein selbstgemachter Kaffee also " + Math.Round((PrUn / 100), 2)
                    + " € günstiger!" + nl
                    + "Bei " + tbxAnKaWo.Text
                    + " Tassen Kaffee pro Woche sparst du also " +
                    // CALC: Ersparnis pro Woche: Anzahl der Tassen pro Woche * Preisunterschied in € gerundet auf 2 Stellen
                    Math.Round((double.Parse(tbxAnKaWo.Text) * Math.Round((PrUn / 100), 2)), 2)
                    + " € pro Woche, " +
                    // CALC: Ersparnis pro Monat: Anz. d. Tassen pro Woche / 7 (Ersparnis pro Tag) * 30.416 (durchschnittliche Tagesanzahl pro Monat) gerundet auf 2 Stellen
                    Math.Round(((Math.Round((double.Parse(tbxAnKaWo.Text) * Math.Round((PrUn / 100), 2)), 2) / 7) * 30.416), 2)
                    // Math.Round((double.Parse(tbxAnKaWo.Text) * Math.Round((PrUn / 100), 2) * 30.416), 2)
                    + " € pro Monat und ganze " +
                    // CALC: Ersparnis pro Jahr: Anz. d. Tassen pro Woche / 7 (Ersparnis pro Tag) * 365,25 (durchschnittliche Tagesanzahl pro Jahr) gerundet auf 2 Stellen
                    Math.Round(((Math.Round((double.Parse(tbxAnKaWo.Text) * Math.Round((PrUn / 100), 2)), 2) / 7) * 365.25), 2)
                    //Math.Round((double.Parse(tbxAnKaWo.Text) * Math.Round((PrUn / 100), 2) * 365.25), 2)
                    + " € im Jahr!!" + nl
                    + "Es erklärt sich also von selbst, dass der Kaffeevollautomat bei einem Preis von satten " + tbxPrKaAu.Text
                    + ",00 € bereits nach " +
                    //CALC: Wochen die zum Abbezahlen nötig sind: (Preis der Automats / Ersparnis pro Tag) / 7
                    Math.Round(((double.Parse(tbxPrKaAu.Text) / Math.Round(((Math.Round((double.Parse(tbxAnKaWo.Text) * Math.Round((PrUn / 100), 2)), 2) / 7)), 2)) / 7), 1)
                    + " Wochen abbezahlt ist!" + nl
                    + "Danach sparst du bei jeder Tasse wirklich die " + Math.Round((PrUn / 100), 2)
                    + " €.";
                gbxStatistik.Visible = true;
            }
            else if (pon == "negative") {
                negativeErr();
            }
        }

        void resetToolStripMenuItem_Click(object sender, EventArgs e) {
            initReset(true, true);
        }

        void btnReset_Click(object sender, EventArgs e) {
            initReset(true, true);
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
            Form2 About = new Form2();
            About.Show();
        }

        private void beendenToolStripMenuItem_Click(object sender, EventArgs e) {
            Application.Exit();
        }

        void initReset (bool elems,bool vars) {
            if (elems==true) resetElements();
            if (vars==true) resetVars();
        }

        void resetElements() {
            tbxMeKaBo.Text = tbxPrKaAu.Text = tbxPrKaAu.Text = 
            tbxPrKaBo.Text = tbxPrTaKa.Text = tbxPrUn.Text = 
            tbxAnKaWo.Text = "";
            cbxPrAlKa.ResetText();
            gbxStatistik.Visible = false;
            tbxPrKaAu.Focus();
        }

        void resetVars() {
            PrUn=PrKa=PrAlKa=MaxKaBo=KaAuBezWo=0;
            DuVeKaBo = 20;
        }
    }
Download

Kaffee-Kalkulator [.exe]

Ich denke nicht, dass es eine ausgebaute Version 2 des Programms geben wird aber trotzdem; Kritik, Verbesserungsvorschläge, Ausbauvorschläge, Spam und puren Stuss, einfach Kommentar schreiben.

PS: Was haltet ihr von meiner neuen „Code anzeigen“ Methode? Ich dachte mir so bleibt die Übersichtlichkeit meines Blogs unverändert und ich kann trotzdem lange Codeschnipsel präsentieren. Ob und wenn ja wie der Code dann allerdings im RSS Reader erscheint weiß ich noch nicht. Werden display:none divs im RSS beachtet? Naja mal sehen.


Ich habe gestern abend im Bloghintergrund etwas aufgeräumt und dabei bemerkt, dass sich das Global Translator Plugin sehr auf die Performance und den Speicherplatz des Servers auswirken kann – negativ gemeint.

Beschäftigen wir uns also kurz mit der Optimierung von Global Translator.

Global Translator (GT) ermöglicht die Übersetzung aller Artikel in so ziemlich jede Sprache der Welt.
Das Plugin greift dafür auf eine der folgenden Übersetzungs-Engines zurück: Google Translation Services, Promt Online Translator, Altavista Babel Fish oder FreeTranslator. Google ist dabei standardmäßig aktiviert und auch mein Favourit.

Die verfügbaren Sprachen kann man im Einstellungsmenü ebenfalls auswählen.

Tipp 1: Wählt so wenig Sprachen wie möglich! Jeder Artikel den ich schreibt und veröffentlicht, wird automatisch in alle aktivierten Sprachen übersetzt und abgespeichert. Habt ihr also 18 Sprachen aktiviert und veröffentlich 1 Artikel so füllt sich der GT Cache mit 18 neuen Dateien. Also, prüft eure Blogstatistiken aus welchen Ländern wieviele Besucher kommen und aktiviert vielleicht die Top 5 oder Top 10 Besucherländer.
Tipp 2: Aktiviert die Option „Use a single and optimized image map“ mit der Anzahl eurer aktivierten Sprachen. Damit hat der Server bei jedem Seitenaufruf nicht 9 einzelne Flaggen zu laden (9 Requests) sondern nur 1 Bild.

Weiter in den Einstellungen:

Lasst euch mal die Cache Statistics anzeigen, wenn ihr Global Translator schon länger nutzt. Folgendes könnte passieren:

Tipp 3: Es bietet sich hier sichtlich an, hin und wieder aufzuräumen. Vor allem, wenn man die Spracheinstellungen ändert, also Sprachen entfernt. Die bereits gecachten Seiten würden dort in dem Speicher weiterhin verrotten, obwohl sie niemand aufrufen kann.

Und noch so ein Hammer: die debug.log

Auch diese kann nach geraumer Zeit seeehr groß werden, bei mir fasst sie nach wenigen Monaten schon 1GB FTP Speicherplatz! Daher
Tipp 4: Deaktiviert die Option „Enable Debug“ und löscht diese Datei. Außer ihr habt Gründe, regelmäßig in die debug.log zu schauen weil es Probleme mit dem Global Translator gibt. Aber das sollte nicht der Fall sein.

So denn, aufgeräumt, ein Traum 🙂

Okay, strange thing: bei einem Kumpel kam letztens folgende Meldung in seiner Google Mail Oberfläche:

Irgendwie ziemlich gruselig. Zwar hat die deutsche Domain nasa.de nichts mit dem bekannten NASA Raumfahrtunternehmen zu tun aber aus irgendeinem Grund würde ich trotz allem spätestens jetzt mein Passwort ändern 😀

Wie erkennt Google diesen ungewöhnlichen Zugriff? Woher weiß Google, dass dieser „Besucher“ nicht der eigentliche Besitzer dieses Google Mail Kontos ist? Immerhin hatte er ja scheinend die Benutzerdaten und sich damit eingeloggt. Oder kommt die Meldung auch bei 3 oder mehr nicht erfolgreichen Login-Versuchen. „Möglicherweise wurde […] zugegriffen“ ist ja jetzt auch keine sehr sichere Ansage.
Ich kenn dieses Verhalten von Google jedenfalls noch nicht.

Mein letzter Post erklärte die spezielle Behandlung von Internet Explorer 6 (und jünger) in meinem Blog. Es wird statt dem eigentlich Inhalt ein bisschen Text und Links zu vernünftigen Browsern angezeigt.
Ich wollte dieses „Feature“ jetzt mit nur 1 Zeile realisieren. Den CSS und HTML Code in der tatsächlich index stehen zu haben ist unschön.
Daher präsentiere ich:

IE-Buster

a small jQuery Anti-IE Plugin

Frei nach dem Motto:
„If there’s something strange
in the internet.
Who ya gonna call?“

IE-Buster!!!
😉



Das Plugin ist nur 2,3KB groß und damit ein Leichtgewicht im Anti IE Geschäft. Es epfiehlt sich also wenn man keinen besonders hübschen und funktionsreichen Abgang beim IE sucht, sondern etwas kleines, schnelles und unkompliziertes.
Einzige Voraussetzung: jQuery muss eingebunden sein!

Code
$(document).ready(function() {
  $("head").append('<!--[if lte IE 6]><style type="text/css">#ie6-warning { display: block; width: 100%; height: 100%; background-color: white; position: absolute; z-index: 1111; top: 0px; left: 0px; color: black; padding: 10%; font-size: 17px; } #ie6-warning td { border: 1px solid #eee; padding: 4px; color: white; } #ie6-warning a { color: blue; }</style><![endif]--><!--[if gt IE 6]><style type="text/css">#ie6-warning { display: none!important; }</style><![endif]-->');
  $("body").append('<div id="ie6-warning">Ihr Browser ist zu alt um diese Internetseite korrekt darzustellen.<br/>Bitte aktualisieren Sie Ihren Browser oder installieren Sie einen anderen modernen Browser.<br/><br/>Your browser is too old to display this website correctly.<br/>Please update your browser or install another modern browser.<br/><br/><br/><table cellpadding="10"><tr><td></td><td>Google Chrome</td><td>Mozilla Firefox</td><td>Opera</td><td>Apple Safari</td><td>Microsoft Internet Explorer</td></tr><tr><td>Download (DE):</td><td><a href="http://www.google.de/chrome/">Link</a></td><td><a href="http://www.mozilla-europe.org/de/firefox/">Link</a></td><td><a href="http://de.opera.com/">Link</a></td><td><a href="http://www.apple.com/de/safari/">Link</a></td><td><a href="http://www.microsoft.com/germany/windows/internet-explorer/">Link</a></td></tr><tr><td>Download (EN):</td><td><a href="http://www.google.com/chrome/">Link</a></td><td><a href="http://www.mozilla-europe.org/en/firefox/">Link</a></td><td><a href="http://www.opera.com/">Link</a></td><td><a href="http://www.apple.com/safari/">Link</a></td><td><a href="http://www.microsoft.com/windows/internet-explorer/">Link</a></td></tr><tr><td>Suchen/Search for:</td><td><a href="http://www.google.com/search?q=chrome">Link</a></td><td><a href="http://www.google.com/search?q=firefox">Link</a></td><td><a href="http://www.google.com/search?q=opera">Link</a></td><td><a href="http://www.google.com/search?q=safari">Link</a></td><td><a href="http://www.google.com/search?q=internet+explorer">Link</a></td></tr></table><br/><br/><span>by <a href="http://it-stack.de">Hannes Schurig</a></span></div>');
});
Download

Download des Plugins v1.2

ie-buster-1.2 [.js] (Rechtsklick -> Speichern unter)
Nicht vergessen, regelmäßig nach Updates schauen.

oder

Einbinden der neuesten Version von meinem Server

<!-- <script type="text/javascript" src="jquery-min.js"></script> // (noch) Voraussetzung: jQuery! -->
<script type="text/javascript" src="http://public.hannes-schurig.de/IE-Buster/ie-buster-latest.js"></script>
Changelog


v1.2 – Anzeigefehler behoben
v1.1 – Anzeigefehler behoben

Am Wochenende gibt es ja normalerweise keine Posts aber ich war Ende der Woche etwas faul, also, Ausnahme.
Außerdem gibt es gerade einen großen Anlass, über den man schreiben kann:

Caschy’s Blog wird 6 Jahre alt und veranstaltet ein großes Gewinnspiel zu Ehren dieses Events!
Bis 04. April hat man Zeit teilzunehmen, ich werd einfach mal jetzt schon aktiv werden. Via Kommentar, Twitter oder Blogpost kommt man den Gewinnen etwas näher. Ich bin ja auf das eine oder andere schon ziemlich scharf.

Muss man noch etwas zu Caschy sagen? Ich denke nicht. Wer Caschy’s Blog „Stadt-Bremerhaven“ nicht kennt ist noch nicht in der Blogosphäre angekommen (ooder bloggt nicht mit einem PC) 😉
Für alle die, die doch gerade „Häää, Kaschieh, wer?“ denken:
DER Blog rund um Software, Internet, Portable, Tech-/Nerdstuff, Mobile und etwas Lifestyle!

Für die Leistung von 6 Jahren Bloggen ein dickes Respekt, Daumen hoch und viel Erfolg, Spaß und Nerven für die Zukunft. Ich blogge seit 2 Jahren und verneige mich vor dieser Leistung denn bloggen kann tatsächlich härter sein als einige vielleicht glauben!

Langzeitblogger, auf die Knie! 😀
Flickr Image Link