Dienstag, 20. September 2011

Easytag - ein Tagger für Audiodateien

EasyTAG ist wahrscheinlich einer der populäreren Editoren für Tags von Audio-Dateien. Dabei kann Easytag nicht nur mit MP3-Dateien umgehen, sondern auch mit diversen anderen Formaten, u.a. OGG Vorbis, Flac, MP4/AAC und ein paar weitere.

Eine ganz gute Einführung in EasyTAg gibt's im Wiki von ubuntuusers.de im Artikel zu EasyTag.

Screenshot des Hauptfensters

Viele der aktuelle Audioplayer können zwar auch Audiodateien Taggen, aber zumeist nicht so komfortable wie EasyTAG. Hier kann man nämlich mit wenigen Klicks ganz einfach die Daten für mehrere Dateien auf einmal setzen. Sehr praktisch, wenn man z.B. für viele Dateien gleichzeitig das Feld "Genre" ändern will.

Des weiteren hat EasyTAG den "Maskeneditor" an Bord. Dies ist ein sehr mächtiges Werkzeug, mit dessen Hilfe man in einem Rutsch aus Tags Dateinamen kreieren kann und auch umgekehrt, also mit Hilfe des Dateinamens Tags befüllen. Wie gesagt, der Maskeneditor ist recht mächtig - und wenn man nicht aufpasst kann man sich auch sehr schnell die Tags oder Dateinamen durcheinander bringen. Habe ich selber schon erfolgreich praktiziert...

Letztendlich ist es aber alles recht einfach, wenn man ein paar Punkte beachtet. Der Maskeneditor arbeitet mit Platzhaltern, welche den Dateinamen darstellen, der Generiert wird bzw. aus dem die Tags generiert werden.

Maskeneditor von EasyTAG
Wie im Screenshot zu sehen, wird hier ein neuer Dateiname basierend auf den Tags generiert. Sollten die erklärende Hilfe nicht angezeigt werden, so muss man auf das Fragezeichen klicken. Die Auswahl für das Füllen von Tags basierend auf dem Dateinamen funktioniert genau so, nur dass man dann im Auswahlfeld "Scanner" den Punkt "Fülle Tag" auswählen muss.

Wie gesagt kann man das auch für mehrere Dateien auf einmal machen. Dazu muss man lediglich im Hauptfenster von EasyTAG alle gewünschten Dateien markieren und dann den Maskeneditor öffnen.

Besonders beim Füllen von Tags sollte man tunlichst das Schema der Platzhalter 2x prüfen, bevor man die Tags schreibt. Dabei ist es auch wichtig, die Leerzeichen zu beachten!

Hat man jedenfalls das Schema festgelegt, so klickt man einmal auf die Schaltfläche, auf der im Screenshot der Mauszeiger steht. Dann werden die neuen Dateinamen generiert bzw. die Tags gefüllt -  aber noch nicht geschrieben (noch ist also nichts zu spät...). Zum endgültigen Schreiben muss man noch im Hauptfenster auf den "Speichern" Button klicken.

Fazit: EasyTAG ist ein leistungsfähiger Tagger für Audiodateien, welcher auch auch mehrere Dateien auf einmal bearbeiten kann. Lässt man bei dem Umgang mit dem Maskeneditor ein wenig Ruhe und Vorsicht walten, so ist auch das komfortable Neubenennen von Dateien oder das Füllen von Tags kein Problem.

Ach ja, ein paar Nachteile seien auch noch erwähnt: die Weiterentwicklung des Programms ist seit einiger Zeit ziemlich langsam. Und die Optik ist ein wenig altbacken...


Samstag, 17. September 2011

Red Hot Chilli Peppers "I'm with you" - Rezension

"I'm with you" ist die neuste CD von den Red Hot Chilli Peppers, erschienen Ende August 2011.

Zwischenruf: Wenn sich jetzt einer fragt, wieso ich was dazu schreibe... Ja, ich höre auch andere Musik als Hardcore und Punk. Zwar eher selten, aber ich bin auch den etwas ruhigeren Sachen nicht abgeneigt.

