HTC Desire flashen (2)

Dit verhaal zal voor vrijwel niemand relevant zijn. Het gaat namelijk over een smartphone van 5 jaar oud. (Maar mocht je nog ergens zo’n telefoon hebben liggen: laat het me weten, en gooi ‘m nog niet weg; als mijn huidige stuk gaat, ben ik er erg blij mee.)
Alles dat ik hieronder beschrijf, heb ik op een Linux-laptop gedaan; waar nodig zul je zelf de vertaalslag moeten maken naar Windows of Mac.

Zo’n anderhalf jaar geleden beschreef ik al hoe ik een HTC Desire flashte. Toen ging het erom dat ik een Desire had gekregen waarop een custom ROM stond, en ik terug moest naar een stock ROM (maar dan wel met root).
Die telefoon heeft het zware buitenleven van een zwerver uiteindelijk niet overleefd, maar onlangs kreeg ik een kerstkadootje: een nieuwe tweedehands Desire.

Deze nieuwe telefoon was nog helemaal zoals hij uit de fabriek was gekomen, met Froyo (Android 2.2) als besturingssysteem. Het was dus aan mij om het apparaat te rooten (beheerdersrechten verkrijgen), en hem direct te upgraden naar Android 2.3 (Gingerbread).
De 2 belangrijkste redenen om root te willen hebben, zijn voor mij het kunnen installeren van een firewall, en het kunnen verwijderen van een aantal systeemapplicaties; en met ‘systeemapplicaties’ bedoel ik dan die applicaties die door de fabrikant op de systeempartitie geïnstalleerd zijn, maar die alleen maar ontwikkeld zijn om mijn privacy te schenden, zoals ‘Aandelen’, ‘Nieuws en weer’, ‘Gmail’, ‘Facebook’, ‘Twitter’, enzovoort.

Als je het verhaaltje hieronder leest, denk je waarschijnlijk ‘dat is een eitje’. Ik moet eerlijk zeggen dat het me enige dagen gekost heeft voordat ik eindelijk zover was.
In eerste instantie was ik begonnen met wat nu stap 2 is (het verkrijgen van root). Het duurde even voordat ik doorhad dat ik, zelfs als ik de systeempartitie read-write gemount had, niet naar die partitie kon schrijven, en dus geen permanent root kon krijgen. Hiervoor moest ik eerst S-OFF (security off) zien te krijgen. Maar om S-OFF te krijgen, moest ik eerst root hebben. Uiteindelijk was het de fabrikant zelf die me uit deze kip-ei-situatie hielp.

Voordat ik begin, wil ik nog even 2 dingen zeggen:

Allereerst heb ik niets van wat ik hieronder beschrijf zelf verzonnen of ontwikkeld. Ik heb alleen informatie verzameld van heel veel verschillende websites, en die gebundeld in dit verhaaltje. Het echte werk is gedaan door anderen.

En allertweedst moet ik even melden dat ik geen enkele verantwoording accepteer voor wat jij doet of nalaat naar aanleiding van dit verhaaltje. Als jouw telefoon, na het al dan niet juist opvolgen van deze aanwijzingen, veranderd is in een hele dure baksteen, dan heb jij er die baksteen van gemaakt, en niet ik.
Ik adviseer je van harte je telefoon zo te laten als de fabrikant hem bedoeld heeft.

Stap 0: voorbereiding

Als je het op dezelfde manier doet als ik, kost de voorbereiding je een dag of wat: zoek alles op dat je op internet kunt vinden over het rooten van de HTC Desire, en lees dat een keer of 3, liefst in een onlogische, en steeds andere volgorde.

Wil je er iets minder tijd aan besteden, installeer dan adb en fastboot. Deze 2 programmaatjes maken deel uit van de Android SDK (Software Development Kit). Als je Arch Linux gebruikt, hoef je niet de hele SDK te installeren, maar kun je android-sdk-platform-tools uit de AUR halen.

Doe na de installatie even

# adb --help

en

# fastboot --help

om te zien wat je precies geïnstalleerd hebt.
Beide programma’s gebruik je om met de telefoon te communiceren; adb als de telefoon gewoon aan staat, en fastboot als de telefoon in de bootloader staat. Uiteraard moet in beide gevallen de telefoon met een USB-kabel aangesloten zijn op je computer, en in de telefoon moet USB-foutopsporing ingeschakeld zijn (Instellingen / Applicaties / Ontwikkeling).
Beide programma’s voer je uit als root.

Hoe ik een geroote ROM gemaakt heb, heb ik bij mijn vorige flash al beschreven, dus daar ga ik niet te diep op in. In het kort: ROM downloaden van shipped-roms.com, en aanpassen met Android Kitchen.

Eén van de stappen hieronder vereist een SD-kaart in de telefoon (ik ben vergeten welke stap). Ik heb echter ook ergens de waarschuwing gelezen dat tijdens het proces de SD-kaart geformatteerd zou kunnen worden. Zorg dus dat er een SD-kaart in de telefoon zit waarvan het niet erg is als je de data die erop staat, kwijtraakt.

Stap 1: unlock bootloader

