Neues GNOME 4 Desktop Design

Es sind erste geheime Bilder von Designstudien des GNOME 4 Desktops aufgetaucht.

GNOME 4 Desktop

Scripting mit Blender 2.61

Heute mal aus Spaß und Interesse angefangen, mit dem Pythonscripting in Blender 2.61 rumzuspielen. Nach anfänglichen Schwierigkeiten mit den Objektselektoren habe ich dann doch noch ein kleines Script hinbekommen, welches aber doch ein paar grundlegende Aspekte des Scriptings in Blender zeigt.

#import blender stuff
import bpy

#loop through all objects in the scene
#bpy.context.scene.objects is a list
for obj in bpy.context.scene.objects:
    #use only real opbject, not the camera or lamp
    if obj.type == 'MESH':
        #select the current object
        obj.select = True
        #remove the current selected object (which will always be obj)
        bpy.ops.object.delete()

#create a new cube object
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0))

#select this object
obj = bpy.context.scene.objects[0]

#move to another location
obj.location = 5.0, 0.0, 0.0


print('----------')
# print all objects
for obj in bpy.data.objects:
    print(obj.name)

Links zum Weiterlesen:

Blender 2.61 Python API

Blender 2.6 Manual

Functional Tests einer Rails 2.3.x Anwendung mit Paperclip und Clearance 0.8.8

Endlich habe ich mal Zeit gefunden, für eine etwas betagtere Rails-Anwendung (Rails 2.3.14) die Tests zu schreiben. Das Scaffolding erstellt zwar ein Grundgerüst, das aber bei fortgeschrittener Entwicklung immer angepasst werden muss. Die Unit-Tests waren kein großes Problem. Bei den Functional-Tests wurde es schon komplizierter. In der Anwendung kommt Paperclip als Gem zum Einsatz, um verschiedene Models mit einem Bild zu erweitern. Zur Authentifizierung wird Clearance als Plugin verwendet und liegt in Version 0.8.8 vor. Diese Version ist schon etwas älter und zum Testen wird Cucumber empfohlen. Paperclip hat sogenannte Matchers für RSpec. Ich wollte aber keines der beiden benutzen und stattdessen mit Rails-eigenen Mitteln (test/unit) Tests schreiben und die durch das Scaffolding automatisch erstellten Tests erweitern.

Mein erstes Problem waren die Fixtures. Da war es recht schwierig ein Bild festzulegen und somit automatisch laden zu lassen. FactoryGirl hat ein ziemlich gutes Konzept, um Fixtures zu erstellen und wird auch ziemlich häufig verwendet. Damit konnte ich dann ganz einfach Fixtures, sogenannte Factories, mit einer Bilddatei erstellen, die dann von meinem Model und damit von Paperclip anstandslos geschluckt wurden.

# test/factories/factories.rb
Factory.define :picture do |picture|
  picture.data    { File.new(RAILS_ROOT + '/test/factories/bg.jpg') }
  picture.author  { "test author" }
  picture.gallery { Factory(:gallery) }
end

Um FactoryGirl anstatt der Standard-Fixtures zu verwenden, habe ich einfach das factory_girl gem zu meiner config/environments/test.rb hinzugefügt,

# config/environments/test.rb
config.gem 'factory_girl'

das Laden der Fixtures in der test_helper.rb auskommentiert,

# fixtures :all

den fixtures Ordner gelöscht und eine factories.rb angelegt. In dieser kann ich nun fleißig Factories mit allerlei Funktionen anlegen. Für weiteres einfach in die FactoryGirl Doku gucken.

Als das erledigt war, konnte ich anfangen die Tests zu schreiben. Da ich Clearance als Authentifizierung verwende, musste ich erst einmal herausfinden, wie ich das Ein- und Ausloggen mit den Tests berwerkstelligen kann. Das Gem ist schon recht alt und deswegen war es etwas schwierig darüber etwas Doku zu finden. Ich habe es wie folgt gelöst.

Meine test_helper.rb bindet die Helpers von Clearance ein.

# test/test_helper.rb
require File.join(File.dirname(__FILE__), '..', 'vendor', 'plugins', 'clearance', 'shoulda_macros', 'clearance')

Jetzt kann ich alle meine Tests mit einer setup und teardown methode ausstatten, die die Clearance Methoden signin und signout nutzen können, um das Ein- und Ausloggen zu bewerkstelligen.

