środa, 23 lipca 2014

Batch upload to Picasa

The problem: upload photos to Picasa (trivial); 2) scale them if neccessary before upload; 3) if photos contains some EXIF tags (geotags in particular) copy these tags to Picasa as well.

To achieve the above I use: googleCL (upload), convert (from ImageMagick bundle for scaling) exiftool (for metadata extraction/manipulation).

Using convert the script below (jpgresize.sh) scale picture to 2048 pixels along longest side:


#!/bin/bash
# Scale pictures to 2048 pixels along longest side for upload to Picasa
# Photos below 2048 x 2048 pixels do not count towards storage limit
# (cf. https://support.google.com/picasa/answer/6558?hl=en )
#
PICASA_FREE_LIMIT=2048

while test $# -gt 0; do
case "$1" in
-o) shift; OUT_FILE="$1";;
-o*) OUT_FILE="`echo :$1 | sed 's/^:-o//'`";;
*) FILE="$1";;
esac
shift
done

if [ -z "$OUT_FILE" ] ; then
my_pic="${FILE%.*}_s.${FILE#*.}"
else
my_pic="$OUT_FILE";
fi

if [ -f "$FILE" ] ; then

echo "** converting $FILE to $my_pic ***"

SIZE="2048x"

my_pic_width=`exiftool -ImageWidth "$FILE" | awk '{print $NF}'`
my_pic_height=`exiftool -ImageHeight "$FILE" | awk '{print $NF}'`

if [[ ( -z "$my_pic_width" ) || ( -z "$my_pic_height" ) ]] ; then
echo "*** $FILE has 0 width and/or height ***"; exit ;
fi

## http://www.imagemagick.org/Usage/resize/#resize
if [[ ( "$my_pic_width" -gt "$PICASA_FREE_LIMIT" ) || \
( "$my_pic_height" -gt "$PICASA_FREE_LIMIT" ) ]] ; then
if [ "$my_pic_width" -gt "$my_pic_height" ] ; then
SIZE="${PICASA_FREE_LIMIT}x>"
echo "*** $FILE width: $my_pic_width ; converting to $SIZE"
convert "$FILE" -geometry $SIZE "$my_pic"
else
SIZE="x$PICASA_FREE_LIMIT>"
echo "*** $FILE height: $my_pic_height ; converting to $SIZE"
convert "$FILE" -geometry $SIZE "$my_pic"
fi
else
## File is too small copy the original:
echo "*** $FILE has $my_pic_width in width; COPYING"
cp "$FILE" "$my_pic"
fi
else
echo "*** FILE $FILE not found! ***"
fi

Upload one picture to picasa with 1photo2picasa.sh


#!/bin/bash
#
# Upload photo to Picasa with googleCL
# It is assumed the photo contains UserComment GPSLatitude GPSLongitude GPSAltitude
# Exif tags which are copied to Picasa (see below for more details)
#
# Default album title:
ALBUMTITLE="???"

echo "$0 -a AlbumTitle FILE-2-UPLOAD"

while test $# -gt 0; do
case "$1" in
-a) shift; ALBUMTITLE="$1";;
-a*) ALBUMTITLE="`echo :$1 | sed 's/^:-a//'`";;
*) FILE="$1";;
esac
shift
done

AUTHOR=`exiftool -S -Artist $FILE`

if [ -z "$AUTHOR" ] ; then
# It there is no Artist tag it is assumed photo was not tagged properly
echo "*** ERROR: $FILE lacks Artist EXIF tag"
exit;
else
## Some tags are edited:
TAGS=`exiftool -S -UserComment $FILE | awk '{ $1=""; for (i=1;i<=NF;i++) { if ($i ~ /http/) { $i=""}}; \
gsub (/, +/, ",", $0); gsub (/ +,/, ",", $0); gsub (/^ +| +$/, "", $0); print $0}'`
GPSLat=`exiftool -S -c '%+.6f' -GPSLatitude $FILE | awk '{ print $2}'`
GPSLon=`exiftool -S -c '%+.6f' -GPSLongitude $FILE | awk '{ print $2}'`
GPSAlt=`exiftool -GPSAltitude $FILE -S -c "%.1f" | awk '{ if ($0 ~ /Below/) { print -$2} else {print $2}}'`

