ehhhh, android w opakowaniu HTC to może i ładne telefony lecz ten, kto miał kontakt z polityką traktowania klienta przez HTC, wie czego można się spodziewać :/
Tak, zostałem bez telefonu, ale z backupem. Cóż, pewnie w google znajdę kilkaset narzędzi do wyciągnięcia kontaktów z backupu zrobionego z użyciem recovery clockworkmod, ale o wiele przyjemniej jest samemu pogryźć temat :D A teraz koniec biadolenia i czas do roboty.
Po przeglądnięciu backupa wyszło na to, że kontakty są w pliku contacts2.db – szybki file i już wszystko wiadomo – baza sqlite. Ha, to pogrzebiemy. W środku trochę tabel, a ta wyglądająca najlepiej to, hm o dziwo tabela o nazwie data :D Szybka analiza i już wiadomo co i jak. Każdy wiersz zawiera jeden element kontaktu – nr, email etc. Co jest w danym wierszu można wywnioskować na podstawie zawartości pól:
- mimetype_id – zawiera cyferkę oznaczającą rodzaj danych umieszczonych w kolumnie data1
- raw_contact_id – jeden raw id dla jednego kontaktu
- is_primary i is_super_primary – czyli czy dany element kontakt jest głównym czy główniejszym elementem :P
- data1 – dane kontaktu np nr telefonu, mail itp
A wiec plan jest taki – dla poszczególnych raw_contact_id wyciągać kolejne wartosci data1 w pogrupowaniu po mimetype_id. Ahh, gdyby sqlite miał cursor-y to było by to zadanie na jeden skrypcik. Ale nie ma wiec zrobię kawałek kodu w bash-u.
W pierwszej kolejności na podstawie tabeli mimetypes ustaliłem jakie mimetype_id mnie interesują, mówiąc ludzkim głosem jakie elementy kontaktu chce wyciągnąć:
mime_name=`sqlite3 contacts2.db "select _id from mimetypes where mimetype like '%/name'"` mime_phone=`sqlite3 contacts2.db "select _id from mimetypes where mimetype like '%/phone_v2'"` mime_email=`sqlite3 contacts2.db "select _id from mimetypes where mimetype like '%/email_v2'"`
Jak już znamy odpowiednie mimetype_id to możemy grzebać po tabeli data. Zaczniemy od wyciągnięcia wszystkich raw_contact_id dla których istnieje wartość określająca nazwę kontaktu:
rawid=(`sqlite3 contacts2.db "select raw_contact_id from data where mimetype_id = ${mime_name} and data1 not null"`)
A teraz mała pętelka, w której będziemy wyciągać interesujące nas dane kontaktów i będziemy zapisywać je w plikach vard:
for id in ${rawid[@]}; do
# poszczegolne dane wyciagamy
name=`sqlite3 contacts2.db "select data1 from data where mimetype_id = ${mime_name} and raw_contact_id = ${id}"`
phone=`sqlite3 contacts2.db "select data1 from data where mimetype_id = ${mime_phone} and raw_contact_id = ${id}"`
email=`sqlite3 contacts2.db "select data1 from data where mimetype_id = ${mime_email} and raw_contact_id = ${id}"`
# i do pliczkow je wrzucamy
echo "BEGIN:VCARD\nVERSION:2.1" > ${id}.vcf
echo "N:;${name};;;" >> ${id}.vcf
echo "TEL;CELL:${phone}" >> ${id}.vcf
echo "EMAIL;INTERNET;ENCODING=QUOTED-PRINTABLE:"
echo $mail | sed 's/@/=40/g'` >> ${id}.vcf
echo "END:VCARD" >> ${id}.vcf
done
Uzyskany format vCard działa na starej dobrej nokia np e50, e51, n95 itp :P ale wysyłanie kilkuset kontaktów na telefon w postaci vCard może być upierdliwe :/ z tego powodu dopisałem kawałek kodu eksportujący kontakty do csv:
Poniżej cały skrypt, w którym dołożyłem obsługę kilku tych samych mimetype_id dla jednego kontaktu (np dwa nr telefonu itp).
#!/bin/bash
# contact@staryadmin.pl
# GNU/GPL
#
# usage
# skrypt.sh db type
# db - contacts db file eg contacts2.db
# type - csv or vcard
# config
sqle="sqlite3 $1 "
# get mimetype for name, phone, email
mime_name=`${sqle} "select _id from mimetypes where mimetype like '%/name'"`
mime_phone=`${sqle} "select _id from mimetypes where mimetype like '%/phone_v2'"`
mime_email=`${sqle} "select _id from mimetypes where mimetype like '%/email_v2'"`
# get raw_contakt_id for contacts with the name
rawid=(`${sqle} "select raw_contact_id from data where mimetype_id = ${mime_name} and data1 not null"`)
# functions
function vcard {
# go to work ;)
for id in ${rawid[@]}; do
# get contact name
name=`${sqle} "select data1 from data where mimetype_id = ${mime_name} and raw_contact_id = ${id}"`
# get phone number - primary number
phonep1=`${sqle} "select data1 from data where mimetype_id = ${mime_phone} and raw_contact_id = ${id} and is_primary = 1 and is_super_primary = 1"`
# get phone numbre - next primary number :P
phonep2=`${sqle} "select data1 from data where mimetype_id = ${mime_phone} and raw_contact_id = ${id} and is_primary = 1 and is_super_primary = 0"`
# get phone number - rest numbers
phone=(`${sqle} "select data1 from data where mimetype_id = ${mime_phone} and raw_contact_id = ${id} and is_primary = 0"`)
email=(`${sqle} "select data1 from data where mimetype_id = ${mime_email} and raw_contact_id = ${id}"`)
# and writ to vCard file
echo "BEGIN:VCARD" > ${id}.vcf
echo "VERSION:2.1" >> ${id}.vcf
echo "N:;${name};;;" >> ${id}.vcf
if [[ $phonep1 ]]; then echo "TEL;CELL:${phonep1}" >> ${id}.vcf; fi
if [[ $phonep2 ]]; then echo "TEL;CELL:${phonep2}" >> ${id}.vcf; fi
for ph in ${phone[@]}; do echo "TEL;CELL:${ph}" >> ${id}.vcf; done
for em in ${email[@]}; do echo "EMAIL;INTERNET;ENCODING=QUOTED-PRINTABLE:"`echo $em | sed 's/@/=40/g'` >> ${id}.vcf; done
echo "END:VCARD" >> ${id}.vcf
done
}
function csv {
# go to work ;)
# put cvs header
echo '"Title";"First name";"General mobile";"General phone";"Home mobile";"Home phone";"Business mobile";"Business phone";"General email";"Home email";"Business email";' > contacts.csv
for id in ${rawid[@]}; do
# get contact name
name=`${sqle} "select data1 from data where mimetype_id = ${mime_name} and raw_contact_id = ${id}"`
# get phone number - primary number
phonep1=`${sqle} "select data1 from data where mimetype_id = ${mime_phone} and raw_contact_id = ${id} and is_primary = 1 and is_super_primary = 1"`
# get phone numbre - next primary number :P
phonep2=`${sqle} "select data1 from data where mimetype_id = ${mime_phone} and raw_contact_id = ${id} and is_primary = 1 and is_super_primary = 0"`
# get phone number - rest numbers
phone=(`${sqle} "select data1 from data where mimetype_id = ${mime_phone} and raw_contact_id = ${id} and is_primary = 0"`)
email=(`${sqle} "select data1 from data where mimetype_id = ${mime_email} and raw_contact_id = ${id}"`)
# and writ to csv file
# prepare phone/mail
i=0
if [[ ${phonep1} ]]; then phons='"'${phonep1}'";'; i=$((${i}+1)); fi
echo ${phonep1}", "${i} >> contacts.csv
if [[ ${phonep2} ]]; then phons='"'${phonep2}'";'; i=$((${i}+1)); fi
echo ${phonep2}", "${i} >> contacts.csv
for ph in ${phone[@]}; do phons='"'${ph}'";'; i=$((${i}+1)); echo ${ph}", "${i} >> contacts.csv; if [[ ${i} -eq 6 ]]; then break; fi; done
if [[ ${i} -lt 6 ]]; then for n in $(seq ${i} 5); do phons=${phons}'"";'; done; fi
i=0
for em in ${email[@]}; do emails='"a'${em}'";'; i=$((${i}+1)); if [[ ${i} -eq 6 ]]; then break; fi; done
echo '"";"'${name}'";'${phons}${emails} >> contacts.csv
done
}
# run convert
$2
a w dalszych planach mam zamiar przepisać to na binarny kod backupów symbianowych.