Kategorien
Allgemein Code

Wie man ohne eigene Infrastruktur und mit wenig Aufwand eine Web-App mit “CMS” betreibt – kostenlos.

Ja, klar, alter Hut. CMS SaaS gibts ja auch wie Sand am Meer, aber, wenn man wirklich nur ne kleine API aus einer Tabellenartigen Struktur erzeugen will, ist das meist mit Kanonen auf Spatzen geschossen.

Ich bin ja Freund des Lean-Ansatzes. Also schnüren wir mal folgende Dinge:

  1. Einen Account bei GitLab (oder Github)
  2. Einen Account bei Netlify, Vercel o.ä.
  3. Einen Account bei Google.

Die meisten Web-Entwickler haben Punkt 1 und 3 schon erfüllt, schätze ich. Netlify oder Vercel hat vielleicht nicht jeder, am Ende tut es auch ein eigener Webspace, aber ich habe mich mit Netlify für den wenigsten Aufwand entschieden, da sie auch Cloud-Functions bieten. Das ist hier zwar nicht notwendig, aber ein nettes Feature, welches API-Calls sicherer macht.

Die Datenbank

Eine Tabelle der Dinge, die ich darstellen wollte, gab es schon:

Übersicht über Gamingbooster am deutschen Markt

Auf Youtube habe ich eine sehr coole Einführung in Google Apps Script, welches im Kontext von Spreadsheet ausgeführt wird, gefunden.

Komprimiert ist das die Funktion die ihr im App Script einbauen wollt:

function doGet() {
  const spreadSheet = SpreadsheetApp.getActiveSpreadsheet()
  const workSheet = spreadSheet.getSheetByName('Übersicht Gaming Booster');
  const data = workSheet.getRange("A1").getDataRegion().getValues();
  const fieldNames = data.shift();

  let jsonArray = data.map((row, i) => {

    // remap header fieldname to create new object
    // makes api more robust on table changes
    const obj = row.reduce((acc, curr, idx) => {
      acc[fieldNames[idx]] = curr;
      return acc
    }, {id: i});
    return obj
  })

  return ContentService
    .createTextOutput(JSON.stringify(jsonArray))
    .setMimeType(ContentService.MimeType.JSON)
}

Damit wird aus Zeilen ein Array von Objekten gemacht, die man in einer Web-App gut verarbeiten kann. Die erste Zeile wird dabei als Property-Name für die Objekte genutzt. Wie man an die einzelnen Stellen herankommt, kann man in den Youtube-Videos gut sehen.

Das Frontend.

Das ist eine einfache Vue-App, in der zentralen App.vue Komponente werden die Daten von der Google-API abgerufen und im LocalStorage abgelegt. Durch Nutzung des Vue-PWA Plugins ist die App damit offline-fähig, nachdem sie das erste Mal geladen wurde.

Der automatische Build

Die Versionierung des Frontends liegt in einem privaten Repository auf Gitlab. In meinem Fall habe ich Netlify und Gitlab verknüpft. Damit bekomme ich in Netlify mit, wenn sich mein stabiler Entwicklungszweig ändert und fängt an, meine Anwendung neu aufzubauen.

Diese wird bei Netlify gehostet, dort wird ein npm install && npm run build ausgeführt und das Build-Artefakt als neue Homepage eingesetzt.

Anstelle von Netlify kann man auch Vercel oder Heroku nutzen, eigenen Webspace, Gitlab Pages via Gitlab CI, Github, Github Actions und Github Pages, die Liste an Möglichkeiten ist lang. Meine gewählte Kombi ist aus Bequemlichkeit entstanden (bekannter Workflow, Netlify bietet noch ein paar interessante Zusatzfunktionen, die ich gerne ausprobieren möchte). Und in dieser Form ist das einzige, was ich machen muss, entwickeln und versionieren, der Rest läuft automatisch. Wenn ich schon ein just-for-fun-Projekt mache, muss sich der Management-Overhead auch schon gegen 0 bewegen.

Bonuspunkte

Ich habe die Google-API in meinem Fall durch eine Netlify Function geproxyd, damit die URL immer gleich bleibt und von der App aus immer nur die neueste Funktion genutzt werden kann. Andernfalls könnte jemand die verschiedenen Stadien der API sehen und nutzen, auch wenn diese z.b. durch Änderungen in der Tabelle gar nicht mehr funktionieren oder Daten ausgeben, die ich gar nicht ausgeben will.

