Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

January 22 2012

13:09

MySQL | Table Migration zu InnoDB

Ich durfte letztens einer schönen Schulung zum Thema MySQL lauschen. Dabei kam viel herrum. Ein Teil davon hat sich mit verschiedenen Storage Engines beschäftigt.

Ich habe mich entschieden den Großteil meiner Datenbanken zu InnoDB umzuwandeln. Welche Vor- und Nachteile das hatt sollte sich jeder vorher klarmachen. Stichwort: ACID und Fulltext-Search. Natürlich könnte man einfach mit ALTER arbeiten. Aber ich wollte nicht umbedingt die alten MyISAM Tables noch im FS liegen haben. Also alle Datenbanken droppen und den geänderten Dump wieder einspielen, sodass die Tables neu (mit InnoDB) angelegt werden.

Zuersteinmal eine Liste mit den generieren mit den Datenbanken die man Bearbeiten möchte. Es ist zu beachten, dass man den mysql Table selbst nicht auf InnoDB umstellen möchte.

mysql -u root -p -e "show databases;" -N --batch | grep -v ^information_schema$ | grep -v ^mysql$

Die Liste der Datenbanken wird nachher noch hilfreich sein. Danach will man wahrscheinlich erstmal alle Dienste beenden, die auf dem MySQL zugreifen (Apache, Tomcat, whatever). In der my.cnf habe ich dann folgende Optionen für die InnoDB spezifiziert.

defaulot-storage-engine = InnoDB
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

Anschliessend den Dump erstellen und alle ENGINE=MyISAM durch InnoDB ersetzen:

mysqldump -u root -p > all-databases.sql
sed -i -e 's#ENGINE=MyISAM#ENGINE=InnoDB#g' all-databases.sql

Vorsicht. Hier ist mysql als Datenbank mit gedumped! Mir ist dabei keine wirklich einfache Zeile eingefallen die mit Suche/Ersetze Spielchen mysql ausschliesst. Es gibt bei mysqldump die Option “–ignore-table=” aber auch hier hätte ich jeden mysql Table einzeln nennen müssen. Ich hab die Datenbank dann einfach per hand aus dem Dump herausgelöscht.

Außerdem sollte man seinen Datenbank Dump nach FULLTEXT durchsuchen, da dieser von InnoDB nicht unterstützt wird. In meinem Fall hat es nur ein altes Forum das niemand mehr benutzt betroffen, weshalb ich die Zeile einfach löschen konnte.

grep "FULLTEXT" all-databases.sql

Um jetzt alle Datenbanken zu droppen hab ich mir folgende Line gebastelt:

for x in $(mysql -u root -phierstehteinpasswort -e "show databases;" -N --batch | grep -v ^information_schema | grep -v ^mysql$) ; do mysql -u root -phierstehteinpasswort -e "drop database $x ; " --batch ; done

Nach der Bearbeitung kann man den Dump mit der neuen Engine für die Tables wieder einspielen:

mysql -u root -p < all-databases.sql

December 21 2011

15:30

Arduino | Ich bau mir einen Synthesizer

Vor ca. 2 Wochen habe ich auf der Suppe vom K4CG ein Video über einen auf Arduino basierten Synthesizer. Die “Firmware” die darauf läuft nennt sich “Auduino”.

Auf deren Projektseite habe ich mich dann etwas schlau gelesen und wie auch schon bei dem Megabitmeter über tinkersoup.de meine Teile bestellt. Auf der Projektseite ist die Konstruktion des ganzen finde ich zwar nicht sonderlich gut beschrieben, aber man kommt mit ein bisschen Googeln und Reverse Engineering schon weiter.

Habe dabei aber einen Arduino Nano benutzt, weil mir die Anschlüsse bzw “Architektur” besser gefällt und ich nicht erst ein Breakout Board von Seriell auf USB nachkaufen musste. Entgegen aller Erwartungen musste ich die Firmware dafür nichtmal modifizieren, da auch bei diesem Board ein ATMega328 verbaut ist.

Ich habe mir wegen der einfacheren Anbringung am Nano so eine Art Halterung/Breadboard mitbestellt, in dem ich die Adern mit Schrauben einfacher verbauen konnte.

Die Potenziometer (wieder was, das ich gelernt habe) sind in Reihe an den Ground und den 5V Pin geschlossen. Der jeweils mittlere Pin der Drehschalter kommt an die Analog Pins 0 bis 4.

Danach kam der (für mich) kniffligere Teil. Der Audio Jack (bzw. Klinke Buchse) hat von Haus aus 5 Pins. Auf der Projekte Seite von Auduino nur Input und Ground. Nach bisschen schlaulesen in Wikis und Foren scheint es, als würden die verschiedenen Revisionen von Klinke andere Features mit sich bringen. für den Mini Synthesizer hätte vollkommen Klinke Mono ausgereicht. Diverse Zusatzfunktionskanäle sind da eigentlich überflüssig aber im Audio Jack bei TinkerSoup integriert.

Nach etwas Trial and Error Verfahren den weg für Doofe gewählt. Ich hab ehrlichgesagt einfach ein altes Klinke Stecker auf Buchse Kabel aufgeschnitten und mir die Belegung auf der Steckerseite angesehen.

Bei 3poligen Klinken Steckern sind die vorderen beiden Kontakte fürs Signal (Links, Rechts) und hinten für Ground. Habe dann die beiden Signaladern auf der Buchsenseite verdrillt und wie vorgesehen in den Digitalen Pin 3 geklemmt. Ground natürlich an seine Stelle.

Im Endeffekt wars dann schon fertig. Firmware mit dem Arduino IDE auf den Chip geladen und hat auch schon funktioniert. Aber weil ich dann ständig die Potenziometer durcheinander gebracht habe, hab ich noch eine alte Plastikbox aus dem Baumarkt meiner Wahl benutzt, die entsprechenden Löcher gebohrt dort das ganze eingebaut.

Etwas smoother ;) Noch ein paar kleine Kostproben von einem wirklich unbegabten Synthesizer-Bediener. Beim hören etwas aufpassen, ab und zu ist mir da ein Ton entglitten.

Auduino Sample Mp4
Auduino Sample WAV 16 bit 22 Kkhz

November 26 2011

12:53

Loading | Eine Bash-Progress-Bar

Für ein kleines Projekt, an dem ich so nebenher immer etwas schreibe habe ich eine Art Ladebalken gebraucht. Habe ein paar wirklich coole Lösungsansätze gefunden, aber es läuft meistens auf Depencies raus (pv z.B.) oder nicht wirklich mein Anwendungsfall.