Zurück zum Thema: Die RHCP haben auf diesem Release einen neuen Gitarristen, Josh Klinghoffer. Und ob ihr's glaubt oder nicht - man hört es. Also nicht das Zweifel aufkommen: Die CD klingt immer noch nach den Red Hot Chilli Peppers, ohne Zweifel.

Um nochmal auf's Gitarrenspiel zurück zu kommen: Es klingt halt in Teilen "anders". Wobei "anders" nicht schlechter (oder besser) heißt, sondern halt wirklich anders. Ist halt schwierig zu beschreiben. Trotzdem hat der Release alles, was die Red Hot Chilli Peppers der letzten Jahr ausmacht: ein bisschen funky, ein bisschen groovy, ein bisschen popig, eingängig und trotzdem individuell. Spieltechnisch wie gewohnt auf hohem Niveau, also wieder sehr schöne Bassläufe, ein tolles Drumming usw.

Einen speziellen Anspieltip von der CD habe ich nicht. Liegt aber eher daran, dass ich so ruhigere Musik bevorzugt im Hintergrund hören, z.B. beim Programmieren.

Fazit ist jedenfalls: Wem die letzten CDs der RHCP gefallen haben, dem wird auch diese CD gefallen. Bzw. der sollte sich diese auf jeden Fall zulegen.

Montag, 12. September 2011

Battery "Only the diehard remain" - CD

Ok, die CD ist 1994 erschienen - ein bisschen spät für eine Rezension. Trotzdem habe ich sie erst seit ein paar Tagen neu. Liegt aber primär daran, dass mir bis vor kurzem nicht bekannt war, dass es eine  dritten Longplayer von Battery gibt. Den - wie ich jetzt weiß - 2. Release "Until the end" und den 3. und letzten Release "Whatever it takes" habe ich schon ziemlich lange.

Neu ist "Only the diehard remain" auf regulärem Wege kaum noch zu bekommen. Ich habe eine gebrauchte CD über eine Händler bei Amazon gekauft. Fast zum Neupreis, allerdings ist der Zustand auch neuwertig, von daher ok.

Zur CD: Der Titel "Only the diehard remain" ist selbst für Hardcore-Verhältnisse ein wenig martialisch. Sei's drum. Musikalisch hört man zwar, dass es Battery ist, wobei im direkten Vergleich zu den beiden oben genannten Folgealben dieser Release in Teil langsamer und düsterer ist. Teilweise erinnert es mich ein wenig an die Releases von Damnation A.D. Gut, da hat Ken Olden ja auch seine Gitarrenfinger im Spiel. Enthalten sind auf dem Release 11 Tracks mit einer Spieldauer von etwas weniger als 30 Minuten. Also quasi Hardcore-Standard.

Die CD ist sicherlich nicht schlecht, allerdings werde ich sie bestimmt nicht so oft wie die anderen beiden hören - die ich relativ oft und immer noch gerne höre. Nichts desto trotz ist meine Sammlung jetzt vollständiger. :-)

Sonntag, 4. September 2011

Cassandra und Python Teil 2 - der Objectmapper

Im ersten Teil des Artikels zur Nutzung von Cassandra mit Python wurde das pycassa-Modul beschrieben.

pycassa bringt zusätzlich auch noch einen Objectmapper mit, mit dessen Hilfe man Pythonklassen auf Column Families mappen kann. Als Beispiel Keyspace dient, wie im ersten Teil auch, "pydemo" und als Column Family wieder "pykontakt". Alle Beispiel werden in der Python-Shell ausgeführt.

Als erstes muss man natürlich pycassa wieder importieren:

>>> import pycassa

Danach legen wir die Klasse an, auf die später gemappt werden soll:

>>> class CFMap(object):
...        name = pycassa.String(default='nobody')
...        alter = pycassa.IntString(default=0)

Wie man sieht, muss man Datentypen aus pycassa / Cassandra zuordnen. Der Default wird immer dann eingesetzt, wenn man selber keine weiteren Vorgaben macht.

Jetzt wird einer Verbindung zum laufenden Cassandra-Server hergestellt sowie der Keyspace "pydemo" und Column Family "pykontakt" genutzt:

>>> pool = pycassa.connect('pydemo')
>>> cf = pycassa.ColumnFamily(pool,'pykontakt',
         autopack_values=False, autopack_names=False)

