Alles eine Frage der Optimierung

So stand ich vor der Aufgabe eine Datei mit zig Zeichenfolgen zu überarbeiten. Also prinzipiell Duplikate löschen und die Datei sortieren.

Viele Wege führen nach Rom. Die Eingangsdatei hatte knapp 19 Millionen Zeilen - also Zeichenfolgen. Rund 190MB. Man könnte es schon Stress-Test nennen.

Wie setzt man dieses jetzt um? Also erst mal die Datei einlesen. Das geht recht unproblematisch mittels System.IO.File.ReadAllLines. Somit hat man jede Zeichenfolge als ein Element in einem String Array. Aber wie geht es weiter?

1. Versuch

Eine For Each Schleife, jedes Element in eine System.Collections.Generic.List(Of String) kopieren, vorher überprüfen lassen ob es nicht bereits existiert. Ich sage mal so... Ja, es geht. Nach 2 Wochen nonstop Laufzeit war er aber erst bei der Hälfte der Daten angelangt und wurde immer langsamer je weiter es fortgeschritten war. Unbrauchbar.

2. Versuch

Wieder For Each, dieses Mal mit einem Array gleicher Größe als Ziel. Abfrage per Array.IndexOf damit nichts doppelt rein kommt. Vergiss es. Das hätte nicht nur Monate sondern Jahre gedauert.

3. Versuch

Das Selbe wie in Versuch 2, nur mit Array.BinarySearch. Tjo, is schnell. Löschte auch hier und da etwas raus, Duplikate waren aber immer noch drin. Auch wieder unbrauchbar.

4. Versuch

Das Array vorher sortiert per Array.Sort, sonst wie im 3. Versuch. Selbes Ergebnis.

Jetzt musste der Gockel herhalten. Viele mit ähnlichen Problemen, aber ohne brauchbare Lösungen. Aber ein Gedankenansatz hat weiter geholfen. Der Code funktionierte natürlich nicht, aber die Grundidee war richtig.

5. Versuch

Also, Ausgangssituation ist immer noch ein Array mit den Zeichenfolgen aus der Datei. Dann das Array sortieren lassen (Array.Sort). Dann eine For Next Schleife erstellen die rückwärts durch das Array geht.

For i As Integer = Content.Length - 1 To 1 Step -1
        If String.Equals(Content(i), Content(i - 1)) Then Content(i) = String.Empty
Next

Es wird der Wert an der aktuellen Position mit der vorigen verglichen. Wenn identisch wird der aktuelle Wert gelöscht / auf String.Empty gesetzt. Später wird ein neues Array erstellt und alle Werte die nicht leer sind rein kopiert. Laufzeit: ca. 2 Minuten, da war's schon fertig.

Dieses Grundprinzip kann man garantiert nicht nur mit Strings verwenden. Auch könnte man natürlich noch ein Dictionary erstellen lassen welche Einträge wie oft vorgekommen sind, eine Variable wie viele Einträge insgesamt entfernt wurden, ...

Warum ich das jetzt hier schreibe?

Ganz einfach. Erstens um Anderen zu helfen, aber auch um ganz klar aufzuzeigen dass viele Wege nach Rom führen. Die Erde ist ja 'ne Kugel, irgendwann wird man schon ankommen. Das Sprichwort ist hier wörtlich zu nehmen. Unzählige Entwickler programmieren, haben wohl auch gute Ideen, aber funktioniert es erst mal dann... tja... funktioniert ja. Auf Performance wird heutzutage gar nicht mehr geachtet.

Leute, achtet mal wieder auf Performance und klatscht nicht blind irgendwas zusammen! Und damit meine ich bei Weitem nicht nur Hobby-Programmierer sondern auch große, namenhafte Firmen! Klar, Optimierung kostet Zeit und somit auch Geld, aber die Benutzer wird es freuen.

Ich schließe mal mit dem Satz ab:

"Qualität ist, wenn der Kunde zurück kommt, nicht das Produkt!"

Edit: Ach ja, das Projekt hat sich gelohnt. Von 187 MB runter auf 145 MB ;)


Fast TraceRoute Header

Beschreibung

Ich kürze das Ganze hier etwas ab: Der normale PC Anwender braucht es nicht. Wer aber weiß was die „tracert.exe“ macht, der schaut sich einfach das Video an.

Wer es nicht weiß aber trotzdem neugierig ist darf das natürlich auch ;)

p.s.: Ja, ich hole mir ein besseres Mikrofon ;)

Systemanforderungen

  • Windows 2000 oder neuer
  • Microsoft .Net Framework 2.0 oder neuer (ab XP im Betriebssystem integriert)

Mittels dem Mono Framework sollte die Anwendung auch unter ReactOS, Linux und MacOS laufen, dies ist aber als experimentell zu sehen.

Lizenz

  • Die Nutzung der Anwendung ist frei für private und kommerzielle Zwecke – solange kein Geld hiermit verdient wird.
  • Die Bearbeitung ist untersagt (z. B. das Ändern des Copyrights). Dies schließt auch „Installer“ oder „Downloader” ein die dem Benutzer andere Software anbieten. Siehe Punkt 1.
  • Die Nutzung des Quelltextes unterliegt diesen Richtlinien: http://source.tightdev.net/License.aspx

Download

Binary: FTraceRt_20170305.zip (71,58 kb)
Source: http://source.tightdev.net/Project.aspx?p=FastTraceRt