Ich hab mir dann kurzerhand was selber gebastelt. Ich gebe zu ich hätte es auch so gestaltet können das es einfach nur für meinen Use-Case gereicht hätte, aber das erschien mir unsinnig. Wenn ich mich schon einen halben Abend hinsetze, dann können ja evtl. auch mehr Menschen was davon haben. So entstand dann die bash-progress-bar.

Zu allererst besteht der Ladebalken aus einer while true Schleife. Sollte die Bar in ein Skript einbaut werden wäre die Bedingung dem Skript anzupassen. Ob das jetzt ein test -e auf ein File ist das getouched wird oder eine Art Counter bleibt jedem selbst überlassen.

$ git clone git://github.com/noqqe/bash-progress-bar.git
$ cd /bash-progress-bar/
$ ./loading.sh
> [            #####       ]

Alle Parameter sind natürlich anpassbar. Ich habe versucht so gut wie alles anpassbar zu halten. Ich hoffe das ist mir gelungen ;)
./loading.sh Groesse Geschwindigkeit Rahmen-Anfang Füllcharacter Rahmen-Ende
./loading.sh 50 0.02 [ "######" ]

Ohne irgendwie ein GIF-File zu erstellen kann ich das jetzt leider schlecht im Blog demonstrieren. Deshalb: ausprobieren :) Mehr Infos auf der Github Page.

Fragen, Anregungen, Kritik erwünscht!

October 15 2011

14:02

Git and the Unix philosophy

Mein Feedreader hat heute einen Post von Julius ausgespuckt, den ich so gut fand, dass ich ihn hier rezitieren möchte.

Git follows Linux’s philosophy of refusing to protect you from yourself. Much like Linux, Git will sit back and watch you fuck your shit right up, and then laugh at you as you try to get your world back to a state where up is up and down is down. As far as source control goes, not a lot of people are used to this kind of free love.

Ich rezitierte also Julius Zitat. Blogpost-Inception?

October 02 2011

21:58

Statistiken | Einfache Graphen mit R und MySQL Anbindung

Immer mal wieder reizt mich die Programmiersprache für Statistiken R. Um diesen Reiz dann auszuleben hab ich vor ein paar Monaten angefangen kleine Graphen für den zufallsbasierten Simulator ZRE zu bauen. Das Spiel “läuft” einfach 24/7 und schreibt für jedes geschehene Event Einträge in die Datenbank. Diese Einträge werte ich dann mit Hilfe von R aus.

Dazu gibt es ein Skript. Nämlich zre.R (Ob das die Konvention bei R-Skriptnamen ist, kann ich nicht sagen ;) )

#!/usr/bin/env Rscript

### General R-Script
# MySQL
library(RMySQL)
con <- dbConnect(MySQL(), user="", password="", host="", client.flag=CLIENT_MULTI_RESULTS)
# Style
zre_colors <- colors()[grep("green",colors())]
zre_mint <- colors()[c(48,86,50)]

Im Klartext wird aus dem CRAN Library Verzeichnis die Library RMySQL includiert und die Verbindung in der Variable con abgelegt. Ähnlich wie bei PHP. Für alle Debian / Ubuntu Benutzer empfiehlt sich aber, die Library einfach über das Paketsystem nachzuinstallieren.

$ aptitude install r-cran-rmysql

Standardmäßig sehen Graphen die mit R erstellt werden ziemlich mau aus. Die weiteren Variablen unter Style habe ich gewählt um mir die Colorierung der Graphen etwas zu erleichtern. Diese werden später einfach als Attribute in den Plots/Barplots gesetzt und ausgewertet. Ich fange einfach mal der Reihe nach an:

Die Abfolge ist immer ziemlich ähnlich. Zu aller Erst wird der Query für die Datenbank an die Variable sql übergeben. Diese Variable wiederrum wird zusammen mit der Connection an die Funktion dbGetQuery übergeben und das Ergebnis dessen schliesslich in zre_wins gespeichert. Anschliessend ein paar kleine Informationen an das Dateiformat übergeben und den Graphen bauen.

Die Funktion par lässt sich erstmal als eine Art Environment Funktion für Graphen verstehen. Hier werden Eigenschaften wie Schriftfarbe, Hintergrund, Axenfarbe, und Liniendicke definiert. Danach kommt (wie ich finde) der schwierigste Teil. Bauen des Graphen. Je nach Art des Graphen (Balken, Linien, Torte u.ä.) werden logischerweise verschiedene Parameter erwartet. Die Daten werden hierbei jetzt als Matrix an ein Balkendiagram übergeben. Weitere Informationen wie die Überschrift (main) und die Beschreibung der Balken (names.arg) werden einfach angefügt.

# Graph: Wins

sql <- paste("SELECT COUNT(id) AS sum, side FROM zombies.zre_wins GROUP BY side;")
zre_wins <- dbGetQuery(con, sql)
png(file="wins.png", width=400, height=400)
par(col="white", bg="transparent", col.axis="white", col.lab="white", col.main="white", lwd=2)
barplot(as.matrix(zre_wins$sum), main="Game Summary", names.arg=c(zre_wins$side), beside=TRUE, col=zre_mint)

Selbes Spiel wieder, nur mit mehr Balken und anderem Use-Case. Diesmal werden die 25 Konflikte mit den meisten Opfern visualisiert.

# Graph: Highest Kills

sql <- paste("SELECT id, kills FROM zombies.zre_kills ORDER BY kills DESC LIMIT 25;")
zre_matches_highest <- dbGetQuery(con,sql)
png(file="highestkills.png", width = 400, height = 400, bg="transparent")
par(col="white", bg="transparent", col.axis="white", col.lab="white", col.main="white", lwd=4)
barplot(zre_matches_highest$kills, zre_matches_highest$id, main="25 Highest Kills", beside = TRUE, ylab="Kills", col=zre_colors)

Aber da Balkendiagramme auch irgendwann Langweilig werden geht das natürlich auch anders. Die 25 letzten Konflikte werden im “Opferverlauf” wie folgt dargestellt:

# Graph: Kills

sql <- paste("SELECT kills FROM zombies.zre_kills ORDER BY id DESC limit 25;")
zre_kills <- dbGetQuery(con,sql)
yrange <- range(zre_kills$kills)
xrange <- length(zre_kills$kills)
png(file="kills.png", width=400, height=400, bg="transparent")
par(col="white", bg="transparent", col.axis="white", col.lab="white", col.main="white", lwd=4)
plot(zre_kills$kills, xlab="Games", type="b", ylab="Kills", main="Kills from last 25 Attacks", col=zre_mint)

