Activate NSZombie to find the object causing EXC_BAD_ACCESS

If you get an EXC_BAD_ACCESS with the following stack trace, activating NSZombie could help you to find the object causing the problem.


0x01285a63 in objc_msgSend
0x0580e400 in ??
0x0105fb8d in _ CFAutoreleasePoolPop
0x00022443 in -[NSAutoreleasePool release]
0x002d3bf2 in _ UIApplicationHandleEvent
0x018cca36 in PurpleEventCallback
0x01105064 in __ CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
0x010656f7 in __CFRunLoopDoSource1
0x01062983 in __CFRunLoopRun
0x01062240 in CFRunLoopRunSpecific
0x01062161 in CFRunLoopRunInMode
0x002cafa8 in -[UIApplication _run]
0x002d742e in UIApplicationMain
0x00001ca0 in main at main.m:14

You can activate NSZombie by doing the following:

  1. Get info of the executable.
  2. Go to the arguments tab.
  3. In the “Variables to be set in the environment:” section add:
  4. Name: NSZombieEnabled Value: YES

Then you can run  your app and when it crashes you should see an log entry in the console about the object causing the problem.

Create plist from excel sheet with python

This is a simple phyton script to create a plist xml file from a excel sheet. The values from the first row are used as keys for the plist. All values are converted to string.

To read the excel sheet, i use the xlrd package.

import xlrd
from xml.dom.minidom import Document
wb = xlrd.open_workbook('Test.xls')
sh = wb.sheet_by_index(0)

doc = Document()
plist = doc.createElement("plist")
plist.setAttribute("version","1.0")
doc.appendChild(plist)

array = doc.createElement("array")
plist.appendChild(array)

for rownum in range(sh.nrows):
    if rownum > 0:
        dict = doc.createElement("dict")
        array.appendChild(dict)
        for cellnum in range(sh.ncols):
            key = doc.createElement("key")
            key.appendChild(doc.createTextNode(sh.cell_value(0,cellnum)))
            dict.appendChild(key)
            value = doc.createElement("string")
            value.appendChild(doc.createTextNode(unicode(sh.cell_value(rownum,cellnum))))
            dict.appendChild(value)

out = open("Test.xml", "w")
out.write(doc.toxml("utf-8"))
out.close()

How to use Facebook Places outside the us (iphone)

Last week Facebook released the new service “Places“. This new thing you can show everyone where you are and even tell your friend’s girlfriend where he is.
This new service will be a big thing, i’m sure. That’s why I updated my iphone App to give it a try … i was really disappointed, the service works only in us for the moment.

Of cause this is not the first cool service you can only use in us. Facebook uses the same mechanism to block all users outside the us like most of the other services. Facebook get’s your geolocation by looking into a IP address – geolocation database. If your IP does not come from us, the service is blocked for you.

To by-pass this problem you have to use facebook with a us IP. You can achieve this by either use an proxy or an VPN located in the usa.

1. Proxy Solution

The proxy solution works only with a WiFi connection, cause you can only configure an proxy for a wifi but not for a 3G or Edge connection (shame on you apple!).
Ask google for a free us proxy and enter the settings under your wifi preferences.

Then point your mobile safari to http://touch.facebook.com/. You should see a new tab called “Places”.

The Facebook App did not work for me with a us proxy but it should. I things it just was a problem with the proxy i used.

2. VPN Solution

The VPN solution works with any connection of your iphone. On google you will find a lot free and payed VPN services. You just have to be sure to use one with an IP from usa and iphone support. Get an VPN accound and add the VPN settings to your iphone’s network configuration.

If you are connected to the VPN Places will work on http://touch.facebook.com/ and with the Facebook app.

Convert all Dreambox recordings to iphone/ipad format automatically

This article describes a way to automatically backup your dreambox recordings to a linux machine and convert them into mp4 files, which can be used on the iphone,ipad and ipod.

My linux machine runs Ubuntu 10.04 LTS/Lucid Lynx. For the backup of the recordings i use lftp and for the convertion HandBrakeCLI.