Zoals ik in mijn inleiding al schreef, liep ik tegen een kip-ei-dingetje aan: om het apparaat te kunnen rooten, moest ik S-OFF hebben, en om S-OFF te kunnen krijgen, had ik root nodig.
In mijn vorige leven, als ICT’er, zou ik een paar dagen vrij genomen hebben, een krat bier en een paar dozen frituursnacks aangeschaft, en Arnoud gebeld; ik twijfel er niet aan dat we erdoorheen gebroken zouden zijn.
Nu, zwervend door Frankrijk, met niet meer dan een 10-inch netbook, Arnoud op 1200 kilometer afstand, en bier en snacks ruimschoots boven mijn budget, was ik blij dat HTC zelf te hulp schoot.

De fabrikant van mijn telefoon heeft besloten 1 laagje van de verschillende laagjes beveiliging te verwijderen voor mensen die echt heel graag een andere ROM willen installeren. Als je daar gebruik van wilt maken, ga je naar de pagina Unlock Bootloader op HTCdev.com. Volg daar de aanwijzingen, en je telefoon is klaar om geroot te worden.

Stap 1½: update ROM

Het kan zijn dat je tijdens dat proces ziet dat je eerst een update moet installeren op je telefoon. Gelukkig was dat bij mij het geval, want dat maakte het toch nog een beetje interessant.

Want hoewel het unlocken van de bootloader door HTC netjes wordt ondersteunt voor de 3 belangrijkste besturingssystemen (Windows, Mac, Linux), is de update er alleen als .exe-bestand voor Windows. Maar dat wil natuurlijk niet zeggen dat ik die niet geïnstalleerd krijg…

Eerst halen we de ROM uit dat bestand, zoals ik dat ook in mijn vorige verhaaltje al beschreef:
Start het .exe-bestand met Wine. Klik niet door als de InstallShield Wizard is gestart; hij zal crashen. Laat in plaats daarvan het venster open staan, en zoek het bestand rom.zip op:

$ find ~/.wine/c_drive/ -type f -name rom.zip -print

Kopieer het gevonden bestand naar een andere directory, en druk op Cancel in de installer.

Koppel nu je telefoon aan je computer (USB-foutopsporing aan), en installeer de ROM:

# adb reboot bootloader
# fastboot oem rebootRUU
# fastboot flash zip rom.zip
# fastboot reboot

(En rom.zip is dan natuurlijk het bestand dat je daarnet uit de installer gepulkt hebt.)

Hierna kun je op HTCdev.com verder met het unlocken van je bootloader.

Stap 2: root

Voor het rooten van je telefoon kun je verschillende programma’s en apps downloaden. Maar ik zit hier inmiddels zo diep in met mijn hoofd, dat ik het liever vanaf mijn vertrouwde command line doe; dan hoef ik ook niet te zoeken naar een programma dat specifiek voor Linux geschreven is.

Ik download daarom SuperOneClick versie 1.7 van deze pagina; dat was een vrij willekeurige, maar daarom nog geen verkeerde keuze. SuperOneClick is een .NET-applicatie, maar dat maakt niet uit, want we gebruiken het toch niet… We halen er alleen een paar bestandjes uit, en zetten die op de telefoon.

# unzip SuperOneClickv1.7-ShortFuse.zip
# cd SuperOneClickv1.7-ShortFuse
# adb install Superuser.apk
# adb push psneuter /data/local/tmp/
# adb push su-v3 /data/local/tmp/

We hebben nu 1 app op de telefoon geïnstalleerd, en 2 bestanden naar de telefoon gekopieerd. De app gebruiken we straks om andere applicaties root-rechten te geven, maar dan moeten we eerst root-rechten op de telefoon hebben:

# adb shell
 $ chmod 755 /data/local/tmp/psneuter
 $ /data/local/tmp/psneuter

(Nu word je er even uitgeknikkerd, dus log opnieuw in; je bent dan root.)

# adb shell
 # mount -o remount,rw /dev/block/mtdblock3 /system
 # cat /data/local/tmp/su-v3 > /system/bin/su
 # chmod 755 /system/bin/su
 # exit
# adb reboot

Met psneuter hebben we tijdelijk root gekregen (wie wil weten hoe dat werkt, kan hier kijken), en vervolgens hebben we de systeempartitie read-write geremount (heb je voor die remount wel even gecontroleerd of je inderdaad /dev/block/mtdblock3 moest hebben?), om daar vervolgens su naartoe te kopiëren, zodat we na een reboot ook nog root kunnen krijgen.
Om dat te checken, kun je nu van de Playstore (dat heet in mijn telefoon trouwens nog Market) een willekeurige terminal emulator installeren, die starten, en dan su intikken. Als de $ prompt verandert in een # prompt, is het gelukt.

Stap 3: custom recovery

Nu we root hebben, kunnen we een custom recovery installeren. Die recovery hebben we sowieso nodig om straks onze eigen ROM te kunnen installeren, maar daarbij zijn de mogelijkheden van de standaard recovery nogal minimaal.

Download de ClockworkMod Touch recovery voor jouw model. (Of natuurlijk de andere, als de Touch er niet is voor jouw model.)

Installeren is een eitje:

# adb reboot bootloader
# fastboot flash recovery recovery-clockwork-touch-5.8.0.2-bravo.img
# fastboot reboot

