DeepinOS: Schönes Linux, schwerer Weg

Ich war ja schon immer ein Fan von Linux, und seit dem die Schule zu Ende war, brauchte ich auch nur Linux.

Eine Zeit lang habe ich openSuse verwendet, bin dann zu Ubuntu gewechselt, von dort aus zu elementaryOS für zwei Wochen und jetzt bin ich bei DeepinOS gelandet. Eine Debian-Distribution aus China.

Das Desktop Environment basiert auf Gnome3 und ist echt schön. Das Kontrollzentrum befindet sich, in einer Seitenleiste am rechten Bildschirmrand.

DeepinBildschirmfoto20160630230317

Die Installation gestaltete sich vergleichsweise schwierig. Obwohl DeepinOS den einfachsten Installer der Welt an Bord hat, musste ich es fünf Mal installieren. Beim ersten Mal hat es die Ubuntu Installation nicht gelöscht und drüber geschrieben. Bei den anderen Malen hatte die Festplatte zu viele primare Partitionen. Das war aber dann mein Fehler. Schlussendlich habe ich die Partitionen gelöscht und im einfachen Modus deepinOS alles regeln lassen. Dann lief es.

Ob ich noch manuell Grub als EFI Standard einstellen müsste, weiß ich nach den ganzen Installationen nicht mehr.

Dokumentation 2 Go

Ich habe vor kurzem entschieden aus einem Projekt auszutreten und war gezwungen meinen Code zu dokumentieren. Ich suchte nach Tools, um mir das Leben einfacher zu machen. Da ich einen Teil des Codes bereits mit docstrings kommentiert habe, konnte ich hier mit apigen eine ansehnliche PHP-Dokumentation basteln.

Da das aber nicht alles war, was ich dokumentieren musste, bin ich zu http://sphinx-doc.org gekommen. Sphinx ist ein wunderbares Tool und ich hatte es schnell aufgesetzt und die ersten Seiten geschrieben. Tmux und Vim machten dies unfassbar schnell möglich.

Um die Dokumentation schöner zu gestalten, habe ich das ReadTheDocs-Theme benutzt und ein paar Tricks von ReadTheDocs und anderen Quellen genutzt, um die Dokumentation effektiver zu gestalten.

Das Hinzufügen neuer Seiten ist unglaublich einfach und ich habe so viel Zeit gespart, die ich sonst mühselig in LibreOffice verbracht hätte.