Damit es nicht immer nur um Tote geht, auch mal was erfreuliches. Die Geburtenrate in ZRE steigt! :)

# Graph: BirthRate

sql <- paste("SELECT Month(date) AS month, count(id) AS born FROM (SELECT *, Month(date) AS M FROM zombies.zre_born) t Group by M; ")
zre_birthrate <- dbGetQuery(con,sql)
png(file="birthrate.png", width=400, height=400)
par(col="white", bg="transparent", col.axis="white", col.lab="white", col.main="white", lwd=3)
barplot(zre_birthrate$born, xlab="Month", ylab="Born Humans/Zombies", names.arg=c(zre_birthrate$month),main="BirthRate per Month", col=zre_colors)

Und auch das Wetter soll bei der ganzen Sache nicht zu kurz kommen. Hierbei bitte besonderes Augenmerk auf die Legende rechts oben. Eine direkte Zuordnung der Werte und Farben ist nicht nötig, da die Farben in der selben Reihenfolge von zre_colors befüllt werden wie die Balken. Die erschreckend hohe Zahl an Naturkatastrophen erklärt das aber trotzdem nicht :)

# Graph: Weather
sql <- paste("SELECT COUNT(id) AS count, weather FROM zombies.zre_weather GROUP BY weather ORDER BY count DESC;")
zre_weather <- dbGetQuery(con,sql)
png(file="weather.png", width=400, height=400)
par(col="white", bg="transparent", col.axis="white", col.lab="white", col.main="white", lwd=2)
barplot(zre_weather[,1], main="Weather in ZRE", beside = TRUE, col=zre_colors)
legend( 5, 40000, zre_weather$weather, cex=0.9, fill=zre_colors, col="white")

Das volle zre.R Skript befindet sich wie das meiste auf Github: https://gist.github.com/1031260

October 01 2011

11:12

Flattr | Man kann seine Meinung auch mal ändern.

Als dieses Micro-Payment System Flattr vor mehr als einem Jahr raus kam habe ich hier im Blog über Sinn und Unsinn des Dienstes sinniert. Ich konnte mich damals nicht wirklich entscheiden, ob mir das System gefällt oder nicht. In der Tat ist es eigentlich eher so, dass mir das Projekt Kulturwertmark vom CCC viel eher zusagt.

Im Moment ist es abe so, dass es keinen anderen verbreiteten Weg gibt Content bzw. Software von Privat-Menschen zu belohnen, weil er/sie mir geholfen hat. Deshalb (und auch weil mich die Oberfläche interessiert hat) habe ich mich dort angemeldet und verteile seit 2 Monaten etwas Geld hier und da. Vorwiegend an Podcasts, Taskwarrior und Blogs von Leuten die ich kenne. Ich habe initial 8 Euro überwiesen mit denen ich jetzt erstmal 4 Monate rumflattern werde. Das das nicht die Welt ist, ist mir klar.

Und da ich jetzt sowieso schon einen Account dort habe, habe ich auch meinen Flattr-Button im Blog (links) eingebunden. Es wird erstmal keinen individuell Button für einzelne Posts geben und es braucht sich auch niemand verpflichtet fühlen da drauf zu drücken.

September 25 2011

11:58

Taskwarrior | Migration von MyTinyTodo

Im Programm der Ubucon habe ich einen Vortrag von Dirk über Taskwarrior gefunden. Aus Gründen hat mich das Tool interessiert. Ich habe zwar bereits eine Todo-Verwaltung (nämlich MyTinytodo) aber trotzdem.

Nach zwei Tagen herumspielen und einem wirklich hervorragendem How-To hat mir Taskwarrior allerdings so gefallen, dass ich mich entschlossen habe MyTinyTodo aufzugeben und zu Taskwarrior zu wechseln. Da ich meine TodoListe aber auch gerne als eine Art “Log” verwende musste ich die Aufgaben erst aus MyTinyTodo migrieren.

Realisiert habe ich das über ein kleines Bash-Script, welches die Daten aus der MyTinyTodo MySQL Datenbank ausliesst und daraus automatisch Taskwarrior Statements formuliert. Allerdings: Ich habe absichtlich nur abgeschlossene Tasks über die “LOG”-Funktion von Taskwarrior einfuegt.

Aus dem Datenbank Eintrag:

mysql> select d_completed,  mtt_lists.name as liste, title from mtt_todolist, mtt_lists where mtt_lists.id = mtt_todolist.list_id order by d_completed desc limit 1;
+-------------+-------+--------------+
| d_completed | liste | title        |
+-------------+-------+--------------+
|  1307714692 | Home  | Miete zahlen |
+-------------+-------+--------------+
1 row in set (0.00 sec)

formuliert das Skript beispielsweise folgendes Kommando für Taskwarrior:

task log due:20110610 pro:IMPORT-Home Miete zahlen

Das passiert eben für jede Eintrag in der Todo-Datenbank, damit ich dort nachschlagen kann wann was passiert ist.

September 21 2011

19:16

DeadDrop | Erlangen – Schwabachanlage

Ich war dann schliesslich doch noch bei einem funktionierenden DeadDrop in Erlangen. Dem in der Schwabachanlage. Quasi also mein erster “Check-In” an einem funktionierendem DeadDrop.

Ich muss sagen der Inhalt war wenig bis gar nicht interessant. Allerdings muss das Bild, wie ich da mit Fahrrad, Laptop auf dem Lenker und Kabel in eine tote Mauer stehe ziemlich skurril ausgesehen haben.

“Gibts da Strom umsonst oder was ist da los?”

“Junger Mann, das is ja unerhört. Mit dem Laptop am Lenker Fahrrad fahren! Das ist eine Gefährdung für den Verkehr!”

“Ach, was wird das denn? Muss ich die Politzei verständigen?”

… um nur ein paar Zitate aufzuzählen. Zur Beruhigung aller: Ich bin natürlich nicht mit dem Fahrrad gefahren während ich den Laptop am Lenker hatte. Das (und den eigentlichen Grund meiner Anwesenheit) habe ich natürlich auch brav jedem erzählt der mich in den insgesamt nur 20 Minuten angesprochen hat. Insgesamt war das sogar witziger als der Deaddrop selbst. Werde das auf jedenfall wiederholen.

August 27 2011

11:10

Arduino | Ich baute ein Megabitmeter

Vor einiger Zeit hab ich über den Podcast von Tim Pritlove (NSFW) von dem Projekt MegabitMeter erfahren. Es hat mich ehrlichgesagt fasziniert. Der eigentliche (im Namen implimzierte) Zweck zwar weniger, aber gernerell einfach Werte über ein USB Device darstellen zu können. Genaue Anwendungsfälle gibts weiter unten.