En vervolgens reboot je in recovery om te zien wat je nou eigenlijk geïnstalleerd hebt:

# adb reboot recovery

(Je kunt ook booten in recovery door je telefoon uit te zetten, en ‘m vervolgens weer aan te zetten terwijl je de ‘Volume omlaag’-toets ingedrukt houdt.)

Kijk een beetje rond, en maak vooral ook een backup. Dat laatste is best belangrijk, want daarmee kun je straks weer terug naar je huidige configuratie, als de installatie van je aangepaste ROM onverhoopt ontploft.
Kies tot slot de optie ‘reboot system now‘.

Stap 4: backup veiligstellen

Je hebt net in Recovery een backup gemaakt (toch?). Die gaan we even veiligstellen. Als het goed is, kun je straks met deze backup terug naar nu, als dat nodig mocht zijn.

# adb shell ls /mnt/sdcard/clockworkmod/backup
 > 2016-01-15.15.07.54
# mkdir -p ~/htc-desire.backups/2016-01-15.15.07.54
# cd ~/htc-desire.backups/2016-01-15.15.07.54
# adb pull -a /mnt/sdcard/clockworkmod/backup/2016-01-15.15.07.54
# md5sum -c ./nandroid.md5

Als md5sum bij een of meer bestanden aangeeft dat er iets mis is, ga je terug naar Recovery, en maak je een nieuwe backup.

Stap 5: nieuwe ROM installeren

Hèhè, daar gaan we eindelijk…

Vervang ‘rom.zip’ door de naam van de ROM die je met Android Kitchen gebrouwen hebt:

# adb push rom.zip /mnt/sdcard/
# adb reboot recovery

En selecteer dan achtereenvolgens op je telefoon:

  • wipe data/factory reset
  • wipe cache partition
  • advanced
  • wipe dalvik cache
  • terug
  • install zip from sdcard
  • choose zip from sdcard
  • selecteer je ROM
  • terug
  • reboot system now

En als alles goed gegaan is, heb je nu een nieuw besturingssysteem op je HTC Desire. Gefeliciteerd!

Stap 6: klaar

# adb kill-server

(Anders blijft adb resources van je pc vreten.)

Geplaatst in Nerd stuff | Reacties uitgeschakeld voor HTC Desire flashen (2)

Os gezocht

De ‘stal’ voor de ezel is klaar; laat Kerstmis nu maar komen…

Een paar dode bomen uit het bos, wat afvalhout en een zeil. De liksteen en waterbak die ik vandaag van Elisabeth voor mijn verjaardag kreeg, maken het af.
Helaas durft Frimousse er nog niet in; waarschijnlijk lijkt het een beetje teveel op een paardentrailer, waarmee hij onlangs een niet-echt-geweldige ervaring had. Ik ga ervan uit dat de kou en zijn nieuwsgierigheid het in de komende dagen wel zullen winnen van zijn wantrouwen.

Geplaatst in Houtsnippers | 2 Reacties

Zwarte Piet

We naderen december. En dat betekent ongetwijfeld dat in Nederland de Zwarte-Pieten-discussie weer in volle gang is. Het leek me daarom een goed idee om ook mijn druppeltje olie even op het vuur te gooien:

Ik ben voor Zwarte Piet, en tegen Regenboogpiet!

Uiteraard ben ik van harte bereid om van mening te veranderen.
Mits:

  • Keti Koti voortaan alleen nog overdag gevierd wordt;
  • met Holi-Phagwa voortaan met confetti gestrooid wordt, in plaats van gekleurd poeder;
  • het tijdens de Ramadan voortaan wel toegestaan is om overdag vlees te eten; en
  • er bij de viering van Pesach voortaan bier geserveerd wordt.

Een paar kleine aanpassinkjes…
‘t Is immers geven en nemen in het leven.

Vrolijk Sinterklaasfeest!

zwartepiet

Geplaatst in Algemeen | Reacties uitgeschakeld voor Zwarte Piet

Foto’s bewerken voor publicatie

Foto’s die ik publiceer (vooral op mijn andere blog en Flickr) zijn allemaal voorzien van een logo en de naam van mijn site. In mijn vorige leven was ik programmeur, dus je dacht toch niet dat ik dat allemaal handmatig deed…?

Vandaag heb ik wat aanpassingen gemaakt aan het script dat dat voor me doet, en toen dacht ik ‘Laat ik het op mijn site zetten…‘; zo heb ik weer eens een berichtje op deze site, en wie weet heeft een ander er ook nog eens iets aan.

Uiteraard is het weer niet voor Windows, maar voor Unix-achtige systemen.

Eerst even wat achtergrond info. Mijn directory-structuur voor foto’s (en andere media) ziet er als volgt uit:

~
 `- media
    |- audio
    |  |- original
    |  |- publish
    |  `- resize
    |- flickr
    |  |- publish
    |  `- resize
    |- gpx
    |  |- gpx
    |  |- jpg
    |  |- png
    |  `- work
    |- images
    |  |- original
    |  |- publish
    |  `- resize
    |- video
    `- watermerk