# test/functional/pictures_controller_test.rb
def setup
  sign_in
  @picture = Factory.create(:picture)
end

def teardown
  sign_out
  @picture = nil
end

Dabei wird außerdem eine Instanzvariable angelegt, die ich in den Tests anstatt der Fixtures verwende. Andere Teile des Tests, die noch die alten Fixtures verwenden, musste ich noch austauschen.

# test/functional/pictures_controller_test.rb
test "should create picture" do
  assert_difference('Picture.count') do
    post :create, :picture => Factory.attributes_for(:picture)
  end

  assert_redirected_to picture_path(assigns(:picture))
end

test "should show picture" do
  get :show, :id => @picture.id
  assert_response :success
end

test "should get edit" do
  get :edit, :id => @picture.id
  assert_response :success
end

test "should update picture" do
  put :update, :id => @picture.id, :picture => Factory.attributes_for(:picture)
  assert_redirected_to picture_path(assigns(:picture))
end

test "should destroy picture" do
  assert_difference('Picture.count', -1) do
    delete :destroy, :id => @picture.id
  end

  assert_redirected_to pictures_path
end

Die kompletten functional-Tests gibt es hier. Damit laufen alle Tests für die Anwendung erfolgreich. Ich bin mir garnicht sicher, ob das der beste Weg ist, um die Tests so zu bauen und daher für Verbesserungsvorschläge dankbar.

Bloggen im Jahr 2011

So geht es los: Der Server muss umziehen. Und da mir dabei aufgefallen ist, dass nur mein Wordpress Blog und phpMyAdmin den PHP-Interpreter auf dem Server notwendig machten, kam mir dieses gruselige Ding garnicht erst auf den neuen Server drauf. 100% Ruby powered aus kontrolliertem Anbau.

Trotzdem wollte ich den Blog behalten. Am besten irgendwo anders gehostet. Es gibt ja 1000 Plattformen dafür. Dachte ich. Blogger ist zu hässlich. Tumblr zu spartanisch. Wordpress.org ist undurchsichtig und kompliziert. Das ich den Fehler gemacht habe, mein nicht mehr existentes Wordpress Blog damit zu verbinden, hat die Sache dann völlig unbrauchbar gemacht. Dort kann man nicht mal seinen Account löschen. Posterous sah ganz gut aus und hatte eine Wordpress-Importier-Funktion. Also habe ich das ausprobiert und es war die Hölle. Erstens einmal ist es saulangsam und es gibt keine Vorschau beim Schreiben. Das kann man ja noch verkraften, aber was wirklich völlig unbrauchbar war, war der Editor. In der Hilfe von Posterous stand etwas von Markdown Unterstützung für Quellcode. Nur hat das leider bei mir auch nach mehrmaligen Anlauf nie funktioniert, weil dieser sinnlose Editor ständig HTML-Tags reingekracht hat und deswegen Nichts als Markdown erkannt hat. Und so kam es, dass ich kaum noch etwas geschrieben habe, aus dem einfachen Grund weil ich keine Lust hatte, dieses gruselige Interface-Monster namens Posterous zu verwenden.

Irgendwann wollte ich dann mal wieder etwas einigermaßen sinnvolles posten und wagte mich wiedermal an Posterous und scheiterte bei der ersten Zeile Quellcode. Ich gab schnell entnervt auf, verfluchte es und machte mich auf die Suche nach einem neuen Blogsystem. Nun ja, und wer mal nach Blogsystemen, die in Ruby geschrieben sind, gesucht hat, wird wissen, was jetzt kommt. Mephistoblog ist tot. Typo ist eine megafette Railsanwendung und sonst irgendwie nur ein halbes Wordpress. Und mehr ist da dann auch nicht wirklich in Sicht. Man könnte sich natürlich schnell selbst eins zusammenprogrammieren, aber eh das dann den Umfang hat, den man selbst will, dauert es auch eine Weile.

Bloggen im Jahr 2011 schien irgendwie garnicht so leicht zu sein.

Dann fand ich Octopress und sah mir die Sache mal näher an. Nach etwas lesen, war ich ziemlich neugierig auf diese "baked blog"-Geschichte und probierte es aus. Der Converter, der aus meinem alten Wordpress-SQL-Dump Markdown-Dateien macht, war schnell erweitert. Dann noch ein paar Zeilen in der Konfigurationsdatei ausgefüllt und schon konnte es losgehen.