Zunächstmal hab ich mich ausgiebig mit dem HowTo beschäftigt welches ich (bis auf ein paar Stellen) sehr gut finde. Die letzten Paar Unstimmigkeiten habe ich dann mit dem wirklich netten und zuvorkommenden Betreibern des Projekts via Mail abstimmen dürfen :) Das lag aber auch an meinen fehlenden elektrotechnischen Kenntnissen.

Ich muss dazu sagen, dass ich in der glücklichen Situation war und jemanden kannte, der in einer Firma tätig ist, die solche Messgeräte anfertigt wodurch ich keinen Kit kaufen musste. Das ist auch der Grund warum das Messgerät etwas anders aussieht.

Ich denke auch das der Sinn des Projekts eher das “do-it-yourself” ist und der wirtschaftliche Erfolg nur eine positiver Nebeneffekt der Betreiber ist… (Zumindest hoffe ich, dass ich das nicht falsch interpretiert habe). Außerdem schwierig war, dass der Kit 2 (incl. dem Arduino) nicht verfügbar war, da laut Twitter gerade keine Arduinio Nano in rauen Mengen billig einzukaufen sind. Den Arduino Prozessor habe ich deswegen von TinkerSoup.de geordert.

Wenn alles fertig gebastelt ist, kann man dem Gerät einfach via echo Werte übergeben.

$ echo "200" > /dev/ttyUSB0

Ein paar Anwendungsbeispeile:

Zufällige Zahlen auf das Gerät projezieren
while true; do RND=$(($RANDOM % 99 * 10)); printf "$RND\n" > /dev/ttyUSB0 ;echo $RND; sleep 2 ; done

Zombie Kill Meter (In Verbindung zu zombies.n0q.org)
while true ; do mysql -u user -ppw -e \"SELECT kills from zombies.zre_kills ORDER BY id DESC LIMIT 1;\" | grep -v ^kills ; sleep 3; done" > /dev/ttyUSB0

Port 80 Verbindungen des Webservers
ssh user@host "while true; do echo \$(( $(netstat -tapn | grep -c -e ':80\s*') * 100 )) ; sleep 2; done" > /dev/ttyUSB0

An weiteren Snippets bastle ich im Moment noch. Werden eventuell nachgereicht wenn Sie spruchreif sind. Am Ende noch ein riesen Danke für die Software und die Projektidee sowie das wunderbare HowTo an das Team von <a href=”megabitmeter.de”>megabitmeter.de</a>

August 25 2011

17:00

DeadDrop | Erlangen Kirchplatz

Komme gerade vom ersten Versuch zurück, mich mal an einen DeadDrop zu stöpseln. Leider erfolglos, weil broken. Der genaue Link zum (kaputten) DeadDrop: http://deaddrops.com/db/?page=view&id=395

Bei aller verwunderung gibt es in der Datenbank keinerlei Funktion einen Toten Toten Drop zu melden. Wie es der Zufall so will gibt es aber genau seit heute(!) einen neuen DeadDrop in Erlangen: http://deaddrops.com/db/?page=view&id=682

July 24 2011

16:56

Abschlussprüfung | Zentrales Versionskontrollsystem mit git und etckeeper

Nachdem ich letzten Donnerstag erfolgreich meine Ausbildung zum Fachinformatiker abgeschlossen habe, kann ich die dazugehörige Dokumentation / Präsentation hier veröffentlichen.

Dokumentation

Präsentation

Zu danken habe ich dabei hauptsächlich all den wunderbaren OpenSource Tools, die mir zur Erstellung und Umsetzung gedient haben. Um einige zu nennen:

  • LaTeX bzw. TeX-Live (Dokumentation)
  • HTML & Slidy (Präsentation)
  • git (Projektinhalt)
  • etckeeper von Joey Hess (Projektinhalt)
  • gitolite (Projektinhalt)
  • und natürlich allen Debian Developern, die die genannte Software paketiert haben :)

July 04 2011

18:42

Minecraft + Git + Bash =

Seit mittlerweile erstaunlich langer Zeit spiele ich Minecraft. Minecraft hält seine Daten in ~/.minecraft vor. Also Levels, Statistiken, Items. Das Minecraft Home Directory unter Versionskontolle zu stellen hat unter Umständen mehrere Vorteile, die ich hier kurz erläutern möchte :)

Initiales Setup

Als erstes muss das Verzeichnis initial eingerichtet werden. Initialisierung, hinzufügen aller Dateien und ersten Commit erstellen.

$ cd $HOME/.minecraft
$ git init
$ git add .
$ git commit -a -m "Initialer Commit"

Spielstände manuell Laden und Verwalten (Commits)

Einer der gravierendsten Vorteile. Wer wie ich oft an Klippen hinunter stürzt oder an einem (oder auch mehreren :P ) Creeper(n) scheitert wird das bestätigen können. Einmal gefallen/gestorben gibt es kein zurück mehr. Bis jetzt.

Die hypothetische “Herausforderung” scheint sich gerade aufzutun. Ob jetzt Creeper, Berg oder sonst was ist erstmal egal. Könnte auf jeden Fall kritisch für meinen Minecraft Character enden.

$ git commit -a -m "Ob man den Sprung ueberlebt?"

Nach einem kurzen Tab in die Konsole, sollte das Spiel erstmal gesichert sein und ich kann den Sprung wagen.

Anscheinend überlebt man nicht, aber genau das war auch der kritische Punkt. Genau jetzt bin ich in der Lage meinen alten Spielstand wiederherzustellen. Mit nachfolgendem Kommando verwerfe ich alle seit dem letzten Commit entstandenen Änderungen an meinem Spielstand. Vorher dringend aufs Minecraft Titelmenü zurückkehren!

$ git stash

Dieses Szenario lässt sich nicht nur auf gerade geschehene Ereignisse abbilden sondern auch zwischen Commits die längere Zeit her sind. Wenn nach einer halben Stunde/einem Monat klar wird, das der Minecraft Char gerade nur Müll verzapft hat, kann auch zwischen mehrere Commits hin und her gesprungen werden. Mit welchen git Kommandos das bewerkstelligt wird, bleibt jedem selbst überlassen.

git-revert macht den letzten Commit rückgängig, erstellt dabei einen neuen in dem die Änderungen enthalten sind. Das ist in soweit gefährlich, dass zwischenliegende Commits unberührt bleiben und eventuell in einen großen Haufen Datenmüll zerfallen(!). Eher Anwendung für den “Warp” an einen früheren Zeitpunkt X findet daher git-reset.