Nieuwe foto’s verplaats ik van mijn camera naar de directory ~/media/images/original/, in subdirectories die de datum als naam hebben (20151025). Als ik foto’s wil publiceren op mijn blog en/of Flickr, maak ik een subdirectory met zo’n zelfde naam (20151025) in ~/media/images/resize/ en/of ~/media/flickr/resize/, en kopieer ik de foto’s daarheen. Vervolgens start ik mijn script (dat je in zijn geheel onderaan dit bericht vind):

~/bin/peregrino_media.sh images

of

~/bin/peregrino_media.sh flickr

of

~/bin/peregrino_media.sh images flickr

Het script bewerkt dan alle foto’s voor publicatie, en verplaatst ze naar de respektievelijke subdirectories publish/. De bewerkingen die uitgevoerd worden, zijn:

  • schalen van de foto’s (max. 800×800 pixels voor mijn blog; max. 1000×1000 px voor Flickr)
  • de naam van mijn site op de foto plakken
  • het logo van mijn site op de foto plakken
  • de Exif-tag ImageDescription verwijderen
  • de Exif-tag Artist toevoegen
  • de Exif-tag Copyright toevoegen

Dit is mijn script (als de tekst te breed is voor je scherm, klik dan op het script, en gebruik vervolgens je pijltoetsen om naar rechts/links te scrollen):

#!/usr/bin/env bash

# ~/bin/peregrino_media.sh

############################################################

#                   peregrino_media.sh
#                        door Rob

# rob@ohreally.nl
############################################################
# https://www.ohreally.nl/

# Bulk edit elPeregrino.nl media for publication.

############################################################
#
# Copyright (c) 2013 Rob la Lau (rob@ohreally.nl)
#
# This work is licensed under the
#   Creative Commons Attribution 4.0 International License
# To view a copy of this license, visit
#   http://creativecommons.org/licenses/by/4.0/
# or send a letter to
#   Creative Commons
#   444 Castro Street, Suite 900
#   Mountain View, California, 94041
#   USA
#
############################################################

############################################################
# Configuration.
#
# All variables may be changed from the environment.

# Artist info.
: ${ARTIST_NAME:='Rob la Lau'}
: ${ARTIST_EMAIL:='rob@elperegrino.nl'}

# Watermarks.
#
# Copyright.
: ${WM_COPYRIGHT='~/media/watermerk/copyright.png'}
: ${WM_COPYRIGHT_DISSOLVE:=15}
: ${WM_COPYRIGHT_GRAVITY:=NorthWest}
: ${WM_COPYRIGHT_GEOMETRY=''}
#
# Logo.
: ${WM_LOGO='~/media/watermerk/klompen.png'}
: ${WM_LOGO_DISSOLVE:=50}
: ${WM_LOGO_GRAVITY:=SouthEast}
: ${WM_LOGO_GEOMETRY='+5+5'}

# Base directory.
: ${BASE='/data'}

# Applications.
: ${CONVERT=`which convert`}
: ${EXIFTOOL=`which exiftool`}
: ${GPX2PNG="`which perl` '~/bin/gpx2png.pl'"}

#
# End of configuration.
############################################################

# We need at least 1 parameter.
[ $# -eq 0 ] && {
    echo "Too few parameters."
    exit
}

# Correct Exif data:
# - remove description
# - add artist and copyright info
correct_exif() {
    local file=${1}
    local year=${2}

    # If we don't receive a correct year, get one from the file itself.
    [ -z "${year}" -o "${year}" = "-" ] && {
        # File creation.
        created=`stat -c '%w' "${file}"`
        [ "${created}" = "-" ] && {
            # Last modification.
            created=`stat -c '%y' "${file}"`
            [ "${created}" = "-" ] && {
                # Last status change.
                created=`stat -c '%z' "${file}"`
                [ "${created}" = "-" ] && {
                    # Last access.
                    created=`stat -c '%x' "${file}"`
                    [ "${created}" = "-" ] && {
                        # Fall back to now.
                        created=`date +'%Y'`
                    }
                }
            }
        }
        year=${created%%-*}
    }

    # Remove and add Exif tags.
    "${EXIFTOOL}" -m -q -overwrite_original -ImageDescription= -Artist="Camera owner, ${ARTIST_NAME}; Photographer, ${ARTIST_NAME}; Image creator, ${ARTIST_NAME}" -Copyright="Copyright, ${ARTIST_NAME} (${ARTIST_EMAIL}), ${year}. All rights reserved." "${file}"
}

# Process image:
# - resize
# - add copyright notice
# - add logo
# - move to publication directory
# - correct Exif data
process_image() {
    local file=${1}
    local size=${2}

    if [ -e "./publish/${file}" ]; then
        # Never process a file twice.
        echo "${file} : exists, skipping"
    else
        # Resize; add copyright and logo.
        "${CONVERT}" "./resize/${file}" -resize ${size} ${WM_COPYRIGHT_ARGS} ${WM_LOGO_ARGS} "./publish/${file}"

        # Correct Exif data.
        copyrightyear=`exiftool -q -CreateDate "./resize/${file}" | awk -F':' '{gsub(/ /,"",\$2)}{print \$2}'`
        correct_exif "./publish/${file}" ${copyrightyear}

        # Delete original.
        rm "./resize/${file}"

        echo "${file} : done"
    fi
}