Nutzung:

Einfach entpacken und in einem Konsolenfenster (cmd oder PS) mit der IP Adresse oder Hostnamen als Argument starten. Es ist keine Installation notwendig.

ScreenCast

 


NetScan Logo

Beschreibung

NetScan ist ein Tool um ihr Heimnetzwerk zu scannen. Vielleicht kennen Sie das, aus irgendeinem Grund brauchen Sie die IP Adresse von einem Gerät was bei Ihnen im Netzwerk ist. Diese Adressen werden normalerweise automatisch von Ihrem Router vergeben. Möchten Sie jetzt z. B. ein Gerät sperren brauchen Sie die IP Adresse.

Dieses kleine Tool braucht nur gestartet zu werden und scannt automatisch alle Netzwerke durch mit denen Ihr Computer verbunden ist und listet die gefundenen Geräte auf, incl. deren IP und MAC Adresse.

Das Ganze können Sie auch unten in meinem ScreenCast in Aktion sehen. Es ist mein erster öffentlicher ScreenCast, also nicht gleich zerfleischen ^^

p.s.: Ja, ich hole mir ein besseres Mikrofon ;)

Systemanforderungen

  • Windows 2000 oder neuer
  • Microsoft .Net Framework 2.0 oder neuer (ab XP im Betriebssystem integriert)

Mittels dem Mono Framework sollte die Anwendung auch unter ReactOS, Linux und MacOS laufen, dies ist aber als experimentell zu sehen.

Lizenz

  • Die Nutzung der Anwendung ist frei für private und kommerzielle Zwecke – solange kein Geld hiermit verdient wird.
  • Die Bearbeitung ist untersagt (z. B. das Ändern des Copyrights). Dies schließt auch „Installer“ oder „Downloader” ein die dem Benutzer andere Software anbieten. Siehe Punkt 1.
  • Die Nutzung des Quelltextes unterliegt diesen Richtlinien: http://source.tightdev.net/License.aspx

Download

Binary: NetScan_2.1.zip (147,16 kb)
Source: http://source.tightdev.net/Project.aspx?p=NetScan

Nutzung:

Einfach entpacken und starten. Es ist keine Installation notwendig.

ScreenCast


Microsoft .Net Framework Logo

Heute nur ganz kurz…

Die Zeit schreitet ja voran, es gibt nicht nur neue Betriebssysteme sondern auch neue Versionen vom .Net Framework. Für den eigentlichen Benutzer unsichtbar, manchmal wegen massiven Updates sogar nervig, wird es dennoch von vielen Anwendungen benötigt.

Was ist das überhaupt?

Das Microsoft .Net Framework (für Windows und mittlerweile auch ReactOS) sowie auch das Mono Framework (Linux, MacOS) nutzen Entwickler um schneller und portabler Anwendungen zu entwickeln, da das Frarmework einem viele lästige Aufgaben abnimmt. Vergleichbar mit Java, auch wenn der Vergleich sehr hinkt, weil Java ist ja nicht grade für die Performance bekannt ist (welche eben nicht existiert)… Aber das Prinzip ist ähnlich.

Wo liegt das Problem?

Ganz einfach. Es gibt mittlerweile 3 verschiedene Versionen der Runtime, nämlich 1, 2 und 4. In wie weit 1 unterstützt wird kann ich nicht sagen, ich bin erst mit der 2 eingestiegen. Das ist der Kern der .Net Versionen 2.0, 3.0 und 3.5 (letztere haben nur die Funktionalität erweitert). Diese war schon bei Windows XP, Vista und 7 vorinstalliert. Nutzte man ein noch älteres System musste man es halt nachrüsten.

Jetzt kommt aber das Problem. Neuere Betriebssysteme wie Windows 8(.1) und Windows 10 setzen auf die Runtime 4 (also Version 4.0, 4.5 oder 4.6). Die 2er Runtime, also das Framework 3.5 in diesem Fall ist nicht mehr vorinstalliert. Will man jetzt also eine Anwendung starten die für das .Net Framework 2 kompiliert wurde erscheint eine Warnmeldung:

Anders als früher kann man das Framework nicht lokal installieren. Das geht nur von der Windows DVD (angeblich, nie selbst getestet) oder online.

Aber das Ganze ist meistens nicht nötig. Man kann .Net Framework 2 Anwendungen auch in der 4er Runtime laufen lassen.

Und wie?

Dazu muss eine Datei erstellt werden die so heißt wie das Programm was man starten möchte, mit „.config“ als Dateiendung, also zum Beispiel „MeineAnwendung.exe.config“.

Diese Datei einfach im Notepad oder einem anderen Text Editor eurer Wahl öffnen und folgenden Text hinein kopieren:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
        <startup useLegacyV2RuntimeActivationPolicy="true">
                <supportedRuntime version="v2.0.50727"/>
                <supportedRuntime version="v4.0"/>
        </startup>
</configuration>

Damit wird der 4er Runtime erlaubt, auch diese Anwendung auszuführen, selbst wenn sie für die 2er kompiliert wurde.

Softwareentwicklern sei trotzdem dringend angeraten die Software in der neuen Runtime ausgiebig zu testen, da es natürlich immer zu Kompatibilitätsproblemen kommen kann. Ist mir zwar bisher noch nicht passiert, aber sicher ist sicher.

