Skip to content

Latest commit

 

History

History
180 lines (128 loc) · 12.8 KB

DOCUMENTATION.md

File metadata and controls

180 lines (128 loc) · 12.8 KB

ToyBlocks

Dieses Dokument soll zukünftigen Entwicklern einen Überblick über verwendete Technologien liefern und eine kurze Einführung in den Programmcode geben.

ToyBlocks ist ein webbasiertes Lernspiel für Studierende des Fachbereichs Architektur, das im Rahmen des Basiskurses Architekturgeschichte (Modul 312) als interdisziplinäres Konzept zwischen den Fachbereichen Architektur und Informatik der TU Darmstadt entstanden ist.

Ziel dieses Studienprojektes ist es, den Studierenden zusätzlich zu den Referaten im Basiskurs Grundlagen zur Architekturgeschichte zu vermitteln, um Gelerntes zu vertiefen und den eigenen Wissensstand zu testen.

Momentan wird ToyBlocks unter https://toyblocks.architektur.tu-darmstadt.de/ gehostet.

Mitwirkende:

  • Franziska Lang
  • Gabriel Dette
  • Marion Boos
  • Stefanie Müller

Entwickler:


Technologien und Architektur

  • node.js als Serverplatform
  • npm zur Verwaltung von node.js-Modulen
  • mongoDB: Document-Database
  • graphicsmagick zur Bildverarbeitung/-skalierung
  • http-proxy als reverse proxy für https-Verbindungen
  • forever stellt sicher, dass die node-Applikation u.A. bei Abstürzen neugestartet wird
  • init-Skripte für die node.js-Applikation, mongoDB sowie den http-proxy

Die Software läuft zurzeit auf einem Debiansystem. Für den Stack wurde der Benutzer production eingerichtet, auf den per SSH nur ein key-basierter Login erlaubt ist.
Lediglich der http-proxy wird mit Root-Rechten gestartet um den Port 80 öffnen zu können. Sobald dies erfolgt ist, werden die Root-Rechte wieder abgegeben.

Änderungen können zu dem git remote ssh://[email protected]/home/production/repos/toyblocks gepusht werden.
Ein git post-receive hook kopiert die Änderungen nach /home/production/apps/toyblocks und forever startet die Applikation neu, da es die Dateiänderungen bemerkt.
Node.js ist in /home/production/node/latest installiert, was das updaten und wechseln von Versionen vereinfacht.
Logs werden im Verzeichnis /home/production/logs gespeichert.
Der Datenbankspeicher liegt in /home/production/dbs/mongo.

Abhängigkeiten und Anforderungen

Die wichtigsten verwendeten node.js-Module:

  • express in Version 3 als Web-Framework
  • Dustjs als Templating-Engine (Linkedin-Fork)
  • mongodb als mongoDB-Client
  • gm als node.js-wrapper für graphicsmagick

Alle node.js-Abhängikeiten können durch einen einzigen Aufruf von npm install im Verzeichnis installiert werden. Die Dependencies sind hierfür in der Datei package.json definiert.

Eine Beispieldatenbank liegt im Ordner toyblocks_dump/.
Diese kann durch mongorestore toyblocks_dump wiederhergestellt werden. Druch den zusätzlichen Parameter --drop wird die bestehende Datenbank überschrieben.

ToyBlocks kann in zwei Modi verwendet werden - production oder development. Diese unterscheiden sich u.A. in der Art des Loggings. Der Modus wird durch eine Linux-Umgebungsvariable bestimmt, die sich auch im init-Skript wiederfindet.

Entwicklungsumgebung

Die Frontend-Dependencies werden durch Bower in der Datei bower.json verwaltet.
bower install lädt alle Pakete in bower_components/.
Bower wird hierfür am besten global installiert durch npm install -g bower.

Als build-Tool wird Grunt verwendet. Auf dem aktuellen Stand gibt es einen Task, der in Gruntfile.js spezifizierte Dateien, die von Bower geladen wurden, in die entsprechenden Ordner kopiert.
Um Grunt verwenden zu können, muss das grunt-cli durch npm install -g grunt-cli installiert werden. Ein Aufruf von grunt init führt dann den oben genannten Task aus.