Wie lange dauert sowas?

Die erste Version der App hat ca. 3 halbe Tage (nach dem Feierabend) gebraucht. In der Zeit habe ich mit Vite und TypeScript angefangen, aufgrund wirklich merkwürdiger Fehler, die TS im Template-Teil einer Vue-Component das ganze noch mal mit Vue-CLI neu aufgesetzt, dann auf Vue-CLI 5-beta geupgraded und nach einer Auseinandersetzung damit, dass Typescript Sortierfunktionen gar nicht mag, wenn man nach einem dynamisch gewählten Feld sortiert (auch wenn es korrekt getyped wurde), fast einfach alles weggeworfen und auf Javascript umgebaut.

Ach ja, und die API habe ich sehr schnell von einem statischen Row-Index auslesen (MVP lässt grüßen) auf das dynamisch erweiterbare Schema welches oben schon erwähnt ist, umgestellt.

Fazit: Was gelernt und Spaß dabei

Wie eben schon erwähnt: Es ist eigentlich so ziemlich alles schief gelaufen, was hätte schief gehen können. Aber: ich habe Dinge über Typescript gelernt (das war mein erstes TypeScript Projekt). Ich habe eine Menge über Google App Scripts gelernt (die Funktion ist bei mir deutlich anders mittlerweile), mit Parametern und Co. und einem Mini-Counter als Mini-Statistik. Netlify und Gitlab und das automatische Bauen von Anwendungen kannte ich schon, Netlify Functions habe ich in diesem Projekt auch das erste Mal genutzt.

Was ich auf jeden Fall noch vorhabe: Einen Service-Worker bauen, der das Datenmanagement im Hintergrund macht und ggf. die PWA-Notification API nutzen um auf neu hinzugefügte Produkte aufmerksam zu machen. Das wird allerdings komplettes Neuland für mich.

Kategorien
Allgemein Webentwicklung Werkzeuge

Webdriver und das Problem mit dem unsichtbaren Text.

Neulich stand ich vor einem Problem, in dem ich mittels PHP-Webdriver versuchte, portentiell versteckten Inhalt aus einer Seite auszulesen.

Leider ist es so, dass das ganze nicht funktioniert, wenn der Inhalt versteckt ist. Dann wird zwar das Element gefunden, wenn man $element->getText() nutzt, wird aber null bzw ein leerer String ausgegeben. Das ist natürlich unschön und Webdriver selbst hat auch keine Möglichkeit, das DOM selbst zu verändern.

Aber natürlich gibt es einen Weg, dafür zu sorgen, dass man die Inhalte auslesen kann, immerhin muss das Element einfach nur sichtbar sein. Aber was, wenn das Element selbst nicht unsichtbar ist, sondern ein Eltern-Element das verursacht?

Hier die mögliche Lösung

PHP-Webdriver hat die Möglichkeit, einen Javascript-Codeblock an den Browser zu senden (analog zu browser.execute), der zweite Parameter von executeScript wird als arguments[] an die JS-Funktion übergeben. Damit bekommen wir das zu untersuchende Element.

In einer While-Schleife geht es dann (wenn ein Element nicht sichtbar ist) Element für Element nach oben. Dabei bekommt jedes einzelne Element ein display: block !important gesetzt.

Sobald ein überordnetes Element sichtbar ist, sind wir fertig. Eine while-Schleife stellt hier eine einfache Möglichkeit dar, den DOM-Tree rekursiv hochzuwandern.

Es besteht dabei auch die Möglichkeit, ein Element aus diesem Codeblock, der in eine Lambda-Funktion (auch “anonyme Funktion”) gepackt wird, zurückzugeben und das Element in PHP weiterzuverarbeiten. Allerdings müsste das Element dann zwischen den beiden Umgebungen ständig das Element für meine Schleifen hin- und hergereicht werden, das ist vermutlich weniger performant, als das einmal am Stück durchzugehen und das komplett in Javascript durchzuziehen, ohne vorher zurückzuspringen.

    /**
     * @param Client $client
     * @param RemoteWebElement $element
     * @throws \Exception
     */
    private function makeElementTreeVisible($client, $element): void
    {
        if (!$element->isDisplayed()) {
            $response = $client->executeScript('
                var element = arguments[0];

                function isVisible(elem){
                    return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length )
                    && window.getComputedStyle(elem).visibility !== "hidden";
                }

                while (!isVisible(element) ) {
                    element.setAttribute("style", "display: block !important")
                    element = element.parentNode;
                }
            ', [$element]);
        }
    }