Fazit:

Mal wieder so eine Kleinigkeit die man als Entwickler wissen sollte. Man stelle sich vor man erstellt eine CD / DVD mit einer Autostart Anwendung und alles was man bekommt ist das oben gezeigte Bild. Unschön. Und da es nur eine harmlose Textdatei ist, sollte es ja kein Problem sein diese gleich mit einzubinden.

Zur Not könnte man sich auf 2er Basis einen Loader schreiben der denn auf die 2er oder 4er Binary verweist, falls dies notwendig sein sollte. Ich wüsste nicht warum, aber Anwendungsgebiete sind ungefähr so vielseitig wie eine DNA. ;)


Wer kennt das nicht…

aus irgendeinem Grund muss man seinen Computer neu aufsetzen. Ich hatte ja schon vor kurzem darüber geschrieben: Windows und Office Updates.

Kurz vorweg, dieser Artikel richtet sich eher an (Hobby-)Administratoren statt an Privatanwender.

Aber das in dem Artikel erwähnte WSUS Offline fängt halt nur Windows und Office Updates ab, und auch nicht zu 100% alle. Programme wie Visual Studio, SQL Server, … bleiben außen vor. Wer – wie ich – mehrere Systeme zu warten hat möchte vielleicht auch noch die fehlenden Updates parat haben. Das ist prinzipiell kein Problem.

Updates finden und herunterladen

In dem Microsoft Update-Katalog findet man sämtliche Updates auch zum Download, häufig als .msp oder .msu Datei. Manchmal ist es auch eine .cab Datei, die kann mit Programmen wie z. B. 7zip entpackt werden. In dem Suchfenster muss man die KB Nummer eintragen. Aber die muss man erst mal kennen.

Wie kommt man an diese KB Nummern?

Lasst Windows- oder besser Microsoft Update durchlaufen, stellt die Einstellungen aber vorher so ein dass die Updates nicht installiert werden. So seht ihr (nach einer gefühlten Ewigkeit) sämtliche Updates die installiert werden sollten.

Jetzt ist es Fleißarbeit. Daher lohnt sich es auch nur wenn ihr die häufiger installieren müsst. Macht dem Katalog auf (wohlgemerkt am Besten im Internet Explorer), gebt die KB Nummer im Suchfeld ein (z. B. KB1234567) und ihr bekommt eine Liste mit Updates die zu dieser Nummer passen. Lasst euch nicht irritieren wenn das Update mehrfach auftaucht. Die Updates gibt es häufig für 32 Bit (x86) und 64 Bit (x64) Systeme, außerdem kann es das selbe Update nicht nur für Windows 7 sondern auch 8, 10, … geben, die zwar z. B. die selbe Lücke schließen (daher die selbe KB Nummer), aber eben auf das Betriebssystem angepasst sind.

Updates installieren

Wie eingangs erwähnt, häufig bekommt ihr .msu (Windows) oder .msp (Office) Dateien. Grade bei Office sind es häufig .cab Dateien, die müssten erst mit z. B. 7zip entpackt werden weil sich darin ggf. mehrere .msu oder .msp Dateien befinden. Gelegentlich bekommt man auch .exe Dateien. .msu, .msp und .exe einfach starten und abwarten.

Blöd nur wenn es gefühlte 5674 Stück sind…

Um das Ganze zu automatisieren habe ich ein kleines Programm geschrieben. Quelltext und Download findet ihr unten. Das Programm macht nichts anderes als in dem Ordner in dem es liegt und in allen Unterordnern nach *.msu, *.msp und Install.bat Dateien zu suchen und diese nacheinander auszuführen / zu installieren. So könnt ihr zum Beispiel Updates auf Setup DVDs hinzufügen und müsst nachher nur noch den Updater starten, fertig. Das einzelne Runterladen bleibt euch jedoch nicht erspart…

Wenn das Tool läuft sollte man den PC nebenbei nicht verwenden. Idealerweise sogar kurz die Netzwerkverbindung trennen, nicht dass Windows Updates währenddessen auch noch zuschlägt.

Alle 3 zusammen

Wenn die Updates fertig geladen sind geht es los das Update Verzeichnis zu erstellen. Ich empfehle diese Struktur:

\x64
\x86
\MspInstaller.exe

Im Ordner x64 halt alle Updates für 64 Bit, in x86 alle 32 Bittigen. Wie gesagt, Unterordner werden auch durchsucht und installiert, man kann es also weiter aufschlüsseln:

\x64\Windows7
\x64\Office2010
…

Einziges Problem sind die .exe Dateien. Häufig könnte man die auch entpacken, aber das funktioniert nicht immer (das Entpacken vielleicht, die Installation scheitert dann aber). Daher sucht das Tool auch nach einer Install.bat. Diese zu erstellen ist recht leicht, aber kostet etwas Zeit. Startet die .exe mit dem Parameter /? dahinter, beispielsweise „KB123456.exe /?“. Häufig bekommt man dann Informationen wie eine automatisierte / unbeaufsichtigte / unattended Installation starten kann. Hier ein Beispiel einer Install.bat:

@ECHO OFF
ECHO KB2538243 (Sicherheitsupdate C++ 2008 SP1)...
X86-all-vcredist_x86_470640aa4bb7db8e69196b5edb0010933569e98d.exe /q
IF NOT ["%errorlevel%"]==["0"] (
    ECHO Installation fehlgeschlagen!
    PAUSE
)