rake new_post["Bloggen im Jahr 2011"]

Die angelegte Datei mit seiner bevorzugten(!) lokalen Editorsoftware öffnen und mit feinstem Markdown füllen. Auf Nimmer-Wiedersehen fürchterliche Web-Editoren, der ihr alle ziemlich schlecht seid!

rake preview

Eine lokale Vorschau erstellen, abchecken ob alles gut ist und mit

rake deploy

die ganze Sache auf den Server schieben. Ich nutze dafür GitHub Pages, welches wirklich sehr einfach einzurichten ist und auch zum Hosten von mehreren Webseiten mit unterschiedlichen Domains geeignet ist. Nun habe ich alles was ich brauche: gehostet, (m)ein guter Editor, Markdown für Quellcode und endlich wieder Spaß beim Bloggen.

Danke Octopress!

JSON, Unicode und UTF-8

Als ich vor ein paar Tagen mit der API.Leipzig rumspielen wollte, startete ich mit dem RestClient Gem ein paar Anfragen und stieß auf ein Anfangs komisches Problem:

RestClient.get 'http://www.apileipzig.de/api/v1/district/streets', :params =>{:api_key => '...', :limit => 1}

Dieser Befehl lieferte mir folgendes zurück:

{
    "data": [
        {
            "housenumber": 1,
            "name": "Abrahamstra\u00dfe",
            "created_at": "2011-05-23T21:41:04+02:00",
            "postcode": "04179",
            "district_id": 50,
            "updated_at": null,
            "id": 1,
            "housenumber_additional": "A",
            "internal_key": "06143"
        }
    ]
}

Statt einem 'ß' in der Abrahamstraße, also Unicode. Das sah auf den ersten Blick nach einem Fehler beim Encoding aus und ich habe eine Weile gebraucht um das Problem zu lösen. Unter anderem findet sich hier die Lösung:

RestClient funktioniert korrekt. Die API funktioniert ebenfalls korrekt, auch ein lokal aufgesetztes API System lieferte, mit unterschiedlichen Konfigurationen, immer das gleiche Ergebnis. Die Zeile, die in der API schlussendlich eine Ausgabe erzeugt ist

# API Leipzig's JSON Ausgabe https://github.com/apileipzig/api/blob/master/lib/helpers.rb#L124
output.to_json

output ist ein Hash und to_json stammt aus dem JSON Gem, das diesen Hash in JSON umwandelt. Bei dieser Umwandlung werden UTF-8 Zeichen, die nicht im ASCII Zeichensatz vorkommen, in Unicode codepoints umgewandelt. Das machen die meisten JSON Bibliotheken um auch kompatibel zu Empfängern zu sein, die kein UTF-8 empfangen können. Als ich dann ins JSON RFC geschaut hatte, wurde mir einiges klar:

If the character is in the Basic Multilingual Plane (U+0000 through U+FFFF), then it may be represented as a six-character sequence: a reverse solidus, followed by the lowercase letter u, followed by four hexadecimal digits that encode the character's code point. The hexadecimal letters A though F can be upper or lowercase. So, for example, a string containing only a single reverse solidus character may be represented as "\u005C".

JSON RFC Punkt 2.5 http://www.ietf.org/rfc/rfc4627.txt

Weiterlesen im RFC...

JSON text SHALL be encoded in Unicode. The default encoding is UTF-8.

JSON RFC Punkt 3 http://www.ietf.org/rfc/rfc4627.txt

Alle neueren Browser berücksichtigen das und wandeln automatisch bei der Anzeige von reinem JSON in UTF-8. Das klärt auch die Frage, warum Chromium und Firefox alles korrekt anzeigen, während mein eigenes kleines Script Probleme machte. Wer aber keine JSON Bibliothek benutzen möchte, kann aus dem Unicode wieder reines UTF-8 machen:

# Lösung http://stackoverflow.com/questions/5123993/json-encoding-wrongly-escaped-rails-3-ruby-1-9-2
response = RestClient.get 'http://www.apileipzig.de/api/v1/district/streets', :params =>{:api_key => '...', :limit => 1}
puts response.gsub!(/\\u([0-9a-z]{4})/) {|s| [$1.to_i(16)].pack("U")}

Nun hat die Abrahamstraße wieder ihr 'ß' und ich kann weiterarbeiten. Gut zu Wissen! :)