PICASA_TAGS=""
## Concatenate all tags
if [ -n "$TAGS" ] ; then PICASA_TAGS="$TAGS"; fi
if [ -n "$GPSLat" ] ; then PICASA_TAGS="$PICASA_TAGS,geo:lat=$GPSLat"; fi
if [ -n "$GPSLon" ] ; then PICASA_TAGS="$PICASA_TAGS,geo:lon=$GPSLon"; fi
if [ -n "$GPSAlt" ] ; then PICASA_TAGS="$PICASA_TAGS,geo:alt=$GPSAlt"; fi

# Upload to picasa:
google picasa post --title "$ALBUMTITLE" --src="$FILE" --photo="$FILE" --tags="$PICASA_TAGS"
fi

Finally simple bash script upload2picassa.sh uses jpgresize.sh and 1photo2picasa.sh to upload all .jpg files from the current directory to picasa:


#!/bin/bash
# Upload all .jpg files (scaled tp 2048) to picasa
#
echo "Uploading all .jpg files to album: $albumtitle"

albumtitle=$1

if [ -z "$albumtitle" ] ; then
echo "Podaj ID albumu!"; exit 1
fi

for file in *.jpg; do

echo "Uploading $file to $albumtitle album..."

outfile="${file%.*}_s.${file#*.}"

jpgresize.sh -p -o $outfile $file && 1photo2picasa.sh -a $albumtitle $outfile
done

wtorek, 22 lipca 2014

Flickr zmienił API

Wycieczka do Swornychgaci spowodowała m.in. konieczność dopasowania moich starych skryptów Perla służących do obsługi Flickra.

Flickr zmienił bowiem niedawno API przechodząc na SSL. Zapewne nowa wersja modułu Flickr-API tą zmianę uwzględnia, ale można też rozwiązać sprawę dodając stosowny parametr do starych skryptów. Konkretnie poniższy wiersz:


my $api = new Flickr::API({'key' => $api_key, 'secret' => $shared_secret, });

należy uzupełnić o parametr rest_uri, tj:


my $api = new Flickr::API({'key' => $api_key, 'secret' => $shared_secret,
'rest_uri' => 'https://api.flickr.com/services/rest/' });

Podobnie niewielkich modyfikacji wymaga skrypt służący do wysyłania zdjęć (moduł Flickr-Upload):


my $ua = Flickr::Upload->new( {'key' => $api_key, 'secret' => $shared_secret,
'uri' => 'https://up.flickr.com/services/upload/' } );

W tzw. międzyczasie zmieniła się też nieco metoda flickr.photos.geo.setLocation:


#if ( $response->{success} ) { ## przestało działać
unless ( $response->{error_code} > 0 ) {

W dokumentacji jest napisane: This method has no specific response -- It returns an empty success response if it completes without error.. No to faktycznie jak jest empty to if (EMPTY) { zwraca fałsz i warunek jest źle interpertowany. Poza tą jedną poprawką wszystko inne działa.

Wycieczka do Swornychgaci

We piątek (18.07.2014) przepłynęliśmy z rodziną kolegi ZK rzeką Chociną, konkretnie od Chocińskiego Młyna do jeziora Karsińskiego (ca 12 km na GPSie). Spływ zaczęliśmy w Chocińskim Młynie około 14:30 a do Swornychgaci dotarliśmy po 18:00.

Rzeczka jest płytka i wąska, ale nie ma w niej żadnych przeszkód. Spływ odbył się zatem bezproblemowo. Chcieliśmy także popłynąć kajakami w niedzielę, niestety, wszystkie okoliczne wypożyczalnie kajaków miały cały swój tabor zarezerwowany.

Miłym rozczarowaniem jest sieć pierwszorzędnych dróg rowerowych w okolicy Chojnic, o istnieniu których nie miałem świadomości. Drogi rowerowe są wytyczone obok drogi dla samochodów, wydają się dobrze oznakowane i mają utwardzoną nawierzchnię (niekoniecznie asfalt czy płytki/kostki). Do roweru szosowego nie nadają się na 100%, ale każdy inny będzie OK, a i na szosowym da się jechać. Na szybko jakieś informacje na temat tych dróg znalazłem tutaj (niekoniecznie musi to być najlepsze źródło).

Wracając wpadliśmy obejrzeć akwedukt w Fojutowie. Rozczarowująca atrakcja. Do tego tłum ludzi--nie wiem czemu akurat to miejsce jest aż tak popularne...

Ślad całej wycieczki (ze zdjęciami) jest też tutaj.

poniedziałek, 21 lipca 2014

Letter from an Idiot

Not very long ago, there was a lot of LGBT propaganda before Sochi Olympics Games related to alleged Putin's war with LGBT Russians. Opinion leader Stephen Fry's open letter to PM Cameron/IOC was a good example of hysteria created then.

IMHO the letter was extremely stupid (as stupid as its creator), namely Putin was compared to Hitler and LGBT Russians to Jews in the 3rd Reich (He is making scapegoats of gay people, just as Hitler did Jews).

Unfortunately Putin started a real war, not a war with some scapegoats.... And of course comparing 6 millions murdered Jews with `suffering gays' is pure and simple grave robbery (taniec na trumnach in Polish).

Fry's letter is here

sobota, 12 lipca 2014

Wysyłanie maila z raspberry Pi/Sheevaplug przez gmail

Dla nieuświadomionych Sheevaplug to taki dziadek RaspberryPi. Kiedy jeszcze nie sprzedawali Rpi kupiłem Sheevaplug i używam do dzisiaj. Na obu komputerach jest zainstalowany Debian, ale w różnych wersjach.

Listy mam wysyłać skryptem Perla więc rozpoczynam od zainstalowania stosowego modułu Net::SMTP::TLS:


sudo apt-cache search TLS | grep perl
libnet-smtp-tls-butmaintained-perl - Perl module for providing SMTP...
libnet-smtp-tls-perl - Perl SMTP client library supporting TLS and AUTH
libwww-curl-perl - Perl bindings to libcurl

sudo apt-get install libnet-smtp-tls-perl

W Debianie działającym na Sheevaplug (Debian Lenny) nie ma gotowego pakietu więc instaluję co trzeba za pomocą cpan:


cpan install Net::SMTP::TLS

Skrypt do wysyłania listu (mail-snd.pl):


#!/usr/bin/perl
# http://dipinkrishna.com/blog/2010/12/sending-emails-gmail-smtp-perl/
use Net::SMTP::TLS;

my $smtp = new Net::SMTP::TLS(
'smtp.gmail.com',
Port => 587,
User => 'USER1@gmail.com',
Password=> '??PASSWORD??',
Timeout => 30
);

# -- Enter email FROM below. --
$smtp->mail('USER1@gmail.com');

# -- Enter recipient mails addresses below --
my @recipients = ('USER2@gmail.com');
$smtp->recipient(@recipients);

$smtp->data();

#This part creates the SMTP headers you see
$smtp->datasend("To: USER2\@gmail.com\n");
$smtp->datasend("From: USER1\@gmail.com\n");
$smtp->datasend("Content-Type: text/html \n");
$smtp->datasend("Subject: A Test Mail");
# line break to separate headers from message body
$smtp->datasend("\n");
$smtp->datasend("This is a test mail body");
$smtp->datasend("\n");
$smtp->dataend();

$smtp->quit;

W Sheevaplug działa i wysyła, a Raspberry Pi nie:


invalid SSL_version specified at /usr/share/perl5/IO/Socket/SSL.pm line 332

Żeby było śmieszniej w Debianie Lenny z Sheevaplug jest jakaś bardzo stara wersja IO::Socket:SSL:


## sprawdź numer wersji modułu
cpan -D IO::Socket::SSL
Installed: 1.16

A na Raspberry Pi znacznie nowsza (ale nie działa):


cpan -D IO::Socket::SSL
Installed: 1.76
CPAN: 1.994 Not up to date

Aktualizuję


sudo cpan
cpan> install IO::Socket:SSL

Ale to nie pomaga:


invalid SSL_version specified at /usr/local/share/perl/5.14.2/IO/Socket/SSL.pm

Rozwiązanie jest podane tutaj. Należy:


## w pliku SSL.pm
sudo nano usr/share/perl5/IO/Socket/SSL.pm
## zmienić
m{^(!?)(?:(SSL(?:v2|v3|v23|v2/3))|(TLSv1[12]?))$}i
## na
m{^(!?)(?:(SSL(?:v2|v3|v23|v2/3))|(TLSv1[12]?))}i

Zamiast rzeźbienia w Perlu można zainstalować gotowe rozwiązanie pn. sendemail:


apt-get install sendemail

List wysyłamy w następujący sposób:


sendEmail -f USER1@gmail.com -t USER2@other.com \
-u "Title1" -m "this is a test message" \
-s smtp.gmail.com \
-o tls=yes \
-xu USER1 -xp '??PASSWORD??'