# Process image directory.
process_image_directory() {
    local path=${1}
    local size=${2}

    # No use continuing without the right tools.
    [ -z "${CONVERT}" -o -z "${EXIFTOOL}" ] && {
        echo "${dir}: Toolset not complete."
        return
    }

    # Construct ImageMagick arguments.
    [ -n "${WM_COPYRIGHT}" ] && {
        WM_COPYRIGHT_ARGS=${WM_COPYRIGHT}
        [ -n "${WM_COPYRIGHT_DISSOLVE}" ] && WM_COPYRIGHT_ARGS+=" -compose dissolve -define compose:args=${WM_COPYRIGHT_DISSOLVE}"
        WM_COPYRIGHT_ARGS+=" -gravity ${WM_COPYRIGHT_GRAVITY}"
        [ -n "${WM_COPYRIGHT_GEOMETRY}" ] && WM_COPYRIGHT_ARGS+=" -geometry ${WM_COPYRIGHT_GEOMETRY}"
        WM_COPYRIGHT_ARGS+=' -composite'
    }
    [ -n "${WM_LOGO}" ] && {
        WM_LOGO_ARGS=${WM_LOGO}
        [ -n "${WM_LOGO_DISSOLVE}" ] && WM_LOGO_ARGS+=" -compose dissolve -define compose:args=${WM_LOGO_DISSOLVE}"
        WM_LOGO_ARGS+=" -gravity ${WM_LOGO_GRAVITY}"
        [ -n "${WM_LOGO_GEOMETRY}" ] && WM_LOGO_ARGS+=" -geometry ${WM_LOGO_GEOMETRY}"
        WM_LOGO_ARGS+=' -composite'
    }

    # Loop through files in 'resize' directory.
    cd "${path}"
    ls -1 ./resize | while read file; do
        if [ -d "./resize/${file}" ]; then
            # Process subdirectories.
            if [ `ls -1 "./resize/${file}" | wc -l` = 0 ]; then
                # Remove empty subdirectories.
                rmdir "./resize/${file}"
            else
                # Create subdirectory for publication.
                [ ! -d "./publish/${file}" ] && mkdir "./publish/${file}"

                # Loop through subdirectory.
                ls -1 "./resize/${file}" | while read f; do
                    # Process each image.
                    process_image "${file}/${f}" ${size}
                done
            fi
        else
            # If it's not a subdirectory, it must be a file; process it.
            process_image "${file}" ${size}
        fi
    done

    # Clean up.
    unset WM_COPYRIGHT_ARGS WM_LOGO_ARGS
}

# Loop through arguments and treat them as directory names.
while (( ${#} )); do
    dir=${1}
    shift
    path="${BASE}/${dir}"
    [ ! -d "${path}" ] && {
        echo "${dir} : Not a directory."
        continue
    }
    case "${dir}" in
        audio)
            ###FIXME
            # No functionality for audio, yet.
            echo "${dir} : Don't know how to process."
            ;;
        flickr)
            # Resize images for publication on Flickr.
            # (Same as blog, but larger.)
            size=1000x1000
            process_image_directory ${path} ${size}
            ;;
        gpx)
            # Create JPEG image from GPX track.

            # No use continuing without the right tools.
            [ -z "${CONVERT}" -o -z "${EXIFTOOL}" -o -z "${GPX2PNG}" ] && {
                echo "${dir}: Toolset not complete."
                continue
            }

            # Arguments for `convert'.
            # (Hardcoded, since this is only used for elPeregrino.nl.)
            [ -n "${WM_COPYRIGHT}" ] && WM_COPYRIGHT_ARGS="'${WM_COPYRIGHT}' -compose dissolve -define compose:args=50 -gravity NorthWest -composite"
            [ -n "${WM_LOGO}" ] && WM_LOGO_ARGS="'${WM_LOGO}' -compose dissolve -define compose:args=30 -gravity NorthEast -geometry +5+5 -composite"

            # Loop through GPX tracks.
            cd "${path}/work"
            ls -1 ../gpx | while read file; do
                png=${file/%.gpx/.png}
                jpg=${file/%.gpx/.jpg}

                if [ -e "../jpg/${jpg}" ]; then
                    # Never process a file twice.
                    echo "${file} : exists, skipping"
                else
                    # Create PNG image from track.
                    ${GPX2PNG} -o "../png/${png}" "../gpx/${file}"

                    # Resize, add copyright and logo, and convert to JPEG.
                    "${CONVERT}" "../png/${png}" -resize 1000x1000 ${WM_COPYRIGHT_ARGS} ${WM_LOGO_ARGS} "../jpg/${jpg}"

                    # Correct Exif data.
                    created=`stat -c '%w' "../gpx/${file}"`
                    [ "${created}" = "-" ] && {
                        created=`stat -c '%y' "../gpx/${file}"`
                    }
                    copyrightyear=${created%%-*}
                    correct_exif "../jpg/${jpg}" ${copyrightyear}

                    echo "${file} : done"
                fi
            done

            # Clean up.
            unset WM_COPYRIGHT_ARGS WM_LOGO_ARGS
            ;;
        images)
            # Resize images for publication on blog.
            # (Same as Flickr, but smaller.)
            size=800x800
            process_image_directory ${path} ${size}
            ;;
        video)
            ###FIXME
            # No functionality for video, yet.
            echo "${dir} : Don't know how to process."
            ;;
        *)
            # Warn and continue for other arguments.
            echo "${dir} : Don't know how to process."
            ;;
    esac