$ git reset 66a2594
# oder
$ git reset HEAD^

Das Working Directory wird damit auf einen Stand gebracht, wie es zum Zeitpunkt des angegebenen Commits aussah. Dieser kann somit auch weiter in der Vergangenheit liegen.

Automatische Speicherung (Bash-Einzeiler)

Allerdings muss ich zugeben, dass diese Praxis relativ schnell aufwendig wird. Immer zwischen Fenstern hin und her zappen ist ja auf Dauer auch eher zermürbend. Daher habe ich mir diese “Arbeit” von einer kleinen Bash Zeile abnehmen lassen.

$ SEKUNDEN=10 ; while true ; do git add . ; git commit -a -m "AutoSave $(date)" ; sleep $SEKUNDEN ; done

Ich denke es ist Geschmacksache wie oft bzw. in welcher Frequenz die Commits abgesetzt werden können. Bis jetzt bin ich mit ca 300 Sekunden (5 Minuten) am besten Gefahren. Die Commits rieseln vor sich hin und beeinträchtigen so in keinster Weise den Spielfluss.

[master bf9dd85] AutoSave Mo 4. Jul 19:56:17 CEST 2011
4 files changed, 15 insertions(+), 12 deletions(-)
rewrite saves/0pen_Running/level.dat (100%)
rewrite saves/0pen_Running/level.dat_old (100%)
[master 5ddedc8] AutoSave Mo 4. Jul 19:56:27 CEST 2011
4 files changed, 17 insertions(+), 19 deletions(-)
rewrite saves/0pen_Running/level.dat (100%)
rewrite saves/0pen_Running/level.dat_old (100%)
[master 2d33023] AutoSave Mo 4. Jul 19:56:37 CEST 2011
4 files changed, 10 insertions(+), 11 deletions(-)
rewrite saves/0pen_Running/level.dat (100%)
rewrite saves/0pen_Running/level.dat_old (100%)

Parallele Welten (Branches)

Um einfach mal ein Anwendungsbeispiel zu nennen: Wer in seinem virtuellen Minecraft-Keller mal raue Mengen an TNT gebunkert hat, möchte es nach Möglichkeit auch mal benutzen, right? Aber danach das ganze Dorf wieder aufbauen? Nee… Branching!

Das ist der Punkt an dem die Geschichte der lokalen Minecraft Map sich in zwei Teile spaltet. In einer wird das eigene Bauwerk Sorum und Gumorra mäßig untergehen und in der anderen weiterhin existierenden Welt tollen sich Pigs und Sheeps in Minecarts herum. Die Abzweigung lässt sich wie folgt bewerkstelligen.

$ git branch blowup
$ git checkout blowup

Jetzt kann man in aller Seelen Ruhe TNT verteilen und auch mal Destroyer statt Builder spielen. Tipp: Commit vor der Sprengung setzen :P Explosion immer und immer wieder von vorne genießen ;) Bemerkenswert sind außerdem die unterschiedlichen Abläufe von ein und der selben Explosion, aber dazu vielleicht wann anders ein Blogpost. Irgendwann wird aber auch das dann zur Routine und man wechselt via

$ git checkout master

wieder zu den Schäfchen. Der Branch “blowup” bleibt aber bestehen und lässt sich auch nach weiteren Spielständen immer wieder herbeirufen. Ich habe mittlerweile eine Art Branchset meiner “Lieblingssituationen” im Game, die ich immer wieder durchspielen kann, wie es mir gerade gefällt. Und nein es sind nicht immer nur Explosionen :)

Networking, Baby! (Remotes)

Mein Minecraft Setup mit allen Einstellungen und Spielständen zentral an einem Ort zu haben war ehrlich gesagt meine erste Motivation git einzusetzen. Ich spiele Minecraft auf 3 verschiedenen Maschinen (Ubuntu, Debian und sogar Mac OSX) und wollte keine 3 unterschiedlichen Maps pflegen müssen. Deshalb fing ich an auf meinem Server zwischen zu lagern. Ein eigens laufender git-Server ist hier aber Vorraussetzung! Freies Hosting bei beispielsweise Github fällt wegen der großen Datenmengen (ca. 300MB bei mir derzeit) und der fehlenden Privatsphäre flach. Remote-Server hinterlegen und aktuellen Stand pushen:

$ git remote add origin git@gitserver.com:minecraft
$ git push origin master

Remote-Server auf anderen hosts klonen:

# Ubuntu/Debian
$ git clone git@gitserver.com:minecraft $HOME/.minecraft
# Mac OSX
$ git clone git@gitserver.com:minecraft $HOME/Library/Application\ Support/minecraft

At least

Ich möchte nicht sagen, dass dies hier der ultimative Weg zum heiligen Gral in Minecraft ist. Manchmal weckt eben diese erzeugte “Sicherheit” durch den Reset eine gewisse “Wayne…” Einstellung in einem, die dem Spielspaß ein Kleinwenig den kitzel raubt. Gerade am Anfang hat es mir aber extrem geholfen, nicht bei jedem Wipe alle Items zu verlieren oder sich nach einem Ausflug in den Wald wieder “zurück warpen” zu können.

Auf weitere Ideen im Umgang mit Minecraft und Git freue ich mich natürlich wie immer :)

May 22 2011

18:38

Beats | Eine in Ruby geschriebene Drummachine

Neulich habe ich voller Begeisterung das Drummachine Projekt Beats entdeckt. Beats stellt so in etwa die Musicbox für Nerds dar. In einem Verzeichnis mit einem Set an *.wav Dateien (wohl der Standard) legt man eine Art Konfigurationsdatei, welche durch Beats interpretiert wird. In einer gewissen Syntax beschreibt man dieses Lied und dessen Abfolge.

Das Traurige an der Sache ist eigentlich lediglich, dass ich mir bewusst geworden bin, wie wenig Kreativität/Können ich im musikalischen Bereich vorzuweisen habe. Teilweise sind beim Herumexperimentieren zwar Interessante Ergebnisse entstanden, aber nichts wofür ich mich nicht schämen müsste ;)

$ beats song1.txt song.wav
$ open song.wav

Ich hab dann allerdings kurzer Hand begonnen, den Vorgang zu automatisieren. Erst wollte ich es outsourcen, aber dann habe ich es doch automatisiert. Da die ganze “Ich baue mir ein neues Lied”-Sache nur auf einem einzigen File beruht, dachte ich mir dass sich das mit Sicherheit auch automatisch generieren lässt.