Wichtig sind die beiden Festlegungen von "autopack_values" und "autopack_names" auf "False" (der Default ist "True"), da im Falle von Mappings die automatische Konvertierung des Datentyps durch den Mapper erfolgt.

Jetzt kann man das eigentliche Mapping vornehmen:

>>> CFMap.objects = pycassa.ColumnFamilyMap(CFMap,cf)

Das Mapping kann man jetzt für neue Objekte nutzen:

>>> c = CFMap()
>>> c.key = 'User100'
>>> c.name = 'Susi'
>>> c.alter = 25

Das Objekt kann nun gespeichert werden:

>>> CFMap.objects.insert(c)
1315076828600806

und natürlich auch abgefragt:

>>> CFMap.objects.get(c.key).name
'Susi'
>>> CFMap.objects.get(c.key).alter
25

Die Defaultwerte werden immer dann eingesetzt, wenn man einer Spalte keinen Wert zuweist:

>>> c2 = CFMap()
>>> c2.key = 'User101'
>>> c2.name = 'Rainer'
>>> CFMap.objects.insert(c2)
1315077378894450
>>> CFMap.objects.get(c2.key).name
'Rainer'
>>> CFMap.objects.get(c2.key).alter
0

Über den Befehl multiget können mehrere Schlüssel auf einmal abgefragt werden, wobei das Ergebnis wie Dictionary abgefragt werden kann:

>>> erg = CFMap.objects.multiget([c2.key,c.key])
>>> erg
OrderedDict([('User101', <__main__.CFMap object at 0x7fe4bfa4ed90>), ('User100', <__main__.CFMap object at 0x7fe4bfa4edd0>)])
>>> erg['User100']
<__main__.CFMap object at 0x7fe4bfa4edd0>
>>> erg['User100'].name
'Susi'
>>> erg['User101'].alter
0

Über den Mapper könne auch Objekte gelöscht werden:

>>> CFMap.objects.remove(c2)
1315078335744352

Eine vollständige Übersicht über den Pycassa-Mapper findet man in der API-Referenz.

Hinweis: Alle Beispiele sind unter Python 2.6 mit Ubuntu 10.04, pycassa 1.1.1 und Cassandra 0.8.2 getestet.

Cassandra und Python

Ergänzend zum Cassandra-Artikel in FreiesMagazin 9/2011 werden hier noch zusätzliche Infos zur Nutzung von Cassandra mit Python gegeben.

Für alle, die den Artikel noch nicht gelesen haben sollten: Cassandra ist die Datenbank hinter Facebook (ist also für "großes" geschaffen), Open Source (in der Obhut der Apache Foundation unter Apache Lizenz) und hat ein interessantes, weil strukturiertes aber trotzdem flexibles Datenmodell.

Und natürlich gibt es auch ein Python-Modul namens "pycassa", mit dem man auf Cassandra Datenbanken zugreifen kann.

Installation

Die Installation ist mittels easy_install schnell erledigt:

sudo easy_install thrift
sudo easy_install pycassa

pycassa braucht das thrift-Modul, löst es als Abhängigkeit aber nicht selber auf, so dass man es selber händisch installieren muss.

Jetzt kann man via Python auf Cassandra zugreifen. Dazu muss man das Modul wie üblich importieren:

>>> import pycassa

Keyspace und Column Family anlegen

Um mit pycassa ein Verbindung zum Server herstellen, ein Keyspace anzulegen usw. benötigt man den "system_manager":

#Verbindung zum Server herstellen
>>> sys = pycassa.system_manager.SystemManager('localhost:9160')
#Keyspace "pydemo" anlegen, Replikation "SimpleStrategy" (=1)
>>> sys.create_keyspace('pydemo',1)
#Column Family "pykontakt" anlegen
>>> sys.create_column_family('pydemo','pykontakt')

Die gezeigten Befehle sind die "Minimalversion". Für eine vollständige Übersicht sollte man einen Blick in die zugehörige API-Dokumentation werfen.

Mit der Datenbank arbeiten

Jetzt kann man mit der Column Family arbeiten.