done

`convert‘ is onderdeel van ImageMagick.
`exiftool‘ is de command line applicatie van ExifTool.
In het begin van mijn pelgrimage hield ik GPS-tracks bij. In dit script gebruik ik gpx2png om van de GPX-bestanden PNG-afbeeldingen te generen, die ik vervolgens verder kan bewerken.

De transparantie van de watermerken regel ik in dit script (dissolve); de watermerken zijn dus ‘gewone’ afbeeldingen.

Mocht je je afvragen waarom de configuratievariabelen zo ‘raar’ gedefinieerd worden: dat is om ze vanuit mijn environment te kunnen wijzigen. Zo kan ik mijn script bijvoorbeeld ook gebruiken om een andere website-naam op de foto’s te zetten wanneer ik dat wil:

#!/usr/bin/env bash

# ~/bin/rll_media.sh

############################################################

#                      rll_media.sh
#                        door Rob

# rob@ohreally.nl
############################################################
# https://www.ohreally.nl/

# Bulk edit roblalau.net media for publication.

############################################################
#
# Copyright (c) 2015 Rob la Lau (rob@ohreally.nl)
#
# This work is licensed under the
#   Creative Commons Attribution 4.0 International License
# To view a copy of this license, visit
#   http://creativecommons.org/licenses/by/4.0/
# or send a letter to
#   Creative Commons
#   444 Castro Street, Suite 900
#   Mountain View, California, 94041
#   USA
#
############################################################

############################################################
# Configuration.
#
# All variables may be changed from the environment.

# Artist info.
export ARTIST_NAME=${ARTIST_NAME:-'Rob la Lau'}
export ARTIST_EMAIL=${ARTIST_EMAIL:-'rob@roblalau.net'}

# Watermarks.
#
# Copyright.
export WM_COPYRIGHT=${WM_COPYRIGHT-'~/media/watermerk/roblalau.net.png'}
export WM_COPYRIGHT_DISSOLVE=${WM_COPYRIGHT_DISSOLVE:-35}
export WM_COPYRIGHT_GRAVITY=${WM_COPYRIGHT_GRAVITY:-South}
export WM_COPYRIGHT_GEOMETRY=${WM_COPYRIGHT_GEOMETRY-'+0+20'}
#
# Logo.
export WM_LOGO=${WM_LOGO-''}

#
# End of configuration.
############################################################

# Call ./peregrino_media.sh to do the actual editing.
"$(dirname $(realpath $0))/peregrino_media.sh" $@

Dus als ik een foto wil publiceren op dit blog, doe ik

~/bin/rll_media.sh images

Of, als ik zelfs daaraan nog iets wil veranderen:

env ARTIST_EMAIL='rob@ohreally.nl' ~/bin/rll_media.sh images

(En dat is de wijziging die ik vandaag aan mijn script gemaakt heb.)

Geplaatst in Nerd stuff | Reacties uitgeschakeld voor Foto’s bewerken voor publicatie

Wekker

M’n smartphone is stuk. Op zich geen probleem, want ik leef al anderhalf jaar zonder telefoon (en geniet ervan), maar hij deed wel dienst als wekker.

Gelukkig doet m’n laptop het nog wel, en dus schreef ik even vlug een wekker, zodat ik morgen toch bijtijds op kan.
(Uiteraard hebben we het over Linux.)

#!/usr/bin/env bash

# ~/bin/wekker.sh

# This script sets an alarm for the specified time.
# All command line parameters will be passed to `at' as timespec.

# Copyright (c) 2015 Rob la Lau <rob@ohreally.nl>
# This script is in the public domain.

#################################################################

# Config.

play=/home/rob/tingeling.wav
repeat=3

#################################################################

timespec=$@
[ -z "${timespec}" ] && {
    echo "No timespec given."
    exit
} 

AMIXER=`which amixer`
MPLAYER=`which mplayer`

(
cat <<EndOfCommands
${AMIXER} sset Master 100%
${MPLAYER} -quiet -loop ${repeat} ${play}
EndOfCommands
) | at -M ${timespec}

En nu kan ik mijn wekker zetten met het commando

./wekker.sh 07:00

Net zo makkelijk…

Geplaatst in Nerd stuff | Reacties uitgeschakeld voor Wekker

Bericht naar andere blog bij bericht naar ene blog

Dit bericht is vooral een reminder voor mezelf. Ik heb een kleine aanpassing gemaakt aan een WordPress-plugin, dus als ik een update doe van die plugin, zal ik ook de aanpassing opnieuw moeten maken.

Ooit heb ik besloten dat het een logisch idee zou zijn om 2 blogs te hebben: ik had al een blog (het blog dat je nu leest), en voor mijn voettocht naar Santiago de Compostela wilde ik een apart blog (elPeregrino.nl). Het idee was om dat andere blog alleen te gebruiken om te schrijven over mijn pelgrimage en er dan een punt achter te zetten. Maar na mijn tocht besloot ik verder te zwerven, en het leek logisch om daarover verder te schrijven op dat blog. En zo zit ik nu dus met 2 blogs: 1 over mijn omzwervingen, en 1 voor ‘de rest’. Ik heb weleens overwogen om ze samen te voegen, maar uiteindelijk besloten dat niet te doen.