Das Skript das dabei herauskam, taufte ich randombeats. Wie alles was ich in letzter Zeit tue habe ich es natürlich auf github veröffentlicht.

https://github.com/noqqe/randombeats

Benutzung:

Ins jeweilige Verzeichnis mit den Roh-Daten kopieren/wechseln und Skript ausführen.

$ git clone http://github.com/noqqe/randombeats
$ cp randombeats/randombeats.bash /path/to/music
$ cd /path/to/music
$ ./randombeats.bash > randomsong.txt
$ beats randomsong.txt
$ open randomsong.wav

Raus kommen allerlei sehr Interessante und manchmal auch schöne Rhythmen. Aber manchmal auch akkute Ohrenschmerzen verursachen. Ein paar davon sammle ich mittlerweile in einem separaten Branch im Git-Repo. Diesen kann ich aber nicht uploaden, weil die größe meines Github Accounts auf 300MB beschränkt ist. Aber vielleicht finde ich anderweitig Möglichkeiten die Ergebnisse zu publizieren.

Mittlerweile habe ich folgenden Befehl in einer Schleife laufen.

./randombeats.bash > rnd.txt && beats rnd.txt && open rnd.wav

An Feedback, Kritik oder Anmerkungen zu Verbesserungen an den Eckdaten des Skripts bin ich wie immer sehr interessiert :)

April 20 2011

10:14

Commandline Tools | PDFs zusammenführen

Aufgrund meiner aktuell vorherrschenden Bewerbungsphase wollte ich ein paar PDF Dateien (hauptsächlich Zertifikate und Zeugnisse) in eine PDF Datei zusammenführen. Auf der Suche nach einem derartigen Programm liefen mir natürlich allerlei (dem anschein nach) hübsche Windows Tools für diese Aufgabe über den Weg. Wie schon oft, fand ich dann aber im Unixboard meine Antwort.

Das Commandline Tool pdftk. Wunderbar für Debian und Ubuntu paketiert.

$ sudo aptitude install pdftk

Ich muss trotzdem zugeben, dass die Syntax mir etwas ungewöhnlich erschien, aber nicht unbezwingbar ist :) Nach ein paar Blicken in die Manpage, kam ich auch da an wo ich wollte.

$ pdftk novell-cert.pdf ripe.pdf lpic-1.pdf cisco-ccna1.pdf cat output Zertifikate.pdf
  \___/ \________________________________________________/  \_/ \____________________/
    |                            |                           |             |
    |                            |                           |             \- Ausgabe an
    |                            |                           |                Zertifikate.pdf
    |                            |                           |
    |                            |                           \- Ausgabe der PDFs
    |                            |
    |                            \- Angabe aller zu kombinierenden PDFs
    |
    \- Programmaufruf

April 16 2011

14:48

statistical | It’s about internal functions.

Als ich statistical auf GitHub hochgepushed habe, fing ich an mir Gedanken über die Leistungsfähigkeit des Scripts zu machen. Ich meine es verhielt sich in Anbetracht der Daten (in meinen Augen) wunderbar. Die Key Länge wird bis zu 4 Tab-Längen mit skaliert, genauso wie die Values, in Form der Bars. Aber wie verhält sich es mit größeren Datenmengen?

Diesbezüglich wollte ich eine kleine For-Schleife benutzen um mehrere zufällige Werte zu generieren und in statistical zu pipen.

time for x in $(seq 1 6000); do echo "$x:$RANDOM" ; done | statistical > /dev/null

Das Ergebnis war mit 6000 Datensätzen und guten 7 Minuten relativ ernüchternd. Vor kurzem hat mich dann auch noch Vain via GitHub auf die Geschwindigkeit von statistical hingewiesen. In seinem Fork, hat er alle extern spawnenden Befehle gegen Bash interne Funktionen ausgetauscht. Siehe da:

real 0m7.788s
user 0m7.610s
sys 0m0.250s

Wahnsinn oder? Durch den Austausch von awk und grep durch interne Bash Funktionen wird das ganze ernsthaft 23x mal schneller. Vielen Dank an Vain an dieser Stelle!

April 14 2011

16:55

statistical | Statistiken visualisieren im Terminal

Mir erschien es einen kurzen Moment lang für sinnvoll ein kleines Shell Tool zu haben, welches mir aus einer Liste von Key:Value Paaren eine Balkenstatistik baut und visualisiert. Wie in etwa $ statistical john:12 alice:5 linus:7 bob:1. Mir gefiel die Idee einfach alles mögliche in meinem Terminal ansehen zu können.

Relativ schnell stieß ich aber an eine Grenze. Diese hieß “Windowsize”. Ich konnte nicht ohne bedenken eine Schleife die die Value Werte zählt bauen, die dementsprechend viele Zeichen anhängt. Denn bei Zahlen >10000 wird das ziemlich unlesbar :)

    while [ $COUNTER -lt $VALUE ]; do
        ((COUNTER++))
        echo -n "$OUTPUTCHAR"
        if [ $COUNTER -ge $VALUE ]; then
            echo
        fi
    done

Ich brauchte ein Schema, welches alle Werte einließt und eine skalierbare Basis für alle Werte schafft. Ich entschied mich für eine simple Lösung.

      # Function for doing the factor increase
    factorincrease () {
        if [ $1 -gt ${FACTOR:-0} ]; then
            FACTOR=$1
        fi
    }

  # Scaling for values. You can use values up to
    # 1.000.000 without your terminal gets broken
    if [ $VALUE -gt 1000000 ]; then
        factorincrease 100000
    elif [ $VALUE -gt 100000 ]; then
        factorincrease 10000
    elif [ $VALUE -gt 10000 ]; then
        factorincrease 1000
    elif [ $VALUE -gt 1000 ]; then
        factorincrease 100
    elif [ $VALUE -gt 100 ]; then
        factorincrease 10
    else
        factorincrease 1
    fi

Letztenendes kam dann folgendes Verhalten bei meinem Key:Value Statistik Script raus. Ich mags.


# Beispiel
$ statistical john:433 alice:49 linus:12 bob:231
john    |###########################################
alice   |####
linus   |#
bob     |#######################

Damit lassen sich sogar teilweise sinnvolle Sachen produzieren. Zum Beispiel die Anzahl der Commits innerhalb eines Git-Repositories. Ich habe hier als Beispiel mal bash-it aufgeführt:

for a in $(git shortlog -sn --all | cut -f2 | cut -f1 -d' '); do echo -n "$a:" ; git log $LOGOPTS --all --numstat --format="%n" --author=$a | cut -f3 | sort -iu | wc -l; done  | statistical
Mark          |##################
Robert        |#########################################################################
Florian       |##############
Jesus         |######
John          |##############
Rich          |########
Piotr         |###
Travis        |####
Fedyashev     |##
zerobearing2  |####
Andy          |###
Daniel        |####
Jeff          |##
Karl          |##
Robert        |#########################################################################
Sirupsen      |##

Sollte jemand Interesse daran hegen, das Skript auch mal auszuprobieren es befindet sich wie immer auf Github: http://github.com/noqqe/statistical

March 26 2011

12:45

ZRE | SQL Statistik Modul

Ich möchte kurz ein Wort über das SQL Modul verlieren, welches die Statistiken des permanent laufenden Zombie Environments aufzeichnet. Wie mit Sicherheit schon überall auf dem Planeten Erde bekannt ist, passieren in ZRE Events. Diese Hand voll Events lösen (wie der Name vielleicht schon suggeriert) Geschehnisse in innerhalb des Environments aus, welche es gilt statistisch auszuwerten und darzustellen.

Han Solo & Chewbacca

Wie aber erfasse ich solche Informationen am Besten. Ich hatte ehrlich gesagt keine große Lust, in jedes der Events einzeln eine SQL-Verbindung aufzubauen und den gewünschten Query abzusetzen. Ganz zu schweigen von der Problemfallbehandlung (MySQL nicht installiert, Modul in Config nicht aktiviert, MySQL nicht erreichbar usw.) die ich in jedem Event hätte extra behandeln müssen.

events/
├── attack.humans.event
├── attack.zombies.event
├── born.humans.event
├── born.zombies.event
├── building.humans.event
├── collecting.zombies.event
├── die.humans.event
├── die.zombies.event
├── infos.event
├── stats.humans.event
├── stats.zombies.event
├── support.humans.event
├── support.zombies.event
└── weather.event

Stattdessen entschied ich mich ein kleines Modul in Bash zu schreiben, welches eine Hand voll übergebener Daten annimmt und dann in die konfigurierte Datenbank schreibt. Hier am Beispiel des weather.event

case $nature_msg in
1) echo "A volcano explodes." ; zresql weather vulcano ;;
2) echo "An earthquake hits the city." ; zresql weather earthquake ;;
3) echo "A hurricane hits the city." ; zresql weather hurricane ;;
esac

Als erstes übergeben wird immer der gewünschte Modus, in den zresql den Datensatz einordnen soll, danach alle weiteren Informationen die der Struktur nach erforderlich sind.

# Hurricane
$ zresql weather hurricane
# Humans gewinnen einen Kampf und vernichten 643 Zombies
$ zresql kill human 643

Das zresql Modul nimmt die Informationen dann entgegen und leitet es unter den gegebenen Umständen via sqlsend an die Datenbank weiter.

[...]
weather) sqlsend "INSERT INTO zre_weather VALUES (NULL, \"$2\", CURRENT_TIMESTAMP);" ;;
kill) sqlsend "INSERT INTO zre_kills VALUES (NULL , \"$2\", \"$3\", CURRENT_TIMESTAMP);" ;;
[...]

sqlsend ist im Grunde nur eine weitere kleine Funktion die direkt über Kommandozeile den SQL Query abschickt.

sqlsend() {
mysql -e "use $sqldb; $1" --user=$sqluser --password=$sqlpw --host=$sqlhost
}

Mit dieser Lösung bin ich eigentlich relativ zufrieden. Über Verbesserungsvorschläge und Kritik freue ich mich natürlich wie immer. Das ganze Modul ist zusehen auf Github: https://github.com/noqqe/zombie-revolution-environment/blob/master/lib/sqlstats.library.bash

March 21 2011

16:07

Persönlicher Eindruck | Chemnitzer Linux Tage 2011

Nachdem mich die Vorträge letztes Jahr so beeindruckt haben, hab ich mich auch dieses Jahr wieder entschieden die Linux Tage in Chemnitz zu besuchen. Durch einen Ausfall im Debian Team, hatte mir mein Kollege angeboten anstelle des ausgefallenen Mitglieds bei Debian mitzufahren. Was sich im Endeffekt als sehr nice herausstellte.

 

Freitag

Freitag war relativ entspannt. Ankunft und Aufbau des Debian Standes, mexikanisches Essen und danach Treffen mit Ben und Bier auf der Opening Party in der Mensa. Die Turnmatten in der Turnhalle waren auch kuschlig :)