1. Install needed tools

First of all we have to install this two programs:

root@dubai ~ # sudo aptitude install lftp handbrake-cli

On my ubuntu version handrake was broken, so i had to add the handbrake snapshot repository first:

root@dubai ~ # sudo add-apt-repository ppa:stebbins/handbrake-snapshots
root@dubai ~ # sudo aptitude update
root@dubai ~ # sudo aptitude install handbrake-cli

2. Create needed directories

Next we create the following directories:

  • /home/dream/scripts – for the scripts we need
  • /home/dream/movie – the backup directory for the recordings
  • /home/dream/archive – the directory for the converted mp4 files

3. Backup the dreambox recordings

Lftp is just perfect to mirror a remote ftp directory. The easiest way to get the recordings from your dreambox is by ftp. The following script is a ftp script you can pass to lftp. First it will connect to your dreambox (you have to change the ip in the first line), then it will login as user root with the password dream. Afterwards it mirrors the /hdd/movie directory to /home/dream/movie. With the parameter –older-than=now-2hours you can easily avoid that running recordings get transfered.

open 192.168.0.XXX
user root dream
mirror -e -v --verbose=2 --older-than=now-2hours /hdd/movie /home/dream/movie
bye

This script goes to /home/dream/scripts/backup_dreambox.ftp

Now you can run lftp -f /home/dream/scripts/backup_dreambox.ftp to backup your dreambox movies.

4. Convert the recordings to mp4 files

To convert the recordings to mp4 i use the Handbrake command line program. It was not that easy to find out the perfect settings but this ones work for me and do also handle 720p HD videos. The only problem i still have is, that my iphone/ipad don’t likes files bigger than 4GB.

I use the following script to handle the convertion. On the first lines you can define the settings like the output folder, the quality of the target file, the handbrake settings.

The script will convert the file you passed as command line argument. If the target file already exists, it will just skip that file. First the scripts scans the the audio tracks on the movie to create the audio parameters for the handbrake convertion command. Currently it supports up to 2 audio tracks. Than it start the convertion and creates the new file in the /home/dream/archive using the original filename without Date/Time.

#!/bin/bash
QUALITY=0.67
OUTPUT=/home/dream/archive
HANDBRAKE_SETTINGS="-4 -T -2 -e x264 --loose-anamorphic -4 -x ref=2:bframes=2:subq=6:mixed-refs=0:weightb=0:8x8dct=0:trellis=0 -X 1280"