#Verbindung zur Datenbank und Keyspace "pydemo" herstellen
>>> pool = pycassa.connect('pydemo')
#Column Family "pykonakt" auswählen
>>> cf = pycassa.ColumnFamily(pool,'pykontakt')
#einige Spalten mit Wert eingeben
>>> cf.insert('User_1',{'name':'Susi'})
>>> cf.insert('User_1',{'alter':'25'})
#es ist auch möglich, mehrere Spalten auf einmal zu schreiben
>>> cf.insert('User_2',{'name':'Otto','alter':30})
>>> cf.insert('User_3',{'name':'Rainer','alter':'25'})

Es wurden also drei Schlüssel, "User_1", User_2", "User_3", angelegt und jeweils ein Wert in die Spaten "name" und "alter" geschrieben.

Die Werte können natürlich auch abgefragt werden:

#User_1 abfragen
>>> cf.get('User_1')
OrderedDict([('alter', '25'), ('name', 'Susi')])
#umgekehrte Reihenfolge
>>> cf.get('User_1',column_reversed=True)
OrderedDict([('name', 'Susi'), ('alter', '25')])
#nur eine Spalte abfragen
>>> cf.get('User_1',columns=['name'])
OrderedDict([('name', 'Susi')])
#Zeitstempel mit Abfragen
>>> cf.get('User_1',include_timestamp=True)
OrderedDict([('alter', ('25', 1312827347304141)), ('name', ('Susi', 1312827336484155))])

Wie man sieht ist das Ergebnis einer Abfrage vom Datentype OrderedDict, es kann darauf also wie auf ein Dictionary zugegriffen werden.

Im direktem Vergleich zum Cassandra-CLI übernimmt pycasssa dankenswerterweise die Konvertierung des Datentyps, d.h. beim Schreiben in die Datenbank wird alles automatisch nach "ByteType" konvertiert und beim Lesen wieder zurück nach UTF-8 usw.

Spalten indizieren

Cassandra unterstützt auch Abfragen über einen Index. Dazu muss die entsprechende Spalte aber zuerst explizit indiziert werden, was wieder über den weiter oben erwähnten SystemManager erfolgen kann:

>>> sys.create_index('pydemo','pykontakt',
'alter',pycassa.system_manager.BYTES_TYPE,index_name='alter_idx')

Hiermit wird im Keyspace "pydemo" aus der Column Family "pykontakt" die Spalte "alter" indiziert. pycassa.system_manager.BYTES_TYPE legt den Typ der Spalte fest, in diesem Fall BYTES_TYPE, den Defaulttyp. Die Angabe des Indexnames ist optional.

Mit einer so indizierten Spalte kann eine entsprechende Abfrage gestartet werden. Im folgenden wird nach Einträgen gesucht, bei denen das Alter gleich 25 ist.

#Suchausdruck festlegen
>>> alter_expr = pycassa.index.create_index_expression('alter','25')
>>> clause = pycassa.index.create_index_clause([alter_expr])
#Abfrage durchführen
>>> for key,user in cf.get_indexed_slices(clause):
...     print 'Schlüssel: %s' %key
...     print 'Name: %s, Alter: %s' %(user['name'],user['alter'])
...
Schlüssel: User_3
Name: Rainer, Alter: 25
Schlüssel: User_1
Name: Susi, Alter: 25

Natürlich ist es auch möglichen, Spalten oder ganze Schlüssel zu löschen:

#Spalte "alter" für "User_3" löschen
>>> cf.remove('User_3',['alter'])
1312829216114192
>>> cf.get('User_3')
OrderedDict([('name', 'Rainer')])
#Schüssel "User_3" komplett löschen
>>> cf.remove('User_3')
1312829235495355
>>> cf.get('User_3')
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.6/dist-packages/pycassa-1.1.1-py2.6.egg/pycassa/columnfamily.py", line 409, in get
raise NotFoundException()
pycassa.cassandra.c08.ttypes.NotFoundException: NotFoundException()

weiterführende Hinweise

Wie oben bereits erwähnt bietet pycassa wesentlich mehr Möglichkeiten als hier gezeigt. Für Interessierte sei ein Blick in die Dokumentation oder das ebenfalls online verfügbare, etwas ausführlichere, englischsprachige Tutorial (an dem sich dieses Tutorial hier auch orientiert) empfohlen.