Dadurch können sehr einfach Frontend-Pakete hinzugefügt und entfernt werden.

Eine Liste der wichtigsten Pakete, die im Frontend verwendet werden:

Im Projektverzeichnis befindet sich außerdem die jshint-Konfigurationsdatei .jshintrc, die den Airbnb JavaScript Style Guide sicherstellt.
Nachdem jshint durch npm install -g jshint installiert wurde, kann eine Datei durch Aufruf von jshint dateiname.js überprüft werden.


Dokumentation

Beim Aufruf einer Webseite wird die URL in der Hauptapplikationsdatei app.js dispatcht. URLs sind immer in der Form /area/controller/action. Wenn eine der drei URL-Teile fehlt, wird sie durch index ersetzt. Anschließend wir der richtige Controller instanziiert. Es gibt einen Grundcontroller in /controllers/Base.js, von dem alle Controller extenden. Dort sind Funktionen, die in jedem Controller benötigt werden. Danach hat jede Area einen Controller mit Grundfunktionen für die entsprechenden Controller aus der Area. Dadurch, dass jeder Controller den Base-Controller erweitert, kann man Funktionalitäten überschreiben wie zum Beispiel Aufruf-Rechte eines Controllers.

Controller

Der Base-Controller bekommt beim Insanziieren von der app.js den Mongo-Datenbank-Handler, das MongoDB-Objekt, das Request-Objekt von Express.js und das Response-Objekt übergeben. So kann man in jedem Controller dadrauf zugreifen. Wenn ein Controller insaziiert ist, wird die Funktion run() aufgerufen, die die passende Action darin aufruft. In der Action ist dann der eigentliche Code für diesen Seitenaufruf. Nach allen Operationen wird this.view.render() aufgerufen, die das passende Template lädt.

View

Die this.view Variable ist eine Insanz der View, die sich in der Datei views/Base.js befindet. Dort werden Templates geladen und entsprechende Basis-Variablen (wie z.B. _area, _controller oder _action um in jedem Template zu wissen, wo man sich befindet - hilfreich für das Layout-Template) an die Templates übergeben.

Templates

Die Templates befinden sich im Ordner templates/ und sind ähnlich den Controllern angeordnet, d.h. für jede Area und Controller ein Ordner. Je Action gibt es ein Template, das so wie die Action selbst mit .dust als Endung benannt wird. Dust.js ist die Template-Engine. Mehr dazu auf der Homepage von dust.js.
Die meisten Templates inkludieren das Layout unter templates/layout/layout.dust. Dieser wiederum inkludiert den Header, Footer und Content. Content ist aufgeteilt in ContentHead, Content und ContentFoot. Dies ist praktisch zum Beispiel für die Ajax-Pagination. Bei Anfragen über Ajax setzt man bei der view über die Funktion setContentOnly(true) den Indikator, dass nur der "Content"-Inhalt gerendert werden soll und dieser wird entsprechend nur in diesen Bereich durch das Paginations-Javascript automatisch geladen.

Javascript

Die allgemeinen Javascript-Funktionalitäten befinden sich unter public/js/. Die Hauptdatei für das Toyblocks Projekt ist main.js. Dort werden Formularelemente, die Pagination und wichtige Modals konfiguriert. Spezieller Javascript-Code, der nur in jeweils einer Action benutzt wird, ist inline in dem Action-Template eingebunden, damit sich die js-Datei nicht unnötig aufbläht und der Code leicht zu finden ist.

Stylesheets

Bei den Stylesheets verhält es sich Ähnlich den Javascript-Dateien. Das meiste kommt vom Bootstrap-Framework. Spezielle Styles werden in der public/css/main.css für das Projekt angepasst. Styles die nur in einer Action vorkommen, werden auch inline nur in der Action eingebunden, um das Haupt-Stylesheet nicht unnötig aufzublähen.

ToyBlocks-Objekte