if [ $# -gt 0 ]
then
 OUTPUT_FILE=`echo $1|awk -F"-" '{ print $3 $4 $5}'|awk -F. '{ print $1 }'`.mp4
 TARGET=$OUTPUT/`echo $OUTPUT_FILE`
 echo $TARGET

 if [ -f "$TARGET" ]
 then
   exit 0
 fi

 AUDIO_TRACKS=`HandBrakeCLI -t 0 -i "$1" 2>&1|grep "scan: audio"|wc -l`
 AUDIO="-a 1"

 if [ "$AUDIO_TRACKS" -eq "2" ]
 then
   AUDIO="-a 1,2"
 fi

 HandBrakeCLI $HANDBRAKE_SETTINGS $AUDIO -q $QUALITY -i "$1" -o "$TARGET"
else
 echo "usage: dream2mp4 INPUT"
fi

This script goes to /home/dream/scripts/dream2mp4.sh

5. Glue everything together

Finally we create a script to first backup the dreambox and than convert all movies. You can just execute the script every day, hour or minute with a cronjob. It will first check if it’s already running.

#!/bin/bash
DREAM_MOVIES=/home/dream/movie
PID_SEARCH=`ps -fea|grep [b]ackup_dreambox.sh|grep bash`
let PID_COUNT=`ps -fea|grep [b]ackup_dreambox.sh|grep bash|wc -l`
if [ $PID_COUNT -lt 3 ]
then
 lftp -f /home/dream/scripts/backup_dreambox.ftp
 find $DREAM_MOVIES -name "*.ts" -exec /home/dream/scripts/dream2mp4.sh {} \;
else
 echo "backup is already/still running"
fi

This script goes to /home/dream/scripts/backup_dreambox.sh

The scripts: dream.tar.gz

In love with Java

Here comes the must watch for every java developer! via http://jz10.java.no/

5 days to go, our tipping competition site wettem.com finally is online

On friday it has finally arrived! South Africa opens the World Cup with the game against Mexico. We can not wait and we all look forward to four weeks of suspense, during which you can finally watch soccer on television every day.

To make the World Cup even more exciting, we updated our “Tipping Competiton” Web Applikation wettem.com.

Some of the new features

  • Facebook integration
  • New Look & Feel
  • Easier and better tipping mechanism
  • Possibility to tip the tournament winner
  • lot more …

Just go to http://www.wettem.com/ and try it out!

Now, there is only one thing to do for the next World cup! a iphone application like:

Java: retrieve locale and timezone from request

If you thought it’s no problem to retrive the users timezone from a http request you are wrong.

You get the locale but not the timezone and if you try to create the timzone from this locale you will get the default timezone from the server.

Currently there are two ways to get the timezone:

  1. expensive geolocation service like http://www.ip2location.com/
  2. javascript as discribed at http://www.onlineaspect.com/

I don’t like both solutions, therefore i created a third one by mapping the locales to timzones. This solution doesn’t work for countries with more than one timezone but thats ok for my requirements.

idcodelanguagecountrycapitaltimezone
1ja_JPJapaneseJapanTokyoAsia/Tokyo
2es_PESpanishPeruLimaAmerica/Lima
3enEnglishUnited StatesWashingtonAmerica/Los_Angeles
4ja_JPJapaneseJapanTokyoAsia/Tokyo
5es_PASpanishPanamaPanama CityAmerica/Panama
6sr_BASerbianBosnia and HerzegovinaSarajevoEurope/Sarajevo
7mkMacedonianMacedoniaSkopjeEurope/Skopje
8es_GTSpanishGuatemalaGuatemala CityAmerica/Guatemala
9ar_AEArabicUnited Arab EmiratesAbu DhabiAsia/Dubai
10no_NONorwegianNorwayOsloEurope/Oslo
11sq_ALAlbanianAlbaniaTiraneEurope/Tirane
12bgBulgarianBulgariaSofiaEurope/Sofia
13ar_IQArabicIraqBaghdadAsia/Baghdad
14ar_YEArabicYemenSanaaAsia/Qatar
15huHungarianHungaryBudapestEurope/Budapest
16pt_PTPortuguesePortugalLisbonEurope/Lisbon
17el_CYGreekCyprusNicosiaAsia/Nicosia
18ar_QAArabicQatarDohaAsia/Qatar
19mk_MKMacedonianMacedoniaSkopjeEurope/Skopje
20svSwedishSwedenStockholmEurope/Stockholm
21de_CHGermanSwitzerlandBernEurope/Zurich
22en_USEnglishUnited StatesWashingtonAmerica/Los_Angeles
23fi_FIFinnishFinlandHelsinkiEurope/Helsinki
24isIcelandicIcelandReykjavikAtlantic/Reykjavik
25csCzechCzech RepublicPragueEurope/Prague
26en_MTEnglishMaltaVallettaEurope/Malta
27sl_SISlovenianSloveniaLjubljanaEurope/Ljubljana
28sk_SKSlovakSlovakiaBratislavaEurope/Bratislava
29itItalianItalyRomeEurope/Rome
30tr_TRTurkishTurkeyAnkaraEurope/Istanbul
31zhChineseTaiwanTaipeiAsia/Taipei
32thThaiThailandBangkokAsia/Bangkok
33ar_SAArabicSaudi ArabiaRiyadhAsia/Riyadh
34noNorwegianNorwayOsloEurope/Oslo
35en_GBEnglishUnited KingdomLondonEurope/London
36sr_CSSerbianSerbia and MontenegroBelgradeEurope/Belgrade
37ltLithuanianLithuaniaVilniusEurope/Vilnius
38roRomanianRomaniaBucharestEurope/Bucharest
39en_NZEnglishNew ZealandWellingtonPacific/Auckland
40no_NONorwegianNorwayOsloEurope/Oslo
41lt_LTLithuanianLithuaniaVilniusEurope/Vilnius
42es_NISpanishNicaraguaManaguaAmerica/Managua
43nlDutchNetherlandsAmsterdamEurope/Amsterdam
44ga_IEIrishIrelandDublinEurope/Dublin
45fr_BEFrenchBelgiumBrusselsEurope/Brussels
46es_ESSpanishSpainMadridEurope/Madrid
47ar_LBArabicLebanonBeirutAsia/Beirut
48koKoreanSouth KoreaSeoulAsia/Seoul
49fr_CAFrenchCanadaOttawaAmerica/Montreal
50et_EEEstonianEstoniaTallinnEurope/Tallinn
51ar_KWArabicKuwaitKuwait CityAsia/Kuwait
52sr_RSSerbianSerbiaBelgradeEurope/Belgrade
53es_USSpanishUnited StatesLondonEurope/London
54es_MXSpanishMexicoMexico CityAmerica/Mexico_City
55ar_SDArabicSudanKhartoumAfrica/Khartoum
56in_IDIndonesianIndonesiaJakartaAsia/Jakarta
57ruRussianRussiaMoscowEurope/Moscow
58lvLatvianLatviaRigaEurope/Riga
59es_UYSpanishUruguayMontevideoAmerica/Montevideo
60lv_LVLatvianLatviaRigaEurope/Riga
61iwHebrewIsraelJerusalem*Asia/Jerusalem
62pt_BRPortugueseBrazilBrasiliaAmerica/Sao_Paulo
63ar_SYArabicSyriaDamascusAsia/Damascus
64hrCroatianCroatiaZagrebEurope/Zagreb
65etEstonianEstoniaTallinnEurope/Tallinn
66es_DOSpanishDominican RepublicSanto DomingoAmerica/Santo_Domingo
67fr_CHFrenchSwitzerlandBernEurope/Zurich
68hi_INHindiIndiaNew DelhiAsia/Calcutta
69es_VESpanishVenezuelaCaracasAmerica/Caracas
70ar_BHArabicBahrainManamaAsia/Bahrain
71en_PHEnglishPhilippinesManilaAsia/Manila
72ar_TNArabicTunisiaTunisAfrica/Tunis
73fiFinnishFinlandHelsinkiEurope/Helsinki
74de_ATGermanAustriaViennaEurope/Vienna
75esSpanishPeruLimaAmerica/Lima
76nl_NLDutchNetherlandsAmsterdamEurope/Amsterdam
77es_ECSpanishEcuadorQuitoAmerica/Guayaquil
78zh_TWChineseTaiwanTaipeiAsia/Taipei
79ar_JOArabicJordanAmmanAsia/Amman
80beBelarusianBelarusMinskEurope/Minsk
81is_ISIcelandicIcelandReykjavikAtlantic/Reykjavik
82es_COSpanishColombiaBogotaAmerica/Bogota
83es_CRSpanishCosta RicaSan JoseAmerica/Costa_Rica
84es_CLSpanishChileSantiagoAmerica/Santiago
85ar_EGArabicEgyptCairoAfrica/Cairo
86en_ZAEnglishSouth AfricaPretoriaAfrica/Johannesburg
87th_THThaiThailandBangkokAsia/Bangkok
88el_GRGreekGreeceAthensEurope/Athens
89it_ITItalianItalyRomeEurope/Rome
90caCatalanSpainMadridEurope/Madrid
91hu_HUHungarianHungaryBudapestEurope/Budapest
92frFrenchBelgiumBrusselsEurope/Brussels
93en_IEEnglishIrelandDublinEurope/Dublin
94uk_UAUkrainianUkraineKyivEurope/Kiev
95pl_PLPolishPolandWarsawEurope/Warsaw
96fr_LUFrenchLuxembourgLuxembourgEurope/Luxembourg
97nl_BEDutchBelgiumBrusselsEurope/Brussels
98en_INEnglishIndiaNew DelhiAsia/Calcutta
99ca_ESCatalanSpainMadridEurope/Madrid
100ar_MAArabicMoroccoRabatAfrica/Casablanca
101es_BOSpanishBoliviaLa PazAmerica/La_Paz
102en_AUEnglishAustraliaCanberraAustralia/Canberra
103srSerbianBosnia and HerzegovinaSarajevoEurope/Sarajevo
104zh_SGChineseSingaporeSingaporeAsia/Singapore
105ptPortuguesePortugalLisbonEurope/Lisbon
106ukUkrainianUkraineKyivEurope/Kiev
107es_SVSpanishEl SalvadorSan SalvadorAmerica/El_Salvador
108ru_RURussianRussiaMoscowEurope/Moscow
109ko_KRKoreanSouth KoreaSeoulAsia/Seoul
110viVietnameseVietnamHanoiAsia/Ho_Chi_Minh
111ar_DZArabicAlgeriaAlgiersAfrica/Algiers
112vi_VNVietnameseVietnamHanoiAsia/Ho_Chi_Minh
113sr_MESerbianMontenegroPodgoricaEurope/Podgorica
114sqAlbanianAlbaniaTiraneEurope/Tirane
115ar_LYArabicLibyaTripoliAfrica/Tripoli
116arArabicUnited Arab EmiratesAbu DhabiAsia/Dubai
117zh_CNChineseChinaBeijingAsia/Shanghai
118be_BYBelarusianBelarusMinskEurope/Minsk
119zh_HKChineseHong KongHong KongAsia/Hong_Kong
120jaJapaneseJapanTokyoAsia/Tokyo
121iw_ILHebrewIsraelJerusalem*Asia/Jerusalem
122bg_BGBulgarianBulgariaSofiaEurope/Sofia
123inIndonesianIndonesiaJakartaAsia/Jakarta
124mt_MTMalteseMaltaVallettaEurope/Malta
125es_PYSpanishParaguayAsuncionAmerica/Asuncion
126slSlovenianSloveniaLjubljanaEurope/Ljubljana
127fr_FRFrenchFranceParisEurope/Paris
128cs_CZCzechCzech RepublicPragueEurope/Prague
129it_CHItalianSwitzerlandBernEurope/Zurich
130ro_RORomanianRomaniaBucharestEurope/Bucharest
131es_PRSpanishPuerto RicoSan JuanAmerica/Argentina/San_Juan
132en_CAEnglishCanadaOttawaAmerica/Montreal
133de_DEGermanGermanyBerlinEurope/Berlin
134gaIrishIrelandDublinEurope/Dublin
135de_LUGermanLuxembourgLuxembourgEurope/Luxembourg
136deGermanSwitzerlandBernEurope/Zurich
137es_ARSpanishArgentinaBuenos AiresAmerica/Argentina/Buenos_Aires
138skSlovakSlovakiaBratislavaEurope/Bratislava
139ms_MYMalayMalaysiaKuala LumpurAsia/Kuala_Lumpur
140hr_HRCroatianCroatiaZagrebEurope/Zagreb
141en_SGEnglishSingaporeSingaporeAsia/Singapore
142daDanishDenmarkCopenhagenEurope/Copenhagen
143mtMalteseMaltaVallettaEurope/Malta
144plPolishPolandWarsawEurope/Warsaw
145ar_OMArabicOmanMuscatAsia/Muscat
146trTurkishTurkeyAnkaraEurope/Istanbul
147th_THThaiThailandBangkokAsia/Bangkok
148elGreekCyprusNicosiaAsia/Nicosia
149msMalayMalaysiaKuala LumpurAsia/Kuala_Lumpur
150sv_SESwedishSwedenStockholmEurope/Stockholm
151da_DKDanishDenmarkCopenhagenEurope/Copenhagen
152es_HNSpanishHondurasTegucigalpaAmerica/Tegucigalpa

SOAP Client with Maven

In combination with maven it is very simple to generate the access layer to an webservice by using its wsdl.

For this example I used an web service which gives access to the results of soccer league games: http://www.openligadb.de/.

First of all i had to decide which SOAP implementation and generator to use. I found three candidates:

To use them with maven an corresponding plugin is needed. The plugin for jax-ws was the simplest one to use:

https://jax-ws-commons.dev.java.net/jaxws-maven-plugin/

After creating the maven project i modified the pom.xml and added this plugin:


<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.uebelacker.openligaclient</groupId>
<artifactId>openligaclient</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>openligaclient</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<wsdlUrls>
<param>http://www.openligadb.de/Webservices/Sportsdata.asmx?WSDL</param>
</wsdlUrls>
<packageName>ch.uebelacker.openligaclient</packageName>
<extension>true</extension>
</configuration>
<dependencies>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-tools</artifactId>
<version>2.1.3</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

After executing mvn install, i have everything i need to access the webservice:

Sportsdata tSportsdata = new Sportsdata();
for ( League tLeague : tSportsdata.getSportsdataSoap().getAvailLeagues().league )
{
    System.out.println(tLeague.getLeagueShortcut() + " - " + tLeague.getLeagueName());
}

Proxy
If you’re behind a proxy you can pass the proxy configuration to the vm:

-Dhttp.proxyHost=192.168.82.1
-Dhttp.proxyPort=3128

iPhone Bilder sortieren

Urlaubsbilder schön aufbereitet und aufs iphone geladen um diese zu zeigen. Blöderweise kommen die Bilder in der Diashow nicht in der Reihenfolge wie man sich das gewünscht hat.

Das iPhone lässt auch keine Möglichkeit zu, die Bilder nach etwas anderem als dem Änderungsdatum zu sortieren. Dieses ist das Einzige Sortierargument, dass verwendet wird.

Aus diesem Grund muss man das Änderungsdatum der Bilder vor dem Übertragen auf das iPhone so abändern, dass dieses die Reihenfolge festlegt.

Leider ist dies aber nicht ganz so trivial bzw. Zeitaufwendig.

Falls die Namen der Bilder die Reihenfolge bereits festlegen, hilft folgendes kleines Skript (Linux/Mac) um das Änderungsdatum anzupassen. Es geht einfach alle Dateien in einem angegebenen Verzeichnis sortiert nach dem Namen durch und nimmt das aktuelle Datum zuzüglich 60 Sekunden für jedes Bild als Änderungsdatum.

#!/bin/bash
if [ $# -lt 1 ] || [ ! -d $1 ]
then
  echo "Usage:"
  echo "  sort4iphone.sh [directory]"
else
  echo "modifiing timestamps..."
  cd $1
  let TIMESTAMP=`date +%s`
  for FILE in `ls`
  do
    MOD_DATE=`date -r $TIMESTAMP +%Y%m%d%H%M`
    echo $FILE
    touch -t $MOD_DATE $FILE
    let TIMESTAMP=$TIMESTAMP+60
  done
fi

The Roo, The Roo is on Fire

Als armer Java Entwickler habe ich lange Zeit den Hype um Ruby on Rails beobachtet. Die Video Tutorials waren doch sehr vielversprechend und ich wollte das umbedingt auch lernen.

Gott sei Dank hat das nie geklappt!  Egal ob Ruby oder Java besser ist, ich bin und bleib Java Entwickler.

Inzwischen wurde der Ruby on Rails Ansatz für alle möglichen Programmiersprachen kopiert. Nicht die Programmiersprache Ruby war der Vorteil von Ruby on Rails, sondern der “Convention over Configuration” Ansatz.

Das Grails Projekt ist also sehr interresant für Java Entwickler, auch wenn man hier die Skriptsprache Groovy lernen muss.

Letzte Woche habe ich jedoch das richtige für mich gefunden: roo von springsource!