Vermutlich nicht die super-perfomanteste Weise, aber zumindest sollten damit alle Edge Cases abgebildet sein.

Andere Möglichkeiten wären noch: den Style für alle Elemente setzen oder versuchen alle CSS-Styles zu entfernen (hilft halt nicht gegen Inline-Styles).

Habt ihr dieses Problem schon einmal gehabt? Wie habt ihr das gelöst?

Kategorien
Allgemein

Wochenbericht 2021.12

  1. California Bans ‘Dark Patterns’ That Trick Users Into Giving Away Their Personal Data – Strengthening The State’s Landmark Digital Privacy Legislation
  2. University of Helsinki language technology professor Jörg Tiedemann has released a dataset with over 500 million translated sentences in 188 languages
  3. How to Create a Shrinking Header on Scroll Without JavaScript
  4. Bestandsdatenauskunft mit Passwortherausgabe verabschiedet

Was zum Lachen: Meanwhile on Mars #16 – Waiting for 2028

Kategorien
Allgemein

Corona, Agile, Hausaufgaben, Kanboard.

Aktuell sind wir als Eltern auch mit einem Grundschulkind zu Corona-Zeiten zuhause. Homeschooling und Home-Office, yeah! Dazu ist meine Frau Mitglied einer Abschlussklasse, was die Situation deutlich verkompliziert.

Wir versuchen dabei, das ganze möglichst gelassen anzugehen, auch wenn wir mittlerweile echt müde von den Maßnahmen sind. Wir halten uns daran und sind im Zweifel eher etwas vorsichtiger als andersherum, in der Hoffung, dass der Spuk dann schneller rum ist.

Wir haben dabei mit der Schule von Kind#0 wirklich Glück. Die Lehrerin ist engagiert, technikaffin, kennt als Mutter von ähnlich alten Kindern auch die aktuellen Herausforderungen für Familien. Sie hält jeden Morgen mit den Kindern eine 30-60-minütige Videokonferenz mit der gesamten Klasse. Wie ein Daily, es heisst aber “Morgenkreis” (ich überlege, meiner Firma auch eine entsprechende Umbenennung vorzuschlagen…). Dazu üer die Woche verteilt Kleingruppen mit einer ähnlichen Zeitspanne in der “Unterricht” mit Screenshariung und Whiteboard gemacht wird.

Trotzdem gibts Probleme.

  1. Die Stimmung.
  2. Der Workload / Mental Load
    Zwei Kinder, Schule der Mama, Schule von K#0, Vollzeitstelle bei Papa, K#1 ist eigentich im Kindergarten und hat daher keine wirkliche Aufgabe vormittags.
  3. Schulaufgaben
    Wer ein Grundschulkind hat, weiß wie Kinder sich beim Thema Hausaufgaben gehen lassen können. Die Wochenpläne, die ja recht verbreitet sind, fühlen sich für die Kinder dabei an, als haben Sie nur Hausaufgaben.

Stimmung und Workload.

Die Themen sind relativ stark verknüpft, da hoher Workload, ständiges Hinterherräumen und darum Kämpfen zu müssen, auch mal in Ruhe Arbeiten zu können, einfach zusätzlich und unnötig an den Nerven zehrt. Die Kinder sind auch gestresst. Ein Kind vom Nichtstun, eins von den Uuuuuuunmengen an Hausaufgaben.

Retros

Wir haben uns überlegt, eine Retrospektive oder “Dailies” mit den Kinden gemeinsam zu machen und einen festen Anker im Tagesplan zu haben, bei dem man den Tag, was gut lief, was nicht gut lief und was man vielleicht daran ändern kann. Das Muster hierbei ist der 10-Minuten-Familienrat von Silke von agile parenting. An Wochenden ergänzen wir das oft mit einer “Was haben wir heute jeweils vor / zu tun” Komponente beim Frühstück.

Vor dem eigentlichen Gespräch machen wir dabei ein kleines Stimmungsbild, wie der jeweilige Tag so war, per Daumen (gut, mittel, doof). Ich bin das Buch in dem unsere “Tagesthemen” drinstehen mal durchgegangen und hab die Daumenzahlen in eine Tabelle geschrieben.