Im zweiten Teil dieses Blogeintrags wird der ebenfalls in pycasse enthaltene Mapper gezeigt.

Hinweis: Alle Beispiele sind unter Python 2.6 mit Ubuntu 10.04, pycassa 1.1.1 und Cassandra 0.8.2 getestet.

Freitag, 26. August 2011

Unity & GNOME2 & ich

Das Thema ist ja immer noch einer Dauerbrenner, auch wenn GNOME 3 und dessen GUI zur Zeit etwas immer im Rampenlicht seht.

Ich selber nutzte zwei Laptops in etwa zu gleichen Teilen, was die Zeit davor angeht. Der eine läuft unter Ubuntu 10.4 LTS mit GNOME2, der anderen unter Ubuntu 11.4 mit Unity. Beides Standardinstallationen ohne Anpassungen. Lucid nehme ich primär zum Programmieren (weil der Server, auf dem die Software später landet, auch unter 10.4 läuft), Natty für private Sachen wie Fotos etc. Und natürlich beide Laptops für Internet, Chat u.ä.

Zum eigentlichen Punkt: Ich selber habe überhaupt keinen Probleme, zwischen Unity und GNOME2  hin- und her zu wechseln. Ich kann auch nicht behaupten, dass das eine oder das andere "besser" oder "effektiver" wäre. Bei Unity kann ich vielleicht etwas schneller zwischen geöffneten Programmen wechseln, weil ich die entsprechenden Tastenkombinationen inzwischen kenne. Das ist aber (für mich) ein marginaler Vorteil.

Klar, Design und Usebility sind Geschmackssache. Aber so gruselig ist Unity definitiv nicht, dass man "Gnome for life" sagen muss... Klar, es ist anders und neu, aber wer nicht offen für neues und anderes ist, bekommt so wie so irgendwann ein Problem.

Jedenfalls sehe ich der Sache gelassen entgegen und freue mich schon auf Oneric mit Unity. Es sollen ja ein paar Sachen geändert und verbessert worden sein. Mal sehen, ob der Flamewar "Unity vs. GNOME" mit dem Release von Ubuntu 11.10 wieder neu aufflammt. Vielleicht auch eher nicht, weil das GNOME-Projekt mit GNOME 3 ja auch einen "progressiven Steilpaß nach ganz vorne" geschlagen hat ;-)

Und wenn's wirklich nicht passt: Das aktuelle Xfce / Xubuntu gefällt mir auch gut... Die sind ja wenigsten Konservativ beim Desktop-Design. ;-)

Donnerstag, 25. August 2011

Earth Crisis "Neutralize The Threat" - Rezension

 Letzten Monat, Juli 2011, ist das neue Album "Neutralize The Thread" von Earth Crisis erschienen, der insgesamt neunte Longplayer (und gleichzeitig siebtes Studioalbum) der Band.

Zu Earth Crisis an sich muss man nicht viel sagen - eine der bekanntesten und einflussreichsten Hardcorebands der Neunziger. Soundmäßig war Earth Crisis immer etwas metalllastig - und ist es auch auf dem neuen Album immer noch.

Im Gegensatz zum letzten Album "To The Death" ist das neue Album weniger brachial. Am besten lässt sich "Neutralize The Thread" wohl als "die alten Earth Crisis mit zeitgemäßem Sound" bezeichnen. Und das klingt sehr gut!

Auf allen zehn Songs geben die Jungs richtig Gas und zeigen, dass sie immer noch zur 1. Riege im Hardcore / Metallcore gehören. Tightes Zusammenspiel mit harten Riffs, gepaart mit prägnantem Drumming und Karl Buechners Gesang - so kennt man Earth Crisis und deshalb mögen wir Earth Crisis.

Nach etwas mehr als 30 min ist die CD dann zu Ende. Nun gut, Hardcore Bands waren noch nie für Alben mit epischer Länge bekannt. Dabei ist die CD aber so abwechslungsreich und gut, dass man sie auch ohne weiteres direkt nochmal hören kann.

Meine Anspieltipps sind dabei der recht kurze Opener "Raise" und der Titeltrack "Neutralize The Thread".