Niet al mijn volgers hebben tijd of zin om allebei mijn blogs te volgen, maar het komt voor dat ik op mijn ene blog een tijd niets te vertellen heb, en op mijn andere blog wel. Om de lezers van mijn ene blog toch te laten weten dat ik er nog ben, ging ik daarom op zoek naar een manier op automatisch een kort berichtje naar mijn ene blog te sturen wanneer ik een bericht plaats op mijn andere blog; ik wilde niet het volledige bericht doorsturen, maar alleen een korte aankondiging met een link naar het bericht op mijn andere blog.

De WordPress-plugin SNAP kon dit (en meer) voor me doen. De plugin had 1 klein probleempje: de berichtcategorie van blog X wordt meegestuurd naar blog Y. Waarmee ik bedoel dat wanneer ik op deze site (roblalau.net) een bericht publiceer in categorie Houtsnippers, de plugin de aankondiging op mijn andere blog (elPeregrino.nl) in diezelfde categorie probeert te plaatsen; ik wil graag dat de aankondiging voor een bericht op roblalau.net, op elPeregrino.nl geplaatst wordt in de categorie roblalau.net. (Als je het niet meer kunt volgen, moet je het nog maar een keer lezen.)

Ik heb dit als volgt opgelost:

Op elPeregrino.nl heb ik een berichtcategorie roblalau.net aangemaakt.
Op roblalau.net heb ik een berichtcategorie elPeregrino.nl aangemaakt.
Ik heb op allebei mijn blogs de genoemde plugin geïnstalleerd. Op roblalau.net heb ik bij de plugin-instellingen aangegeven dat berichten in de categorie elPeregrino.nl nooit doorgestuurd mogen worden, en op elPeregrino.nl heb ik datzelfde gedaan voor de categorie roblalau.net.
Daarna heb ik op beide sites een bestand van de plugin een beetje aangepast:

Log in op je WordPress-dashboard, en ga naar Plugins.
Zoek daar de plugin NextScripts: Social Networks Auto-Poster, en klik bij die plugin op Bewerken.
Selecteer, aan de rechterkant van je scherm, het bestand inc-cl/wp.api.php.
Wijzig de regels 52 en 64 (regelnummers kunnen verschillen bij nieuwe versies van de plugin).

Regel 52 is:
$nxsToWPContent = array(‘title’=>$msgT, ‘description’=>$msg, ‘post_status’=>’draft’, ‘mt_excerpt’=>$ext, ‘mt_allow_comments’=>1, ‘mt_allow_pings’=>1, ‘post_type’=>’post’, ‘mt_keywords’=>$message[‘tags’], ‘categories’=>$message[‘cats’], ‘custom_fields’ => ”);
en wordt:
$nxsToWPContent = array(‘title’=>$msgT, ‘description’=>$msg, ‘post_status’=>’draft’, ‘mt_excerpt’=>$ext, ‘mt_allow_comments’=>1, ‘mt_allow_pings’=>1, ‘post_type’=>’post’, ‘mt_keywords’=>$message[‘tags’], ‘categories’=>array(‘elPeregrino.nl’), ‘custom_fields’ => ”);

Regel 64 is:
$nxsToWPContent = array(‘title’=>$msgT, ‘description’=>$msg, ‘post_status’=>’publish’, ‘mt_allow_comments’=>1, ‘mt_allow_pings’=>1, ‘post_type’=>’post’, ‘mt_keywords’=>$message[‘tags’], ‘categories’=>$message[‘cats’], ‘custom_fields’ => ”);
en wordt:
$nxsToWPContent = array(‘title’=>$msgT, ‘description’=>$msg, ‘post_status’=>’publish’, ‘mt_allow_comments’=>1, ‘mt_allow_pings’=>1, ‘post_type’=>’post’, ‘mt_keywords’=>$message[‘tags’], ‘categories’=>array(‘elPeregrino.nl’), ‘custom_fields’ => ”);

Bovenstaande geldt natuurlijk voor de bestanden op elPeregrino.nl; berichten die vanaf roblalau.net verstuurd worden, moeten in de categorie roblalau.net komen.

Zoals gezegd moet deze wijziging na elke plugin-update opnieuw gemaakt worden (uiteraard hoeven de categorieën en de instellingen niet steeds opnieuw gemaakt te worden).

Geplaatst in Nerd stuff | Reacties uitgeschakeld voor Bericht naar andere blog bij bericht naar ene blog

Het is wit en je kunt erop staan…

Een kuikentje!

IMG02260-cropped

Geplaatst in Algemeen | Reacties uitgeschakeld voor Het is wit en je kunt erop staan…

Wanden en trappenhuis

Voordat ik mijn mouwen opstroopte, was dit een grote, lege ruimte. Een paar dagen later is het klaar voor de isolatie en de gipsplaten (maar eerst binnenkort de vloer storten).

Geplaatst in Houtsnippers | Reacties uitgeschakeld voor Wanden en trappenhuis

WordPress 4.2, HTML5 image canvas data en privacy in het algemeen