Die Struktur von Toyblocks basiert auf einem simplen selbstentwickelten Objekte-Attribute System. Es gibt eine Verwaltung für Attribute, die grundlegende Attribute mit ihren Eigenschaften anlegen kann. Diese haben einen bestimmt Typ, Titel und ob sie vordefinierte Werte haben. Mögliche Attribut-Typen sind bislang:

  • string - Einfaches Textfeld für Namen, Titel und Ähnliches. Vordefinierte Werte werden als eine Auswahl-Selectbox gezeigt.
  • text - Textarea für längere Texte mit Summernote als Texteditor
  • int - Einfache Zahlen, die so auch validiert werden
  • bool - Ja/Nein Auswahl
  • image - Bilder-Upload. Die Bilder werden in der der images-Collection in Mongo abgelegt.
  • objecttype - Referenzen zu anderen Objekten. In einem neuen Modal kann man Objekte aus anderen Objekttypen referenzieren.

In der Objekte-Verwaltung wiederum setzt man Objekt-Typen aus den vorhandenen Attributen zusammen. Für einen neuen Objekt-Typ gibt man einen technischen Namen ein, der später als der Name der Collection in der Datenbank dient. Einen Titel und die Attribute die sich darin befinden. Bei den Attributen kann man bestimmen, ob sie multipel sein dürfen und ob sie obligatorisch sind. (Anzeigbar wird momentan nicht genutzt, sollte aber dazu dienen, um in dem Objekte-Anzeige Interface nur anzeigbare Attribute anzuzeigen, um es überschaubar zu halten.) Wenn ein Typ angelegt ist, kann er angeklickt werden um die ensprechenden Objekt in diesem Typ zu sehen, zu bearbeiten und neue zu erstellen.

Beispielhaft am Fehlstellen-Spiel: Wir haben einen Objekt-Typ mit Titel, Fehlstellen-Bild, Kategorie, korrekten Einzelteilen und Lösungsbild. Ein anderer Objekt-Typ Fehlstellen Einzelteile beschreibt die Einzelteile, die in den Kategorien vorkommen können. Wenn man ein Spiel beginnt, wird einem das Fehlstellen-Bild mit Lücken angezeigt. Aus den Einzelteilen werden alle Einzelteile aus der Kategorie des Spiels geladen. Durch die Referenz im Spiel auf das korrekte Einzelteil, weiß das Spiel die richtige Lösung. Referenzen sind immer über die MongoIDs verknüpft.

Benutzer

Als Nutzer von Toyblocks kann jeder mit einer TU-ID bzw. entsprechendem Login werden. Man wird über den SSO eingeloggt und falls nicht in der users-Collection existent ensprechend angelegt. Wir benutzen das SAML1.1-Protokoll. Im Base-Controller in der checkLogin-Funktion ist die komplette User-Login Verwaltung beschrieben.

Rechte

Für die Rechte ist die Funktion getRightLevel() verantwortlich. Ein Besucher der Webseite hat ein Recht von 400, ein Student 300, ein Moderator 200 und ein Administrator 100. Damit ist sichergestellt, dass zum Beispiel ein Moderator alles machen kann, was auch ein Student machen kann, aber nicht das, was für Admins erlaubt ist. Die Zahlen sind im Hunderter Bereich, damit es durch eventuell kommende zusätzliche Rechte einfach erweitert werden kann.

Datenbank

Für die Datenbank wird MongoDB verwendet. Dazu muss eine Table namens toyblocks existieren. Dazu muss auf dem Server mongodb als Service laufen. Dies kann gestartet werden mit

sudo service mongodb start

Zusätzlich muss für die Suche die Volltext suche innerhalb MongoDB aktiviert werden.

mongod --setParameter textSearchEnabled=true

Um die Demo Datenbank zu importieren

mongorestore --db toyblocks toyblocks_dump_server/

Um ein Backup der Datenbank zu erstellen

mongodump --db toyblocks -o toyblocks_dump/

und danach gezippt werden mit

tar -zcvf dump.tar.gz toyblocks_dump/toyblocks