Fazit: Wer Earth Crisis mag braucht die CD auf jeden Fall, wer metalllastigen Hardcore mag, der braucht die CD auch, da sie definitiv zu den "must have" Releases aus diesem Genre gehört.

Montag, 15. August 2011

Bottle: Dateinamen für dynamisch generierte PDFs übertragen

Ich habe diverse Python-basierte Webapplikation für das Firmenintranet programmiert, die PDFs (mittels ReportLab) generieren. Die PDFs schreiben ich dabei in ein StringIO-Objekt anstatt die Datei temporär auf Platte zu legen. Funktioniert auch alles soweit gut.

Das einzige "Problem" war, dass der Name des PDF nicht übertragen wurde, d.h. wenn man die Datei im Browser öffnet und dann speichern will schlagen Evince, Adobe Reader & Co. als Dateiname immer "pdf.pdf" (oder so ähnlich) vor. Nun gut, nicht wirklich tragisch, aber ein bisschen doof ist das trotzdem.

Die Lösung für das Problem ist dabei aber denkbar einfach - man muss nur von Hand den passende Eintrag im Response-Header setzen. Im Falle von Bottle, meinem aktuell favorisierten Webframework, sieht das so aus:


from bottle import response, ...
...
#Buffer-Objekt anlegen
buf = cStringIO.StringIO()
#hier kommt der Pythoncode zur PDF Generierung
...
#Senden vorbereiten
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = 'attachment;filename={0}'.format(pdf_filename)
#und Senden
return  buf

Wie gesagt, sehr einfach. "pdf_filename" enthält dabei den eigentlichen Dateinamen. Funktioniert natürlich auch genau so mit allen anderen Dateitypen.

Freitag, 5. August 2011

Skatepark Dornumersiel

Letzthin waren wir (Familie) im Urlaub in Norddeutschland. Da ich wusste, dass in Dornumersiel ein Skatepark ist, habe ich direkt mal mein Skateboard und meine Skateschuhe eingepackt.

Und - es hat sich gelohnt! Der Skatepark ist zwar nicht groß, aber echt klasse! Klasse in so fern, als das die Rampen einfach zu fahren sind, so dass auch Einsteiger, Gelegenheitsskater und alte Leute (die letzten beiden Punkte treffen auch mich zu ;-) ) Spaß haben können.

Der Park besteht aus einer zentralen Funbox, die auf einer Seite aus einer relativ flachen Pyramide und auf der anderen Seite aus einer Rampe und einer Bank besteht. Weiterhin gibt es einer Quarterpipe mit zwei Corners, eine kombinierte Quarterpipe mit Bank (ideal als Anlauf für die Funbox!), einer Grindbox mit "Auffahrt" und einem etwas zu hohen Rail.

Grindbox, kombinierte Quarter + Bank

Ollie über die Funbox, Quarterpipe im Hintergrund

Wie gesagt, es hat Spaß gemacht, auch wenn meine Skateschuhe dabei das zeitliche gesegnet haben...

Also, wer mal in der Nähe ist und sein Board dabei hat, der sollte im Skatepark Dornumersiel mal eine Runde fahren gehen. BMX-tauglich ist der Park übrigens auch.

Dienstag, 26. Juli 2011

Meine alten Skateschuhe - R.I.P.

Ich bin immer noch in tiefer Trauer... meine Skateschuhe sind nach 15 Jahren (oder vielleicht mehr?) kaputt gegangen. Trotzdem sie von der Markenfirma DC Shoes waren...

Nun gut - 15 Jahre halten die wenigsten Schuhe. Und Skateschuhe erst recht nicht. Wer sich jetzt wundert - die letzten 12-13 Jahre bin ich ziemlich wenig gefahren. Und mein Griptape ist ziemlich abgenutzt. ;-)

Anbei noch ein letztes Foto. Vielen von euch werden den Schuh wahrscheinlich gar nicht kennen. Wenn mich meine Erinnerung nicht täuscht waren das die mit als erstes erhältlichen DC Schuhe in Deutschland. Das Modell müsste das damalige Guy Mariana Signature Model sein. Kann mich aber auch täuschen...



Jedenfalls: R.I.P.