Das muss natürlich immer für jede .exe angepasst werden.

So. Einmal gestartet sucht das Tool nach unterstützten Update Dateien (halt die Install.bat, *.msu und *.msp, in dieser Reihenfolge) im Eigenen Verzeichnis, dann pro Unterverzeichnis nach den Dateien, danach weiter in den nächsten Unterverzeichnissen usw.. Wenn ein Verzeichnis den Namen „x86“ hat wird es ignoriert wenn ein 64 Bit Betriebssystem verwendet wird, ebenso „x64“ wenn ein 32 Bit System verwendet wird. Sofern kein Fehler auftritt läuft die Installation unbeaufsichtigt durch, das Konsolenfenster bleibt aber offen um Erfolg zu melden.

Screenshot (hier beim Durchlauf einer Visual Studio 2008 Installation):

Download:

Version: 1.0.2016.0601

Binary (ausführbare Datei):
MspInstaller.exe (154,00 kb)

Quelltext:
http://nopaste.tightdev.net/?ID=kthpw5
VB.Net, Projekttyp: Konsolenanwendung, Starttyp Sub Main. Nicht vergessen im Manifest Admin zu erfordern.


Aus irgend einem Grund…

… ich weiß nicht warum. Aber zumindest bei einem frisch installiertem Windows 7 klappt es nicht mehr statt Windows Updates auf Microsoft Updates umzuschalten. Letzteres würde auch Updates für Office, SQL Server und weitere beziehen.

Hätte ich gerne. Aber das Aktivieren geht nicht mehr. (Absicht?) Erst nach der Installation (und erstmaligem Starten) von Office funktioniert es.

Daher habe ich gesucht und ein kleines VBScript im Netz gefunden was ich leicht angepasst habe. Dadurch werden die Microsoft Updates aktiviert. Hier aber als startbare Datei, weil benutzerfreundlicher.

Edit 08.06.2016:
Wichtig: Der PC muss über eine Internet Verbindung verfügen, sonst funktioniert es nicht. Warum? Keine Ahnung. Ist einfach so.

Quelltext und Download:

Quelltext:

Wieder recht klein, aber erfolgreich. Da es aus VBS kommt is nich mit Option Strict. Egal, ist zwar unschön, aber geht auch so.

Friend Module App

        Friend Sub Main()

                Dim ServiceManager = CreateObject("Microsoft.Update.ServiceManager")
                ServiceManager.ClientApplicationID = "ActivateMSUpdates"
                Dim NewUpdateService = ServiceManager.AddService2("7971f918-a847-4430-9279-4a52d1efe18d", 7, "")

        End Sub

End Module

Projekttyp VB.Net, Framework 2, Konsolenanwendung, Starttyp Sub Main.

Download:

ActivateMSUpdates.exe (7,50 kb)


Man muss sich nur zu helfen wissen…

… so heißt es. Die Windows UAC hat mich heute geärgert. Kann mal vorkommen bei älterer Software die dem Betriebssystem nicht mitteilt dass sie Admin Rechte braucht. Fazit: Die Installation schlägt fehl.

Häufig reicht es dann eine Befehlszeile (cmd) als Admin zu öffnen und die Anwendung oder Befehle darin zu starten. Aber das ist mit Tipperei verbunden und für manche Leute unzumutbar. In meinem Fall hat mich das Microsoft SQL Server 2005 Management Studio geärgert.

Man könnte jetzt sagen, ja, Rechtsklick und „als Administrator starten“. Klar. Geht bei .msi Dateien aber nicht ;)

Da ich primär nach universell nutzbaren Lösungen suche die auch Nutzerfreundlich sind habe ich mal ein kleines Programm geschrieben was im Endeffekt nichts Anderes macht als zu verlangen dass es als Admin gestartet wird und dann die Datei startet die im Dateinamen steht.

Beispiel und Verwendung:

Wenn die Datei „RunAsAdmin_test.exe.exe“ heißt würde sie die Datei „test.exe“ ausführen. Ein einfaches Umbenennen reicht also. Alle Parameter und Rückgabewert wird weiter geleitet. Das ganze funktioniert mit allen startbaren Dateien, wie .exe, .bat, .msi, …

Quelltext und Download:

Quelltext:

Der Quelltext ist so klein, da lohnt sich NoPaste nicht:

Friend Module App

        Friend Function Main(ByVal Args As String()) As Integer

                Using p As New Diagnostics.Process
                        p.StartInfo.Arguments = String.Join(" ", Args)
                        p.StartInfo.FileName = IO.Path.GetFileNameWithoutExtension(Environment.CommandLine.Trim.Trim(""""c)).Substring(11)
                        p.Start()
                        p.WaitForExit()
                        Main = p.ExitCode
                End Using

        End Function

End Module

Das wars schon. … Naja, fast. In den Projekteigenschaften muss noch festgelegt werden dass die Anwendung Admin Rechte benötigt. VB.Net, Framework 2.0, Starttyp Sub Main, Konsolenanwendung.

Alternativ hier der Download:

RunAsAdmin_test.exe.exe (7,50 kb)

Es sind manchmal eben auch die kleinen Dinge die die Welt begeistern ;)


Online TV Recorder Titelbild

Heute mal was ganz Anderes

Damals, da gab es Video Rekorder. Jeder hat garantiert mindestens 1x einen Film oder eine Serie aufgenommen. Dann gab es DVD Recorder. Vom Prinzip das Selbe, nur das Speichermedium war ein Anderes, eben DVD statt Videokassette. Man gab Start- und Endzeit ein, es gab auch VPS Nummern die es einem etwas erleichtert haben… Wie auch immer. Die Kiste sprang an, nahm es auf und man konnte es sich später anschauen.

Aber – ausgenommen unsere werten Politiker – leben wir in der Welt 2.0, sprich wir haben so eine merkwürdige unbekannte Kommunikationsmöglichkeit mit daran angebundenen Dienstleistungen. Dies wird überwiegend „Internet“ genannt, für Dumme „Cloud“ und in öffentlichen Stellen #Neuland.

So verwundert es nicht dass es mittlerweile auch Dienste im Internet gibt die das TV Programm aufzeichnen können und zum Download anbieten. Schöne Sache ist das. Man braucht kein Gerät mehr, man läd es sich einfach runter wenn man wieder am PC ist.

Stellt sich manchen jetzt vielleicht die Frage ob das legal ist. Ja, ist es, auch wenn es den TV Konzernen aus Gründen die ich nicht verstehen kann ärgert. Es gab zwar Klagen (war ja klar), die Sender haben aber verloren. Es ist ja nichts anderes wie ein klassischer Rekorder, sei es nun Kassette oder DVD. Stichwort Privatkopie.

So viel zur Vorgeschichte.

Wie geht das?

Ich gehe hier jetzt auf den OnlineTVRecorder.com ein, da ich den Dienst selber nutze. Es gibt bestimmt noch weitere, aber das ist der bekannteste – zumindest soweit ich weiß. Darum geht es auch im späteren Teil.

Es ist vom Prinzip ganz einfach. Man geht auf die Seite und erstellt sich einen Benutzeraccount. Dazu ist nur E-Mail Adresse und ein selbstgewähltes Passwort nötig, also nichts Anderes wie in jedem Forum u. Ä.. Danach kann man sich dort anmelden und – wohlgemerkt erst ab diesem Zeitpunkt – Sendungen aufnehmen und herunterladen.

Hier sieht es ähnlich aus wie in (hier TV Zeitschrift deiner Wahl einfügen). Man sieht in Spalten und Gruppen die einzelnen Sender, und zeilengerecht den Zeitpunkt wo was läuft. Nur anders als in Zeitschriften kann man hier sagen dass man die Sendung aufnehmen möchte (das grüne + oben links).

Ein kleines „aber“ gibt es allerdings. Es ist nicht ganz kostenlos. Wenn ich mich richtig erinnere waren nur die ersten 10 Downloads frei. Naja, zum Testen genug. Aber der Dienst ist nicht teuer, ich hab 9,50€ für ein Jahr bezahlt. Klar, die ganze Hardware muss ja auch finanziert und gewartet werden. Finde ich fair. (wenn man da mal an die ganzen Android „free to play“ Spiele denkt…)

Der Download

… ist etwas kompliziert. Aber das muss so sein damit der Dienst legal bleibt. Ungefähr 6 Stunden nach Ende der Aufzeichnung steht das Video auf der Seite vom OTR zum Download zur Verfügung (bei kurzen Sendungen manchmal auch schon früher). Aber erstmal nur auf dem OTR Server. Die haben natürlich eher die Priorität die Videos aufzunehmen und zu verteilen, anstatt sie den Kunden runter laden zu lassen. Daher ist ein Download nur zwischen 0 und 8 Uhr morgens gratis, sonst kostet es ein paar Cent, je nach Länge. Aber keine Angst. Es wird auf diverse weitere Server weiter geleitet wo man es auch tagsüber kostenlos runter laden kann. Läd man das Video von diesen Mirrorn runter sind diese aber verschlüsselt. Man muss die Datei denn erst mit einem Tool vom OTR entschlüsseln, wo man seine Benutzerdaten eingeben muss (sonst wäre es eine illegale Verbreitung). Die Software gibt es nicht nur für Windows, sondern auch für MacOS, Linux, …

Komfort

Der Download von den Mirror Servern ist manchmal etwas nervig. Man hat manchmal Wartezeiten, manche Mirror blenden Werbung ein (während des Downloads, nicht im Video selbst). Daher bevorzuge ich eher den Download von den OTR Servern selbst. Wie aber bereits erwähnt ist das nur zwischen 0 und 8 Uhr kostenlos. Daher habe ich einen Downloader programmiert der nur innerhalb dieses Zeitraums runter läd. So muss man nur noch den Rechner die Nacht über laufen lassen, der Rest passiert automatisch.

Ich möchte es noch mal betonen: Das Tool ist nur ein Downloader! Er umgeht nicht die Verschlüsselung. Es wird ein Premium Account voraus gesetzt um die Links zu den Downloads zu erstellen.

Funktionsweise

Das Tool erwartet eine Text Datei mit jeweils einem Link pro Zeile. Diese kann entweder mit „Öffnen mit…“ geöffnet werden, oder falls das Tool selbst gestartet wird dann wird nach einer Datei „Queue.txt“ gesucht und die verwendet. Diese Datei kann einfach im Notepad geöffnet und bearbeitet werden. Eine Raute (#) dient als Zeichen dass alles hiernach ein Kommentar ist, es wird also der Rest der Zeile ignoriert. Downloads werden um 0:10 Uhr gestartet und (ggf.) um 7:50 abgebrochen damit keine Kosten entstehen. Den Rest der Zeit wartet die Anwendung lediglich. Die 10 Minuten dienen als Sicherheit – wer weiß schon wie genau die Uhren auf dem Server und auf eurem PC laufen.

Die Download Links bekommt ihr im OTR unter „Meine Aufnahmen – Fertige Aufnahmen“. Klickt dort alle Aufnahmen an die ihr herunter laden wollt (die Checkbox links). Dann auf der Seite ganz unten ist ein Auswahlfeld „Aktion wählen“. Da wählt ihr „Downloadlinks erstellen“ und klickt dann auf „Aktion ausführen“ daneben. Auf der folgenden Seite könnt ihr die Qualität auswählen. Die die mit .otrkey enden könnt ihr ignorieren, sinnvoll sind hier eigentlich nur die „.HQ.avi“ oder ggf. „.HD.avi“ falls verfügbar. Markiert dort die Qualität pro Datei die ihr möchtet (leider ist standardmäßig nur mp4 ausgewählt was eher was für's Handy ist, brauchen wir nicht). Die mit .cut (selten) sind bereits von der TV Werbung befreit, sonst identisch. Danach öffnet sich eine Seite wo ihr alle ausgewählten Links kopieren könnt. Diese einfach in die Textdatei kopieren, das Tool starten, fertig.

Download

Der OTR Downloader ist Freeware und Open Source. Das .Net Framework 2.0 wird benötigt (fast überall bereits vorinstalliert, das 3.5 tut's auch, 4.0 und neuer sind nicht abwärtskompatibel). Möglicherweise funktioniert die Software auch unter anderen Systemen wie Linux und MacOS mittels dem Mono Framework, Wine oder CrossOver (kostenpflichtig), ich habe es aber nicht getestet.

OTRDownloader.zip (19,65 kb)

Quelltext
Projekttyp ist VB.Net, Konsolenanwendung, Starttyp Sub Main.

In dem Sinne viel Spass :)

p.s.: Ich bin nicht haftbar für eventuell entstandene Kosten!


Raspberry Pi

Weiter geht's im Text…

… mit dem Raspberry. Hierbei ist es egal welcher, das betrifft alle Versionen gleichermaßen. Egal ob Zero, 1 oder 2, egal ob A(+) oder B(+).

Grundinstallation

Ich denke mal die Grundinstallation sollte jedem klar sein. Ich persönlich verwende ausschließlich Raspbian. Bekommen kann man das auf der offiziellen Homepage in 2 Versionen – Normal mit grafischer Oberfläche oder Light ohne. Ich bevorzuge letzteres und installiere mir ggf. die grafische Oberfläche später dazu. Ist ja möglich. Auf der Seite stehen auch Installationsanweisungen.

Ab jetzt gehe ich also von einem lauffähigem System aus.

Vergesst nicht mittels

sudo raspi-config

das Dateisystem auf die Größe der SD Karte zu expandieren. Es ist gleich der erste Punkt.

Updates

Linuxer kennen es genau so wie Windows und Mac Benutzer. Betriebssysteme werden gelegentlich aktualisiert – so auch Raspbian. Um die aktuellsten Updates zu bekommen gebt in der Konsole folgende Befehle ein:

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get upgrade
sudo shutdown -r now

Damit werden alle Updates geladen und installiert Das dauert ein Weilchen, je nachdem wie schnell eure Internetverbindung ist und welchen Raspberry Pi ihr nutzt.

Tendenziell wäre es eine gute Idee jetzt von der Karte noch mal ein Backup zu machen. Sonst müsst ihr das alles noch mal durchlaufen solltet ihr euer System zerbasteln.

SPI und TWI/I2C freischalten

Diese Funktionen sind standardmäßig deaktiviert, die Pins können also als normale IO Pins verwendet werden. Da der Raspberry davon aber genug hat und ich beide Bussysteme häufig nutze ist es das Erste was ich aktiviere. Gebt hierzu in der Konsole ein:

sudo raspi-config

In diesem Config Tool schaut mal unter "Advanced options". Hier sind 2 Menüpunkte relevant, nämlich I2C und SPI. Aktiviert hier beide Funktionen (inklusive automatischem Laden der Module falls ihr gefragt werdet). Nach einem Neustart sollten dann die Module geladen sein und zur Verfügung stehen. Zumindest für das System.

Python und Module installieren

Weiter geht es mit der Installation von Python und dessen Modulen für SPI und TWI/I2C. Ich bleibe eben dem Namen treu (Raspberry PI, PI=Python Interpreter) und nutze Python. Wieder in der Konsole gebt folgende Befehle ein (# sind Kommentare und können weg gelassen werden):

# Python 2 und 3 installieren
sudo apt-get install python-dev python3-dev
sudo apt-get install python-pip python3-pip

# GPIO Support
sudo apt-get install python-rpi.gpio python3-rpi.gpio

# I2C Support
sudo apt-get install python-smbus python3-smbus libi2c-dev

# SPI Support
wget https://github.com/Gadgetoid/py-spidev/archive/master.zip
unzip master.zip
rm master.zip
cd py-spidev-master
sudo python setup.py install
sudo python3 setup.py install
cd ..
sudo rm -f -r py-spidev-master

Jetzt ist Python 2 und 3 installiert und kann auf die GPIO, TWI/I2C und SPI Funktionen zugreifen.

Es gibt auch noch ein weiteres Plugin, namentlich WiringPi, mit dem ich selbst noch nichts gemacht habe. Die Installation sollte so gehen:

# WireingPi (bisher noch nichts mit gemacht, klingt aber nicht schlecht)
sudo apt-get install git-core
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build
# Muss hier noch was installiert oder kopiert werden?
cd ..
rm -f -r wiringPi

Das aber ohne Gewähr, lediglich der Vollständigkeit halber.

Verwendung von Python

Python ist nur eine Programmiersprache, keine grafische Oberfläche zum Programmieren wie z. B. Microsoft Visual Studio, AVR Studio (Atmel), …. Den Quelltext kann man in jedem x-beliebigen Texteditor erstellen (ich verwende hier nano), es gibt aber auch komfortablere Editoren wie z. B. Geany.

Ansich ist Python leicht zu verstehen, da es ähnlich wie Basic auf englischen Sprache basiert. Nichts kryptisches. Ganz wichtig bei Python ist das korrekte Einrücken der Quelltext Zeilen! Sollte man beim Programmieren eh immer drauf achten. Wer das eh tut wird keine Probleme haben, wer nicht wird fluchen. Aber über sich selbst.

Starten wir mit dem klassischem Beispiel HalloWelt.

Wieder in der Konsole öffnet nano und gebt schon mal den Dateinamen vor:

nano hallo.py

Jetzt seit ihr in nano, dem Texteditor, mit einer leeren Datei namens hallo.py. Sollte die Datei nicht leer sein existierte sie bereits ;)

Gebt hier folgenden Code ein:

#!/usr/bin/env python

print("Hallo Welt!")

Die erste Zeile ist Linux typisch. Anders als z. B. bei Windows, wo die Dateierweiterung (wie .txt, .mp3, …) festlegt welche Anwendung die Datei öffnen kann oder soll ist es hier so dass es die Datei selbst sagt (optional). Kann man weg lassen, sollte man aber einbinden. Hier besagt die Zeile dass die Datei mit Python (2) geöffnet werden soll.

Die zweite Zeile gibt ein "Hallo Welt!" auf der Konsole aus. Da danach nichts mehr folgt ist das Programm somit abgelaufen und beendet.

Speichern könnt ihr das Werk mit [STRG]+[O] und Enter, Beenden könnt ihr nano dann mit [STRG]+[X].

Jetzt soll das Programm natürlich gestartet werden. Es gibt mehrere Möglichkeiten. Die einfachste wäre einfach das Script mit Python zu starten:

python hallo.py

Eine andere Alternative wäre die Datei als ausführbar zu markieren und so zu starten. Da wird dann die erste Zeile im Script ganz wichtig.

chmod +x hallo.py
./hallo.py

Egal wie, es wird das Hallo Welt ausgegeben. Gratulation zum ersten Schritt :)

Auf GPIO zugreifen

 Hier geht es schon etwas los. Aber es ist alles recht einfach. Bevor wir los legen sagen wir welche Module wir verwenden wollen. Ich zeige hier auch noch ein paar Informationen an über das System. Das ist natürlich optional.

#!/usr/bin/env python
#
# Import sys (for version & error info) and time (for sleep) modules
import sys
import time

# Import GPIO module
try:
    import RPi.GPIO as GPIO
except RuntimeError:
    print("Error importing RPi.GPIO! This is probably because you need " + \
          "superuser privileges. You can achieve this by using 'sudo' to " + \
          "run your script.")
except:
    print("Unexpected error: ", sys.exc_info()[0])
#end try

# Print some version info
print("")
print("Using Python version:   %s.%s.%s" % sys.version_info[:3])
print("Installed GPIO Version: " + GPIO.VERSION)
print("Raspberry PI revision:  " + str(GPIO.RPI_REVISION))
print("")

# Set up pin numbering. BCM=Pin number from the controller, BOARD=Pin number from the header.
GPIO.setmode(GPIO.BCM)

# Set warnings on (if a pin is already used by another script). It's the default anyway.
GPIO.setwarnings(True)

Das Wichtigste hier ist das Einbinden von GPIO. Das kann bei manchen Distributionen fehlschlagen wenn das Script nicht als root läuft (z. B. mittels sudo), daher die Abfrage mittels try. Hier sieht man auch wie Python arbeitet, es nutzt das Einrücken aus um die Blöcke zu erkennen. Aus (Visual) Basic kenne ich das so dass es zu jedem If / try / … auch ein end if / try / … gibt, daher schreibe ich es auch in Python immer hin (als Kommentar). Ich finde es übersichtlicher. C ähnliche Sprachen nutzen die geschweiften Klammern, Python eben die Leerzeichen. Mal was Anderes.

Sollte euch eine Zeile mal zu lang geraten könnt ihr diese an bestimmten Stellen mit \ umbrechen. Habe ich hier in der Fehlermeldung gemacht.

So. Der Code oben macht aber eigentlich noch nichts, außer das bisschen Status auszugeben. Jetzt geht es weiter mit dem Code:

try:

    # Set pin as output
    GPIO.setup(26, GPIO.OUT)

    # Let the state change at 1hz
    while True:
        GPIO.output(26, True)
        time.sleep(0.5)
        GPIO.output(26, False)
        time.sleep(0.5)
    #end while

except KeyboardInterrupt:

    GPIO.output(26, False)
    pass

finally:

    # Ctrl+C pressed, cleanup
    GPIO.cleanup()

#end try

Hier wird erst der Pin 26 als Ausgang definiert. Dann wird in einer Schleife dieser High gesetzt, 0,5 Sekunden gewartet, auf Low gesetzt, wieder 0,5 Sekunden gewartet und alles von vorne.

Das ganze läuft in einem Try Block. So können wir abfangen wenn der Benutzer [STRG]+[C] drückt um das Script abzubrechen (es würde sonst unbegrenzt weiter laufen) um den Ausgang sicher auf Low zu setzen. Ebenfalls wichtig ist der Finally Block, der immer ausgeführt wird, egal ob ein Fehler aufgetreten ist oder nicht. Das ist hier wichtig, da wir bei Script Ende auch alle Bezüge zum GPIO entfernen wollen die wir erstellt haben. Somit ist nach Ablauf des Scripts wieder alles wie es vorher war.

Ziemlich einfach, oder? ;)

Mit Eingängen wird es etwas komplizierter, schlimm ist es aber nicht. Das Grundkonzept wie hier bleibt bestehen. Eingänge können verschieden definiert werden, mit internem PullUp oder PullDown. Da ich die Atmel AVRs gewöhnt bin welche ausschließlich PullUps besitzen nehme ich eher dieses, das ist aber Geschmackssache. Bei PullUp muss der Eingang eben auf Masse gezogen werden (beispielsweise mit einem Taster), bei PullDown gegen VCC. Seid hier vorsichtig! Die I/O Pins sind nicht abgesichert und verkraften nur maximal VCC, also 3,3V! Legt ihr ein 5V Signal an kann es das schon gewesen sein, mit etwas Glück für den Pin, mit Pech für den ganzen Pi. Dauerhaft. Durchgebrannt. Tot.

Nicht nur dass es PullUp und PullDown gibt, es gibt (wie überall) auch mehrere Arten den Pin auszulesen. So kann man ihn Pollen (direkt den Wert auslesen) was meistens aber nicht sinnvoll ist da es die CPU Last unnötig erhöht, oder man kann sich benachrichtigen lassen wenn sich der Zustand ändert (Interrupts).

Dieser Code zeigt wie man die GPIO's per Interrupt einliest. Vieles ist wie oben bereits beschrieben und erklärt, der Rest ist eigentlich selbsterklärend.

#!/usr/bin/env python
#
# Example script how to use GPIO on Raspberry PI (and to use Python).
#
# Wireing for this example:
#   Pin  7: Duo-LED Red
#   Pin  9: Duo-LED Kathode
#   Pin 11: Duo-LED Green
#   Pin 14: Switch 1, a
#   Pin 16: Switch 1, b
#   Pin 17: Switch 2, a
#   Pin 18: Switch 2, b
#
# Switch 1 turns on the green LED, Switch 2 turns it off while the red LED is flashing with 1hz.

#Import sys (for version & error info) and time (for sleep) modules
import sys
import time

# Import GPIO module
try:
    import RPi.GPIO as GPIO
except RuntimeError:
    print("Error importing RPi.GPIO! This is probably because you need " + \
          "superuser privileges. You can achieve this by using 'sudo' to " + \
          "run your script.")
except:
    print("Unexpected error: ", sys.exc_info()[0])
#end try

# Print some version info
print("Installed Python version: %s.%s.%s" % sys.version_info[:3])
print("Installed GPIO Version:   " + GPIO.VERSION)
print("Raspberry PI revision:    " + str(GPIO.RPI_REVISION))

# Set up pin numbering. BCM=Pin number from the controller, BOARD=Pin number from the header.
GPIO.setmode(GPIO.BCM)

# Set warnings on (if a pin is already used by another script). It's the default anyway.
GPIO.setwarnings(True)

# Setup two pins as input.
# Port 23 (pin 16) will be pulled up (3.3V), Port 24 (pin 18) down.
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

# Setup two pins as output.
GPIO.setup(17, GPIO.OUT)        # GPIO 17 (pin 11)
GPIO.setup(4, GPIO.OUT)         # GPIO 4  (pin 7)

# Callback if button 1 is pressed
def key1_down(channel):

    GPIO.output(17, True)

#end def

# Callback if button 1 is pressed
def key2_down(channel):

    GPIO.output(17, False)

#end def

# Subroutine which is called in the main application loop that simply turns an LED
# on GPIO4 (pin 7) on and off. Also demonstrates the sleep command.
def led_blink():
    GPIO.output(4, True)
    time.sleep(0.5)
    GPIO.output(4, False)
    time.sleep(0.5)
#end def

# Add event listeners to the 2 input signals (like interrupt service routines)
GPIO.add_event_detect(23, GPIO.FALLING, callback=key1_down)
GPIO.add_event_detect(24, GPIO.RISING, callback=key2_down)

# Main application loop
try:
    while True:
        led_blink()
    #end while
except KeyboardInterrupt:
    # Ctrl+C pressed
    pass
finally:
    GPIO.cleanup()
#end try

In einem späteren Beitrag erfahrt ihr wie man auf SPI und TWI/I2C zugreift, für heute reicht es erstmal :)