Ich finde, die Aggregation der Werte auf Wochendurchschnitte offenbart: Tiefpunkt ist der Schulbeginn in Hessen. Die erste Woche war der Horror. Von da an geht es bergauf.

Lebensregeln

Wir haben einen Weg gesucht, das gemeinsame Zusammenleben sinnvoller beschreiben zu können, so dass auch K#1 damit gut klarkommt. Gefunden haben wir die “Lebensregeln” von Rebecca und Mauricio Wild:

  • Wir bemühen uns, niemanden zu verletzen.
  • Wir bemühen uns, nichts zu zerstören.
  • Wir bemühen uns, andere nicht zu stören.
  • Wir beteiligen uns an der Arbeit.
  • Wir bemühen uns, Ordnung zu halten.

Damit haben alle die gleiche Basis und alle haben dem zugestimmt. Das macht es im täglichen Leben etwas einfacher, wenn man um Hilfe bittet, oder Konflikte auftreten.

Das Thema Stimmung ist seitdem besser geworden. Machen wir uns aber nichts vor: Es gibt immer Tage, die 💩 laufen.

Hausaufgaben – Wochenpläne – Kanboard

In der Corona-Zeit werden Wochenpläne von den meisten Lehrern verteilt. Das ist aus meiner Sicht gar nicht schlimm und und fördert im besten Fall auch die Selbstorganisation. In unserem Fall haben wir folgende Dinge versucht:

Woche 1: Wochenplan as-is, unser Kind hat sich geweigert irgendeine Form der Forschrittsnotation zu machen, trotz mehrfachem guten Zureden und Hilfangeboten. Das endete damit, dass wir Donnerstag und Freitag viele Dinge aus der Woche nachholen mussten – Frust auf allen Seiten. Online-Aufgaben sind aus der Betrachtung tatsächlich rausgefallen.

Woche 2: Wir haben im Wochenplan die Aufgaben genauer ausgeschrieben: Wo “AH Seite 1” stand, haben wir Sonntag geschaut wie viele Aufgaben es dort gibt und diese als Abzuhakende Aufgaben dazugeschrieben. Das hat in Woche 2 gut funktioniert, in Woche 3 dann nicht mehr, trotz Bitten, Hilfsangeboten und Co. Das war Donnerstag/Freitag dann nicht mehr ganz so viel wie Woche eins, aber wieder viel zu tun.

Woche 4: Experiment: Kanban Board, digital. Ich habe zuhause auf dem NAS die Software Kanboard installiert, ein Projekt mit mit und dem Kind angelegt. Lustige Avatare und ein bisschen Styling und los geht’s.

Dazu gab’s ein paar Automatische Regeln, die die Tickets je Kategorie (Schulfach) eingefärbt haben, je nach Spalte automatisch Bearbeiter zugewiesen haben:

  1. Zu erledigen: Niemand
  2. Bereit: Enthält automatisch die Aufgaben des aktuellen Tages, Bearbeiter: Kind
  3. In Arbeit: Die Aufgaben, die das Kind rüberzieht
  4. Kontrolle: Der Bearbeiter wechselt automatisch auf Papa
  5. Fertig: Kein Bearbeiter

Der Verlauf der Woche ist in der Galerie zu sehen. Das lief ziemlich gut, das Kind hat ein Notebook und das Kanban-System war schon bekannt, so dass die digitale Umsetzung kein Problem war.

Am Ende der Woche haben wir uns dann zusammen kurz die Statistiken angeschaut, die Kanboard generiert, wenn man es mit den richtigen Daten füttert und haben festgestellt, dass der Flaschenhals der Hausaufgaben im Verlauf einer Aufgabe bei der Kontrollstelle liegt…

Für alle, die auf ein spannendes Experiment haben: Probiert es aus, die Automatischen Regeln sind auch unten in der Galerie.

Was noch zu sagen war: Kanboard bietet eine wunderbare Excel-Import-Vorlage an, mit der man so einen Wochenplan fix runtertippern und dann importieren kann. Wer ein Beispiel dazu haben möchte, schreibt mir am besten eine E-Mail.

Kategorien
Allgemein

Wie Corona Familien agile Prinzipien näherbringt.

Der 16.03. hat unser Leben in Hessen von einem auf den anderen Tag umgekrempelt. Alles was sicher und stabil lief, Arbeit, Kinderbetreuung, etc. wurde sich von einem auf den anderen Tag in Frage gestellt. Schule zu, Kita zu und nebenbei arbeiten, wie soll das gehen?