Samstag

  • Frühstück @ Catering-Tage – Sehr leckere Sachen.
  • 1. Vortrag: Storage – Aber richtig von Martin Gerhard Loschwitz. Fand ich persönlich interessant, gerade der iSCSI-DRBD-Ansatz um FibreChannel zu ersetzen gefiel mir sehr gut.
  • 2. Vortrag: Provokante Thesen zur IT-Administration von Peer Heinlein Ja, Herr Heinlein. Der Autor des Buchs, welches mich durch die LPIC-1 Prüfung geführt hat sinnierte auf eher komödiantische Art über die typischen Eigenschaften der IT-Dienstleistungsbranche. Hat allerdings Spaß gemacht zuzuhören.
  • Danach Pause. Erstmal durch die Stände gestöbert, die mittlerweile so gut wie vollzählig anwesend waren. Währenddessen ausgeknobelt, ob der nächste Vortrag Icinga oder Configs mit Git verwalten wird.
  • 3. Vortrag: Konfigurationsdateien mit Git verwalten von Julius Plenz. Mit bash-it benutze ich ja bereits eine Lösung die für mich zur Verwaltung Teile meines /home gut funktioniert. Aber es schadet ja nie, sich andere Taktiken anzusehen und daraus zu lernen. Genau das habe ich auch erreicht. Julius hatte ein sinnvolles zwei Branches Modell, mit denen er lokale und globale Änderungen seiner Konfigurationsdateien verwaltet. Disziplin und etwas Aufwand sind dafür allerdings nötig. (http://chemnitzer.linux-tage.de/2011/vortraege/folien/782-config-management.pdf)
  • Hungerbedingt verpasste ich den Vortrag über von C.  Klostermann über Professionelle IT Dokumentation – Anforderungen aus rechtlicher Sicht Mittagsbuffet schaffte aber Abhilfe.
  • 4. Vortrag: Von H. Uhlig Dem Hack keine Chance: LAMP sicher betreiben: erwieß sich grade als Administrator von Shared Hosting Systemen als hilfreich und informativ.
  • 5. Vortrag: A. Scherbaum: Datenbanken von MySQL zu PostgreSQL portieren: Hierzu muss ich sagen, dass ich mir den Ansatz etwas Administrativer vorgestellt habe. Die Feinheiten der Möglichkeiten fernab vom SQL Standart von MySQL und PostgreSQL wurden aber schön ausgeführt und beschrieben. Persönlich aber muss ich gestehen, nicht sagen zu können ob PostgreSQL (abgesehen von dieser Oracle Sache) besser ist als MySQL. Es scheint eben anders zu sein.
  • 6. Vortrag: P. Heinlein: SPF, DKIM und Greylisting – Was bringen Absender-Authentifizierung und der neue Spam-Schutz? : Nochmal Herr Heinlein, diesmal über SPF und DKIM als Spam-Schutz sinnierend. Aufklärend auf jedenfall, da ich die beiden Funktionen garnicht kannte und gegen Ende noch 2-12 Worte über Greylisting. Alles in Allem Runde Sache
  • 7. Vortrag: T. Winde: Mit dem Midnight Commander Freiheit leben: Hauptsächlich hat mich Jan’s Vorliebe für MC in diesen Vortrag getrieben. Es war schön zu sehen, nicht nur Vorträgen von Business-Guys auf den Linux Tagen zu sehen. Ein fast schon “goldiger” Vortrag eines älteren Taxi-Unternehmers, der mir trotz geringem Lernerfolg irgendwie gefiel.
  • Social Event: Wunderbares Buffet mit reichlich zu trinken und zu Essen. Hat im Endeffekt genau dem gedient, für was es gut war. Bier, Essen & Social’n.

 

Sonntag

  • 8. Vortrag: Sonntag begann nach einer  weiteren Turnhallen-Nacht mit einem Vortrag von S. Kemter: Höher, Schneller, Weiter – openSUSE 11.4 : Der auch als Buergermeister von Karl-Tux-Stadt.de bekannte Redner, gab sich größte Mühe im Einsteigerforum das neue openSUSE, sowie die LTS, stable und unstable Linien vorzustellen.
  • 9. Vortrag: Von Andreas Tille Ein Jahr OpenStreetMap: Im Einsteigerforum ging es dann für mich auch gleich weiter mit einem (für mich komplett unbekannten) Thema. OpenStreetMap und seine Anwendung. Andreas, der selbst erst ca. 1 Jahr mit OpenStreetMap arbeitet, klärte die Zuhörer über all das auf, was er gerne von Anfang an über das Projekt gewusst hätte. War sehr schön gemacht und hat mir super gefallen. Dem ansonsten überfüllten Raum scheinbar auch.
  • 10. Vortrag: H. Voß Erstellung großer und größter Dokumente mit dem Satzsystem TeX: Ich muss sagen das meine Definition von “große Dokumente” ca. 1000 Seiten vor dem begonnen hatte die der Redner als große Dokumente definierte. Wenn so ein LaTeX Dokument mal länger läuft, als ein Kaffee hält, ist es eben viel :)
  • Mittags ließ ich mich dann von Julius (vom Git-Vortrag) nochmal einen Schritt in Zsh einführen, da sich am Social-Event rausgestellt hat, das er der Autor von Zsh beim OpenPress Verlag ist. Gab ehrlichgesagt vieles, bei dem ich nicht schlecht geschaut hab. … Wenn ich noch Zeit fände mir das alles einzuprägen… :)
  • 11. Vortrag: J. Kubieziel: Tor Bridges — Eine Brücke für freie Information: Danach ließ ich mich dann über die Risiken und Nebenwirkungen von Tor-Bridges aufklären. War sehr aufschlussreich. Langfristiges Interesse == unvermeidbar ;)
  • Stand abbauen – Ab nach Hause ;)

Im großen und ganzen war es wirklich sehr schön und interessant, viele Leute und Projekte näher kennenzulernen. Die Zahl der Projekte die mich interessieren ist wiedermal gewachsen, die Zahl für die ich die Energie/Zeit habe mich auseinanderzusetzen bleibt aber leider wie immer gleich.

Und gerade als ich mich daran gewöhnt habe, dass am Rednerpult intelligente Leute stehen die Ahnung haben von dem was Sie tun, muss ich wieder in die Schule. Bäm Montag.

March 14 2011

19:37

ZRE | Live Game Mitschnitt via jQuery und PHP

Eine der Aufgaben, von denen ich wirklich wenig bis keine Ahnung habe, war die Umsetzung der Live Gamebox für ZRE. Die Anforderung hat mich ehrlich gesagt mal in die Nähe des Web2.0 Wahns getrieben, von dem ich mich sonst fernzuhalten versuche. Zumindest von Entwicklerseiten her.

ZRE als Daemon (ja, der Teil kommt auch noch) hat die Eigenschaft im zufällig wiederkehrendem Rhythmus Output in ein Textfile zu produzieren. Dieses Textfile (game.txt) hat einen Platz im DocumentRoot des Webauftritts zombies.n0q.org (Ist das eigentilch das erste Mal, dass ich die URL erwähne? Ich glaube ja.). Diese möchte ich parsen und über asynchrone Aktualisierung in den Browser des Heimanwenders bringen.

Zuerst musste ich also den PHP Parser Teil schreiben, der mir die letzten 20 Zeilen, oder falls weniger eben diese aus meiner game.txt ausließt.

$input = file($zreoutput);
$resultArray = "";
$index = 20;
if (count($input) < 20)
{
   $index = count($input);
}
for($i=count($input)-$index; $i
{
   $resultArray .= $input[$i]."<br/>";
}
return $resultArray;

Als nächstes war es dann noch nötig diesen zurecht gebogenen Output dann noch selbst aktualisierend in meine Index Datei zu portieren. Dazu ist dann eine JavaScript nötig um die Funktion zu definieren.

setInterval(
    function() {
      $('#gamebox').load('../statics/gamequery.php');
      }, 2000
);

Jetzt mussten sowohl jQuery als auch das JavaScript Snippet in die Index Datei eingebunden werden. Über Kritik und Anregung freue ich mich natürlich wie immer.

<!-- game informations -->
<script src="js/jquery-min.js" type="text/javascript"></script>
<script src="js/gamebox.js" type="text/javascript"></script>
<!-- game results -->
<div id="gamebox"></div>

An der Stelle hatte ich gleich mal tatkräftige Hilfe eines Arbeitskollegen ;) Danke an dieser Stelle.

March 08 2011

18:51

ZRE | Visualisiert.

Ja -.- Ich weiss, ich hab Google Docs benutzt. Soweit jedenfalls zur Planung.

Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.