Obwohl ich sagen muss, dass ich bei ` und ^ die Taste zweimal drücken muss, und so Überschriften dritten Gerades etwas mühselig sind, bin ich zufrieden.

REST-CodeSchnipsel: RestRecipes

Vor kurzem ist bei mir die Notwendigkeit nach eine REST API aufgekommen und ich wollte keine großen Frameworks dafür nutzen, die viel zu viel Overhead mitliefern.

Aus dem Grund habe ich mir selber eine kleine Sammlung an Hilfsklassen erstellt, die mir das Leben einfacher machen. Die Sammlung habe ich RestRecipes getauft.

Zu finden unter: https://github.com/maikwoehl/rest-recipes

Nutzbar wie folgt:

require_once "RestRecipes/autoload.php";

use RestRecipes\Router;

$app = new Router();

$app->route("/order/<id>", "GET", function($id) {
    // Fancy stuff with $id
});

$app->route("/order/<id>", "PUT", function($id, $data) {
    // Fancy stuff with $id and $data
});

$app->route("/order/<id>", "POST", function($id, $data) {
    // Fancy stuff with $id and $data
});

$app->route("/order/<id>", "DELETE", function($id) {
    // Fancy stuff with $id
});

Das ganze kann auch per Composer im eigenen Projekt eingebunden werden:

~$ composer require maikwoehl/rest-recipes

USB-Stick im ReadOnly Modus retten

Heute ist mir meine Stiftebox heruntergefallen und ich habe einen alten USB-Stick gefunden. Diesen haben ich natürlich direkt angesteckt (Windows) und festgestellt, dass ich nicht schreiben konnte. Sonst war der Stick aber leer.

Was ist mit diesem Stick passiert? Warum kann ich nicht schreiben? Der hat keinen Schalter für einen Schreibschutz. Also startete ich meinen PC in mein openSUSE neu und versuchte mit dem Internet eine Lösung zu finden.

fdisk lieferte mir diverse komische Partitionen verschiedenen Typs. Außerdem meldete dmesg einen WriteProtect. hdparm -r0 /dev/sdb behob das Problem und ich habe mit fdisk den USB-Stick komplett formatiert. Eine primäre Partition im W95 Fat32 (fdisk b HEX-Code) entstand. Interessanterweise wurde diese unter Linux nur unter /dev/sdb gemeldet, kein /dev/sdb1. Das sollte mich nicht weiter stören.
Das tat es aber dann doch. Gparted half mir. Es tat Dinge die ich nicht kannte. Die Magie der GUI.

Der Stick funktioniert mittlerweile wieder. Ein schöner Stick mit meinem Sternzeichen eingraviert. Sehr edel, finde ich.

OpenSUSE LEAP 14.2 – KDE

Ich habe vor kurzem mal wieder ein Linux installiert. Diesmal habe ich mich für OpenSUSE entschieden und finde es recht ansprechend. Die KDE-Oberfläche läuft sehr flüssig. An das Paketmanagement muss ich mich erst noch gewöhnen.

Folgendes ist mir dann passiert:
Ich wollte mit KNetAttach Netzlaufwerke verbinden und wusste nicht, wie ich das genau machen soll, bis ich im Internet gelesen habe, dass in das Feld „Server“ wirklich nur die Server-IP oder der Server-Domainname hineinkommt. In das Feld „Ordner“ kommt dann der Pfad, welcher bei den meisten Tools hinten drangehängt wird.

Hier muss wohl noch ein wenig an der Benutzerfreundlichkeit gefeilt werden.

IntelliJ und andere JetBrains-Produkte mit deutscher Tastatur

Wer IntelliJ oder andere JetBrains-Produkte mit deutscher Tastatur verwenden will, der hat unter Umständen Probleme mit Sonderzeichen und Tastenkombinationen.

Nach langer Recherche konnte ich folgenden Link ausgraben:

https://youtrack.jetbrains.com/issue/IDEA-142462

In den keyboard.xml-Dateien der diversen IDE’s von JetBrains diesen Eintrag löschen und den Haken in den Settings setzen. Schon klappt es. (Jedenfalls bei mir.)

Objektorientierung in PHP

Die  Web-Skriptsprache PHP ist an sich ja schon in einigen Kreisen verpönt, aber ich habe zugestimmt eine einfache Web-Shop Software für einen Freund zu programmieren.
Natürlich habe ich nicht vor xt:commerce nachzuprogrammieren, aber etwas kleines und feines sollte es schon sein. Also habe ich mich drangesetzt und mich in OOP mit PHP eingearbeitet und war erst beeindruckt und an einigen Stellen enttäuscht. Meine Erfahrungen möchte ich in diesem Beitrag teilen.

Interfaces

Interface heißt auf Deutsch Schnittstelle und ist das, was es bedeutet. Ein Interface bietet eine Schnittstelle zu einem Projekt und ihren Objekten. Entscheidet sich ein Programmierer dazu, solch ein Projekt zu modifizieren, dann kann der ein Interface implementieren und stellt damit sicher, dass das Projekt die gleichen Signaturen vorfindet.

Nicht nur ein anderer Programmierer, sondern auch man selber profitiert von Interfaces, weil diese Flüchtigkeitsfehler schnell aufdecken können.

Lange Rede, kurzer Sinn: Ein Interface wird wie folgt geschrieben:

interface iMyClass {
  public function sampleMethod();
  public function exampleMethod($someVariable);
}

Klassen

Klassen im einfachen Sinne sind Baupläne für Objekte. Auch hier ist PHP mittlerweile gut dabei, denn Type Hinting erlaubt es einem, bestimmte Variablen an Typen zu binden. Mehr dazu in der PHP-Dokumentation.

class MyClass implements iMyClass {
  public $someProperty;
  public array $someArrayProperty;
  public AnotherClass $someAnotherClassProperty;

  protected $someProtectedProperty;
  private $somePrivateProperty;

  public function __construct()
  {
    // Constructor
  }

  public function getSomeProperty()
  {
    return $this->someProperty;
  }

  public function setSomeProperty($someProperty)
  {
    $this->someProperty = $someProperty;
  }
}

Das ist ja alles schon ganz nett. Doch kommen wir jetzt zu den Ärgernissen.

Ärgernis 1: Überladung von Konstruktoren

Ab und zu kommt es vor, dass man Konstruktoren überladen möchte. In PHP ist es nicht möglich eine Methode innerhalb einer Klasse zweimal zu deklarieren. Dadurch kommt ein typisches Überladen, wie man es aus Java oder C# kennt, nicht infrage.

Vielmehr muss hier zu einem Trick gegriffen werden, der in der PHP-Dokumentation in einem Kommentar erklärt wird.

Ärgernis 2: Überladung von Methoden

Das Überladen von Methoden ist auch etwas umständliches in PHP. Hier muss zu sogenannten Magic Methods gegriffen werden. In diesem Fall werden diese über __call() aufgerufen.

class AnotherClass {
    public function __call($name, $arguments)
    {
        if ($name == "someFunction")
        {
              switch (count($arguments))
              {
                  case 0:
                      // Do something
                      break;

                  case 1:
                     // Do something different with one Argument
                     break;
              }
        }
    }
}

Das ist eine Möglichkeit an die Sache heranzugehen. Es gibt aber noch mehr. Welche man nutzt, liegt beim persönlichen Geschmack.

Fazit

Wenn ich nicht müsste, dann würde ich nicht in PHP programmieren. Wider Erwarten hat sich PHP in den letzten Jahren zu einer anderen Sprache entwickelt. Es ist für mich zu einer Skriptsprache geworden, die ich nicht mehr allzu sehr verabscheue. Auch wenn es wahrscheinlich ein Großteil an Erfahrung ist, der in diese Erkenntnis einfließt.

Microsoft Edge

Microsoft Edge ist der neue Browser von Microsoft. Er wird standardmäßig bei Windows 10 mitgeliefert und integriert sich gut in das Look&Feel des gesamten Systems. Nicht zu vergessen ist die Integration von OneNote in Microsoft Edge. Diese erlaubt das Kommentieren von Webseiten, die dann geteilt werden können oder in OneNote gespeichert werden können.

Edge ist super schnell und lädt fast jede Webseite in einem Tempo, dem ein Chrome, der wenige Plugins installiert hat, bereits hinterherhängt. Zugegeben, Edge besitzt noch einige Kinderkrankheiten und stürzt ab und zu mal ab, aber ich verzeihe das Microsoft, denn sie haben ein gutes Konkurrenzprodukt auf den Markt gebracht.

TypeScript Entwicklungsworkflow

Seit ein paar Tagen stelle ich meinen Entwicklungsworkflow für HTML5-Applikationen um. Ich nutze jetzt viel mehr TypeScript und möchte mir das Entwickeln damit natürlich erleichtern. Zum Glück bietet der TypeScript Compiler einige Features, die einem dabei helfen.

Zu aller erst:

~$ tsc --init

Mit diesem Befehl wird eine Datei mit dem Namen tsconfig.json angelegt. Nach dieser Datei sucht der TypeScript Compiler automatisch und führt den darin beschriebenen Kompiliervorgang aus.

~$ tsc -w

Dieser Parameter veranlasst tsc dazu, das Verzeichnis zu überwachen und bei jeder gespeicherten Änderung die Datei(en) neu zu kompilieren.

~$ tsc -d

TSC bietet außerdem die Möglichkeit aus dem Projekt Definitionen zu erzeugen, damit fremde Programmierer Statement Completion nutzen können, ohne die TypeScript-Datei zu laden.

Visual Studio Code und eigene TypeScript Definition Files

Vor kurzem bin ich über Visual Studio Code gestolpert und bin angenehm überrascht. Ich hätte nicht gedacht, dass Microsoft es wirklich schafft, die Annehmlichkeiten einer großen IDE in einen leichtgewichtigen Editor zu verpacken.

Nun habe ich begonnen VSCode auch im Alltag einzusetzen. Ich bin damit deutlich schneller unterwegs als mit Brackets. In den letzten Tagen habe ich meine Vertretungsplan-Webapp erweitert und wollte jetzt für meine Vertretungsplan-Bibliothek, die ich geschrieben habe, TypeScript Definition Files anlegen. Mit denen kann VSCode die IntelliSense-Dienste anbieten.

Nach einigem hin und her und ganz viel Gesuche habe ich endlich die Lösung des Rätsels gefunden. Und ich musste einen Fehler akzeptieren.
Das alte Resultat ist folgendes:

interface VP {
    new (webViewElementID: string): VP;
    prototype: VP;
     
    username: string;
    password: string;
    webView: string;
    classID: number;
    CW: number;
    genericPlanStart: string;
    genericTeacherPlanStart: string;
    classList: string[];
    teacherList: string[];
    roomList: string[];
    teacherMode: boolean;
     
    setType(type: string): void;
    navigate(): void;
    getCurrentCW(): number;
    retrieveClassList(): void;
    parseRawData(newRawData: string): void;
    parseTeacherRawData(newRawData: string): void;
    getClassList(listType: string): string[];
    setClassID(id: number): void;
    parseClassID(): string;
}
 
declare var Vertretungsplan: VP;
 
declare var classFavList: string[];
declare var classList: string[];
declare var isFaved: boolean; 
declare var isAlreadyFav: boolean;
declare var classID: number;
 
declare function refreshFavListSelector(): void;

Hier die d.ts-Datei für lose Typen-Definitionen:

declare var classFavList: string[];
declare var classList: string[];
declare var isFaved: boolean; 
declare var isAlreadyFav: boolean;
declare var classID: number;

declare function refreshFavListSelector(): void;
declare function getWeekNumber(): number;
declare class VertretungsplanTP {
    webView: string;
    classID: number;
    CW: number;
    currentType: string;
    genericPlanStart: string;
    genericTeacherPlanStart: string;
    bigPlanEnding: string;
    classList: string[];
    teacherList: string[];
    roomList: string[];
    teacherMode: boolean;
    username: string;
    password: string;
    constructor(webViewElementID: string);
    setType(type: string): void;
    navigate(): void;
    getCurrentCW(): number;
    retrieveClassList(): void;
    parseRawData(newRawData: any): void;
    parseTeacherRawData(newRawData: string): void;
    getClassList(listType: string): void;
    setClassID(id: number): void;
    parseClassID(): string;
}

Mit dieser Datei bot mir VSCode endlich IntelliSense-Dienste für meine Bibliothek an. Wenn man seine Bibliothek nicht gerade selber mit TypeScript schreibt und danach kompilieren lässt, dann ist das hier eine nützliche Methode, um IntelliSense-Unterstützung für eigene JS-Dateien zu bekommen.

Eventuell werde ich die Klasse in TypeScript neu implementieren, das ist aber grundsätzlich nicht nötig.


Nachtrag: Ich habe nun die Klasse in TypeScript neu implementiert und habe die Definitionen nun in zwei d.ts-Dateien aufgeteilt. Eine Definition beinhaltet lose Funktionen und Variablen innerhalb der App und die andere wird mit tsc generiert und beinhaltet die Deklarationen und Typen-Definitionen der Vetretungsplan-Klasse.