Als je een WordPress blog hebt, en een upgrade doet naar versie 4.2, word je ineens geconfronteerd met de waarschuwing dat de site probeert HTML5 image canvas data te lezen. Uiteraard wil je dat helemaal niet, want je wilt niet dat je bezoekers denken dat jij iets engs probeert te doen, terwijl jij je van geen kwaad bewust bent.

Na even zoeken ontdekte ik dat deze waarschuwing te danken is aan de introductie van emojis. En niet alleen zorgt deze introductie voor een alarmerende waarschuwing: ik ontdekte ook dat voor deze emojis, voor elke pagina die een bezoeker bekijkt, automatisch een aanvraag gedaan wordt naar de website van WordPress.

En waarom is het erg dat bezoekers gedwongen worden informatie op te halen van de WordPress site als ze jouw site bezoeken? Omdat je hiermee WordPress in staat stelt te registreren welke WordPress blogs bezocht worden door jouw bezoekers. Je maakt hiermee dus een enorme inbreuk op de privacy van jouw bezoekers!

De eenvoudigste manier om zowel van die enge waarschuwing af te komen als de privacy van je bezoekers beter te garanderen, is het installeren van de WordPress plugin Disable emojis; deze plugin verwijdert deze functionaliteit volledig uit je website.

Tot zover over WordPress.

Maar nu we het dan toch hebben over inbreken op de privacy: door op je site gebruik te maken van Google Maps, Google APIs, Google Search, Google Fonts, een Google Plus button, Google Analytics of YouTube video, geef je de privacy van je bezoekers uit handen aan Google; en door een Facebook Like button op je site te plaatsen doe je datzelfde aan Facebook. Al deze gadgets lijken je website leuker te maken, of de ontwikkeling ervan makkelijker, maar zijn alleen maar ontwikkeld om zoveel mogelijk informatie te verzamelen over de bezoekers van jouw website (en over jouzelf, natuurlijk).
Een kundig website-ontwikkelaar heeft al deze enge dingen niet nodig, en een website-eigenaar die geeft om zijn/haar bezoekers weigert er gebruik van te maken.

Voor de gebruiker/bezoeker:

Als je meer controle wilt hebben over de aanvragen die uit jouw naam gedaan worden naar externe sites, gebruik dan Mozilla Firefox met de Request Policy en AdBlock Plus add-ons. Als je die add-ons lastig vindt, kun je er ook voor kiezen de Tor Browser Bundle te installeren; deze Firefox variant zorgt ervoor dat je op een andere fysieke locatie lijkt te zitten dan je daadwerkelijk doet, en verandert die locatie bovendien regelmatig, waardoor bedrijven je surfgedrag niet meer aan jou kunnen koppelen.
Als zoekmachine zou ik je Startpage of DuckDuckGo aanraden.
En het is natuurlijk verstandig om nooit cookies te accepteren, tenzij je echt geen andere keuze hebt. Maar dat weet iedereen inmiddels toch wel?

Voor de ontwikkelaar:

Als je website-ontwikkelaar bent, heb ik hier nog wat alternatieven voor je:

  • Google Maps → OpenStreetMap
  • Google Analytics → Piwik
  • Google Fonts → upload het te gebruiken font naar je site, en gebruik een stylesheet
  • Google Plus, Facebook Like, enz. → gewoon achterwege laten; dat is zo 2010…
  • authenticatie met Facebook, Twitter, enz. → een beetje programmeur heeft in een vloek en een zucht een eigen gebruikersdatabase en authenticatie-module opgezet

Voor alles wat deze enge bedrijven aanbieden, zijn alternatieven te verzinnen waarmee je niemands privacy op het spel zet. Wees een professional, en bescherm de onwetende bezoekers en gebruikers; laat je gemakzucht niet de overhand krijgen.

En bovendien:

Als ik dan toch bezig ben: je zou je kunnen afvragen hoe verstandig het is om je persoonlijke, of zelfs je zakelijke, e-mails te delen met bedrijven als Google (Gmail, Android), Microsoft (Outlook.com, Hotmail, Live.com, Windows Phone) en Apple (iPhone, iPad).

Weet je trouwens dat je voor GPS helemaal geen internetverbinding nodig hebt? Fabrikanten van mobiele apparaten (Android, iPhone, Windows Phone, enzovoort) willen je dat alleen maar laten geloven, zodat ze je fysieke locatie ook nog kunnen koppelen aan je surfgedrag.

Dit bericht werd getriggerd door mijn upgrade naar WordPress 4.2, maar als ik eenmaal begin over privacy…
Vrijheid begint met privacy; zonder privacy geen vrijheid.

Geplaatst in Nerd stuff | Reacties uitgeschakeld voor WordPress 4.2, HTML5 image canvas data en privacy in het algemeen

Dienblad

Want hoe krijg ik anders mijn ontbijt naar mijn picknicktafel?

De oplettende kijker heeft gezien dat de handgreepjes afgekeurde handvatjes zijn van de kast die ik gemaakt heb; verder een stukje afvalhout en een vensterlatje; het geheel afgewerkt met boenwas om het mooi te laten lijken.

Geplaatst in Houtsnippers | Reacties uitgeschakeld voor Dienblad