niedziela, 9 lutego 2014

Ethernet connection drop on Raspberry Pi

From time to time internet connection to my Raspberry Pi disappears (AFAIK it is well known feature of Pi). Removing and reconnecting the ethernet cables did not work, so one has to reboot by pulling the plug (risking to corrupt file systems from improper shutdown).

To reconnect I use the following bash script (found here):


#!/bin/bash
# Check if Internet connection is still alive ***
# Insert into crontab at *.16
LOGLOG="/home/pi/Logs/Cron/Reboot.log"
WLAN=eth0

if /sbin/ifconfig $WLAN | grep -q "inet addr:" ; then
echo "Network connection up!"
else
echo "Attempting reconnect [`date +%Y%m%d%H%M`]" >> $LOGLOG
/usr/bin/sudo /sbin/ifup --force $WLAN
fi

Note: use ifconfig -a to identify relevant interface (WLAN):


pi@raspberryberrystar ~ $ ifconfig -a ifconfig -a
eth0 Link encap:Ethernet HWaddr b8:27:eb:f5:9a:d7
inet addr:192.168.1.146 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

My other Pi is connected to internet not through a cable but with WiFi dongle. The relevant interface is:


pi@blackberrystar ~ $ ifconfig -a
wlan2 Link encap:Ethernet HWaddr 10:fe:ed:12:ef:2c
inet addr:192.168.1.144 Bcast:192.168.1.255 Mask:255.255.255.0

The connection is checked every 20 minutes with the following crontab entry:


## Check Internet connection every 7th, 27th, 47th minute:
7,27,47 * * * * /home/pi/bin/chk_www_alive.sh > /dev/null 2>&1

wtorek, 14 stycznia 2014

WinterhilfswerkKapelle

Winterhilfswerk Kapelle = Orkiestra Zimowej Pomocy, złośliwe nawiązanie do Winterhilfswerk des Deutschen Volkes w kontekście akcji p. Owsiaka.

Minister Kamysz cyt. Nie niszczmy inicjatyw charytatywnych polską wojenką.

Otóż akcje charytatywne dzielą się na sensowne i bezsensowne. Wiele samorządów wspieranych przez organizacje pozarządowe zwalcza (niszczy powiedziałby p. Kamysz) spontaniczne wspieranie żebrzących jako dobroczynność bardziej szkodzącą niż przynoszących pożytek (np. Dając mi pieniądze nie pomagasz).

Gdyby polski system ochrony zdrowia był dobrze zarządzany WOŚP byłaby zbędna dla większości ubezpieczonych. (Dalej wszakże mogłaby by się zajmować np. ludźmi nie ubezpieczonymi lub ubezpieczonymi, których problemy nie są objęte systemem ubezpieczeń.) Stawianie sprawy tak jak się ją stawia od 22 lat: chorym potrzebującym pomocy jest szpital a nie konkretny człowiek jest zgodą na byle jakie, złe zarządzanie, na reformy obliczone tak żeby nie naruszyć interesów żadnej wpływowej grupy, itd...

Innymi słowy jest to bezsensowna akcja charytatywna. Bezsensowna, bo utrwalająca stan złego zarządzania służbą ochrony zdrowia.

Ponadto WOŚP jest w dużym stopniu wspierana przez finanse publiczne. To co ląduje w puszkach to przysłowiowy pryszcz...

Liczne samorządy upychają na aukcjach coś, co jest finansowane z pieniędzy publicznych (przyłapane na tym bezczelnie twierdzą, że absolutnie nie, że nie wiąże się to z dodatkowymi wydatkami, ale przecież there is no such a thing as a free lunch). Innym słowy podatnik zapłacił za jakiś towar/usługę (powiedzmy stadion w Gdańsku wybudowany za 800 mln) a dostanie aparat USG (kupiony za pieniądze pochodzące z wydzierżawienia loży VIP na ww. stadionie...) Czy nie prościej byłoby od razu obciążyć podatnika kosztem aparatu USG? Tak bez zbędnych pośredników (p. Jurek, pan prezydent gdańska Budyń, itp) -- być może można by kupić za te same pieniądze 3 aparaty USG? A może nawet 4?

wtorek, 31 grudnia 2013

Temperature statistics 2010--2013

Average monthly outdoor temperature for Sopot, Abrahama in 2010--2013 (recorded with DS18B20 sensor). Average monthly temperature computed as $t_a = \sum_i^n t_i/n$, where: $t_i$ denotes measurement recorded in month $i$ (the temperature is recorded every hour BTW).

Average monthly outdoor temperature for Sopot

Click to see interactive version and data at plot.ly

The data shows (among other things:-) that December 2013 was really hot.

wtorek, 10 grudnia 2013

A newer version of the Raspberry Pi

I am using Raspberry Pi version A (256 Mb) for more than a year and now I bought one Pi more--model B (512 Mb) this time. I bought a TP-Link WiFi card (TL-WN725N) and a camera as well. The plan is:

  • attach the camera to the old Pi; connect Pi to WiFi network (because all four ports on my router are already occupied)
  • the whole stuff connected to the old Pi (temperature, humidity (DHT-22) and pressure (BMP085) sensors as well as Logitech C270 camera) connect into the new one.

Attaching everything to one single Pi is not an option--I want the camera-equipped Pi to be more portable.

Also I did not want to install a new system but just to use what I use so far (ie the system used on the old Pi):


uname-a
Raspberrystar.pinkaccordions.org Linux 3.2.27 + # 174 PREEMPT ...

Simple inserting the card from the old Pi into the new one did not work (the system did not start). An upgrade is needed probably:


sudo apt-get update
sudo rpi-update
uname-a
Raspberrystar.pinkaccordions.org Linux 3.10.18 +

Now 1-Wire bus stopped working. I also can not start the WiFi adapter TP-Link TL-WN725N. Inspecting Internet forums I discovered that version 3.6.11+ of the kernel may be less problematic in this respect. Therefore, I try to downgrade:


sudo rpi-update 8234d5148aded657760e9ecd622f324d140ae891

The above means to downgrade to the latest of 3.6.11+ versions:


pi @ raspberrystar ~ $ uname-a
Linux 3.6.11 + raspberrystar.pinkaccordions.org # 557 PREEMPT

Now the 1-Wire bus magically started to work. Sensors DHT-22 also work. The program I have used to read data from pressure sensor BMP085 required minor modifications and recompilation (as GPIO layout is different on Pi model B).

WiFi card also works, but require to download an appropriate driver. This one works for me (a copy is here). Other drivers, such as available here or here do not work. Compilation from sources as described here (in Polish is here) ends with an error as well.

Module 8188eu.ko can be installed as follows:


wget http://www.mendrugox.net/downloads/13 -O 818188eu.ko
## albo https://dl.dropboxusercontent.com/u/61315145/PiStuff/8188eu.ko.gz
## after download: gunzip 8188eu.ko.gz

sudo install -p -m 644 8188eu.ko /lib/modules/`uname -r`/kernel/drivers/net/wireless
sudo depmod -a
sudo modprobe 8188eu

The contents of the file /etc/network/interfaces should look like:


auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-ssid "NAME OF-NETWORK"
wpa-psk "PASSWORD"

One have to provide correct values for the NAME-NET and PASSWORD of course. The above settings will automatically establish a connection when the system starts.

Changing the host name

Minor thing, but I want to know easily which Pi is which:


## in the last line of /etc/hosts change host name
sudo vi /etc/hosts

## insert host name (this file contains only 1 line with a host name:)
sudo vi /etc/hostname

sudo /etc/init.d/hostname.sh
sudo reboot

The file /etc/hosts looks something like this:


127.0.0.1 localhost
:: 1 localhost ip6-localhost ip6-loopback
fe00 :: 0 ip6-localnet
ff00 :: 0 ip6-mcastprefix
ff02 :: 1 ip6-allnodes
ff02 :: 2 ip6-allrouters

127.0.1.1 blackberrystar

Camera

Updated system was cloned on a second card (Btw. for years I use Toshiba SDHC 8GB Class 10. This card is advertised as SLC but on card packaging/casing there is no word about it. SLC or not SLC I had never any problem with this card.)

Pi + kamera
Pi + camera

First picture

How to connect a camera to the Pi can be seen at one of the many videos on YouTube.

I followed instructions from How to set up the camera hardware.

Since I have not done this before:


pi@blackberrystar ~ $ sudo apt-get update
pi@blackberrystar ~ $ sudo apt-get upgrade

Now:


pi@blackberrystar ~ $ sudo raspi-config

I Choose Enable/Disable camera addon support and Memory split. I have not decided on the suggested 128 Mb for the GPU, bearing in mind that all the memory in my Pi is 256 Mb. Perhaps I am wrong and recommended 128MBs is better.

Test if it works:


pi@blackberrystar ~ $ mkdir picam
pi@blackberrystar ~ $ cd picam
pi@blackberrystar ~ $ raspistill -o image.jpg

The result (the first picture taken) is shown on the picture.

sobota, 16 listopada 2013

Nowsza wersja Raspberry Pi

Do posiadanego Raspberry Pi w wersji A (256 Mb) dokupiłem parę dni temu drugi egzemplarz, tym razem w wersji B (512 Mb). Kupiłem też kartę WiFi TP-link TL-WN725N oraz kamerę. Plan jest taki:

  • kamerę podłączyć do starego Pi (kupionego w sierpniu 2012); udostępnić je poprzez WiFi, chociażby dlatego że wszystkie 4 porty w moim ruterze są już zajęte.
  • to co było podpięte do starego Pi (pomiar temperatury, wilgotności (DHT-22) i ciśnienia (BMP085) oraz kamera Logitech C270) podpiąć pod nowe.

Doczepienie wszystkiego do jednego komputerka nie wchodzi w grę bo docelowo kamera ma być mobilna.

Nie chciałem instalować nowego systemu tylko skorzystać z tego co używam do tej pory (tj. system używany na starym Pi):


uname -a
Linux raspberrystar.pinkaccordions.org 3.2.27+ #174 PREEMPT ...

Prosta wymiana karty nie działa (system się nie uruchamia). Potrzebny jest zapewne upgrade:


sudo apt-get update
sudo rpi-update
uname -a
Linux raspberrystar.pinkaccordions.org 3.10.18+

Teraz przestała działać magistrala 1-Wire. Nie mogę też uruchomić karty WiFi TP-link TL-WN725N. Gdzieś na forach doczytałem, że wersja 3.6.11+ może być pod tym względem mniej problematyczna. Zatem próbuję:


sudo rpi-update 8234d5148aded657760e9ecd622f324d140ae891

Powyższe oznacza cofnięcie się do najstarszej wersji oznaczonej symbolem 3.6.11+:


pi@raspberrystar ~ $ uname -a
Linux raspberrystar.pinkaccordions.org 3.6.11+ #557 PREEMPT

Teraz magistrala 1-Wire magicznie zaczęła działać. Czujniki DHT-22 też działają. Czujnik ciśnienia BMP085, obsługiwany przez program opisany tutaj, wymagał drobnej modyfikacji i przekompilowania, bo zmienił się układ wejść GPIO.

Karta WiFi też działa, ale wymagała ściągnięcia stosownego sterownika. U mnie działa ten (kopia jest tutaj). Natomiast inne, np. udostępniane tu albo tutaj nie działają. Także kompilacja wg. sposobu opisanego tutaj (po polsku jest tutaj) kończy się błędem.

Moduł 8188eu.ko należy zainstalować w następujący sposób:


wget http://www.mendrugox.net/downloads/13 -O 818188eu.ko
## albo https://dl.dropboxusercontent.com/u/61315145/PiStuff/8188eu.ko.gz
## po ściągnięciu: gunzip 8188eu.ko.gz

sudo install -p -m 644 8188eu.ko /lib/modules/`uname -r`/kernel/drivers/net/wireless
sudo depmod -a
sudo modprobe 8188eu

Zawartość pliku /etc/network/interfaces powinna wyglądać następująco:


auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-ssid "NAZWA-SIECI"
wpa-psk "HASŁO"

Należy oczywiście podać prawidłowe wartości dla NAZWY-SIECI oraz HASŁA. Takie ustawienie powoduje automatyczne ustanowienie połączenia po uruchomieniu systemu.

Zmiana nazwy hosta

Sprawa drobna ale potrzebna żeby wiedzieć który jest który:


## w ostatnim wierszu /etc/hosts zmień nazwę hosta
sudo vi /etc/hosts

## wpisz nazwę hosta (ten plik zawiera jeden wiesz, nazwę hosta):
sudo vi /etc/hostname

sudo /etc/init.d/hostname.sh
sudo reboot

W rezultacie mój plik /etc/hosts wygląda jakoś tak:


127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

127.0.1.1 blackberrystar

Kamera

Uaktualniony i działający na nowym Pi system sklonowałem na drugą kartę (BTW. Od lat używam kart Toshiba SDHC 8GB Class 10. Karta ta jest reklamowana jako typu SLC aczkolwiek na opakowaniu/karcie nie ma o tym ani słowa. SLC czy nie SLC nigdy nie miałem z tą kartą żadnych problemów.)

Pi + kamera
Pi + kamera

Pierwsze zdjęcie

Jak podłączyć kamerę do komputerka można obejrzeć na jednym z licznych filmów na YouTube.

Dalej postępowałem wg. instrukcji na stronie How to set up the camera hardware.

Ponieważ wcześniej tego nie robiłem:


pi@blackberrystar ~ $ sudo apt-get update # na wszelki wypadek
pi@blackberrystar ~ $ sudo apt-get upgrade

teraz:


pi@blackberrystar ~ $ sudo raspi-config

Wybieram Enable/Disable camera addon support a następnie Memory split. Nie zdecydowałem się na sugerowane wydzielenie 128 Mb na GPU, mając na uwadze, że cała pamięć w moim Pi to raptem 256 Mb. Być może niepotrzebnie się spłoszyłem -- doczytam jeszcze na ten temat.

Test czy działa:


pi@blackberrystar ~ $ mkdir picam
pi@blackberrystar ~ $ cd picam
pi@blackberrystar ~ $ raspistill -o image.jpg

Wynik (pierwsze wykonane zdjęcie) jest zamieszczony obok.

niedziela, 6 października 2013

SimpleCart.js

Koledze założyłem sklep--nie sklep (katalog książek z możliwością złożenie zamówienia.) Koszyk obsługuje aplikacja w JavaScript pn. SimpleCart.js. Na początek powinno koledze GB wystarczyć (albo i nie....)

Nie działa toto z Internet Explorerem wersja 7 ale na szczęście mało kto dziś używa IE 7. Zrobiłem upgrade swojego (a raczej Jaśka bo ja nie korzystam z Windows) do IE 8 i zaczęło działać. Jeszcze się temu przyjrzę...

poniedziałek, 23 września 2013

Pobranie zawartości zbioru/grupy zdjęć z flickr.com

Zbiór to set a grupa to pool. Zbiór zawiera zdjęcia jednego użytkownika a grupa (pool) to zbiór zdjęć różnych użytkowników. To tak tytułem wyjaśnienia.

Flickr API zawiera funkcje flickr.groups.pools.getPhotos oraz flickr.photosets.getPhotos, które zwracają informacje o zdjęciach należących do określonego zbioru (albo grupy). Wynik wygląda jakoś tak:


<photoset id="4" primary="2483" page="1" perpage="500" pages="1" total="2">
<photo id="2484" secret="123456" server="1" title="my photo" isprimary="0" />
<photo id="2483" secret="123456" server="1" title="flickr rocks" isprimary="1" />
</photoset>

Poniższy skrypt wykorzystujący flickr.groups.pools.getPhotos/flickr.photosets.getPhotos ściąga informacje o zdjęciach dodanych do grupy/zbioru. Wynik zapisuje w Perlowej notacji:


@photos=( {'id'=>"2484", 'secret'=>"123456", 'server'=>"1", 'title'=>"my photo", 'isprimary'=>"0"},
{'id' =>"2483", 'secret'=>"123456", 'server'=>"1", 'title'=>"flickr rocks", 'isprimary'=>"1", );

Jest to zatem gotowy do dołączenia do innego skryptu np. za pomocą require kod Perla (lista haszy). Ściągana jest informacja o grupie lub zbiorze określonej/określonym przez podanie stosownego id:


flickr_albums.getPhotos.pl -s set-id
# albo
flickr_albums.getPhotos.pl -p group-id

Uwaga: moduł login2flickr.rc deklaruje m.in stosowną wartość api_key co jest niezbędne do korzystania z API flickra.


#!/usr/bin/perl
#
use Flickr::API;
use Compress::Zlib;
use Getopt::Long;
use XML::DOM;

require 'login2flickr.rc'; # prywatny moduł do

$set_id = $pool_id = $method = $Photos='';

GetOptions( "set=s" => \$set_id, "pool=s" => \$pool_id, ) ;

if ( $set_id ne "" ) {
$root_ele = 'photoset';
$method = 'flickr.photosets.getPhotos';
$ofname = "set-${set_id}.ph";
}
elsif ( $pool_id ne "" ) {
$root_ele='photos';
$method = 'flickr.groups.pools.getPhotos';
$ofname = "pool-${pool_id}.ph";
} else {
die "*** Podaj id zbioru/pula (set-id/pool-id)\n";
}

## ### ### ### ### ###
my $extras = 'date_taken,views,url_o,url_m,geo,tags';

my $api = new Flickr::API({'key' => $api_key, secret => $sharedsecret});
my $parser = XML::DOM::Parser->new();

my $nbrPages = $photoIdx = 0;

do
{
my $params = { per_page => 500, page => $nbrPages+1, extras => $extras };

$params->{group_id} = $pool_id if $pool_id;
$params->{photoset_id} = $set_id if $set_id;

##print STDERR "*** Method/params: $method, $params ***\n";
my $response = $api->execute_method($method, $params );

die "Problem: $response->{error_message}\n" if !$response->{success};

## sprawdz czy _content nie jest gzipniety, jezeli to rozpakuj:
my $content_encoding = $response->{_headers}->{'content-encoding'} ;
my $plain_content ;

if ($content_encoding =~ /gzip/ ) {
$plain_content = Compress::Zlib::memGunzip( $response->{_content});
} else { $plain_content = $response->{_content}; }

my $log = $parser->parse($plain_content);

## Dane są podzielone na strony o maksymalnej wielkości 500 zdjęć:
for $ps ( $log->getElementsByTagName( $root_ele ) ) {
if ($ps->getAttributeNode ("page") ) { $page = $ps->getAttributeNode ("page")->getValue(); }
if ($ps->getAttributeNode ("pages") ) { $pages = $ps->getAttributeNode ("pages")->getValue(); }
}

print "*** Page $page of $pages ***\n";

## dla każdego elementu:
for $p_ ( $log->getElementsByTagName('photo') ) {
$element_content='';

## zapisz wszystkie atrybuty
if ($p_ ->getAttributes() !=null){
$numberAttributes = $p_->getAttributes()->getLength();
}

for ($loopIndex =0; $loopIndex < $numberAttributes; $loopIndex++) {
$attribute = ($p_ -> getAttributes())->item($loopIndex);
$attrname = $attribute->getNodeName();
$attrvalue = $attribute->getNodeValue();
$element_content .= "'$attrname' => '$attrvalue', ";
}

$Photos .= "{ $element_content },\n";
$photoIdx++;
}

++$nbrPages;

} while ($page < $pages );

## ## ###
print STDERR "Writing to $ofname\n";
open (OFILE, ">$ofname");
print OFILE "## Created with $method\n\@photos = (\n $Photos \n);\n1;\n";
close OFILE;

print STDERR "*** $photoIdx photos written to $ofname ***\n";

Skrypt jest do pobrania tutaj.

sobota, 31 sierpnia 2013

Importowanie i wyświetlanie plików KML w Google Maps

Ubocznym skutkiem dodania współrzędnych geograficznych do zdjęć za pomocą skryptu gpsPhoto.pl jest plik w formacie KML. Każde zdjęcie w takim pliku jest oznakowane jak na przykładzie:


#1: Import do GMaps

#2: Z pinkaccordions

#3: Z sites.google.com

#4: Z sites.google.com

#5: Z serwera chello.pl

<Placemark>
<name>s300013_08275298.jpg</name>
<description><![CDATA[<a href="/home/tomek/Obrazy/s300013_08275298.jpg">
<img src="/home/tomek/Obrazy/s300013_08275298.jpg" width="200" /></a><br>
<a href="/home/tomek/Obrazy/s300013_08275298.jpg">full size</a>]]>
</description>
<Point>
<altitudeMode>clampToGround</altitudeMode>
<coordinates>16.496808361,53.466461571,122</coordinates>
</Point>

Dawno temu zrobiłem skrypt, który podmienia adres w lokalnym systemie plików (taki jak /home/tomek/Obrazy/s300013_08275298.jpg) na tenże plik, ale umieszczony na moim koncie w serwisie flickr.com:


<Placemark>
<name>s300013_08275298.jpg</name>
<description><![CDATA[<a href="http://www.flickr.com/tprzechlewski/9615076609/">
<img src="http://static.flickr.com/7411/9615076609_a243eed0f1_m.jpg" width="200" /></a><br>
<a href="http://www.flickr.com/tprzechlewski/9615076609/">full size</a>]]>
</description>
... itd ...

Taki plik za pomocą kilku klików importowałem do mapy Google (Mapy→Moje Miejsca → utwórz w klasycznej wersji Moich map) i działało -- do zeszłego piątku, kiedy to plik KML z wycieczki do Nadarzyc uparcie nie chciał się poprawnie wyświetlić (#1 -- obcięty ślad w okolicach Nadarzyc).

Konsultując problem via Google dowiedziałem się, że cyt KML upload and rendering has always been problematic with Maps i że lepiej (jeżeli już) to nie importować KML tylko wyświetlić go podając URL do dokumentu KML jako wartość parametru q. Przykład:


https://mapy.google.pl/maps?q=http://pinkaccordions.homelinux.org/Geo/kml/20130828__MP.kml

Działa (rys. #2). Ponieważ serwer pinkaccordions.homelinux.org jest rachityczny pomyślałem, że dobrze by było plik KML umieścić w jakimś lepszym miejscu, np. na witrynie sites.google.com. Jest nawet dedykowany -- i niestary bo z 2010 roku -- dokument w temacie pn. Using Google Sites to Host Your KML

Niestety plik KML pobierany z http://sites.google.com/site/ nie wyświetla się poprawnie. Po kliknięciu w ikonę niektórych zdjęć otwiera się okno ale jest ono puste (#3) i/lub nie wskazuje na stosowne miejsce na mapie (por. #4). Kombinowałem jak toto poprawić ale nie doszedłem do żadnych pozytywnych wniosków: połączenie GMaps + KML + sites.google.com nie działa.

PS: przypomniałem sobie, że mój Internet Provider daje w pakiecie konto na serwerze WWW z limitem 200Mb (z którego do tej pory mało korzystałem)... Sprawdziłem -- działa. Będę zatem tam trzymał pliki KML/KMZ (Rys. #5.)

Wycieczka do Bornego Sulinowa

We wtorek pojechaliśmy do Nadarzyc koło Bornego Sulinowa (Gross Born). Głównym punktem wycieczki był spływ rzeką Piławą. Byliśmy na miejscu (agroturystyka U Stasia w Nadarzycach nad brzegiem Piławy) tuż po 11:00. Dalej standard: pojechaliśmy samochodem właściciela i jego kajakami do mostu nad Piławą we wsi Liszkowo. Około 12:00 z tego miejsca zaczęliśmy spływ, który skończyliśmy U Stasia tuż przed 18:00.

Miejscami jest bardzo szeroko, miejscami rzeczka jest płytka i wąska. Jest odcinek z przeszkodami (zwalone drzewa), ale da się płynąć. Dwa razy trzeba przenieść kajak.

Drugi raz w życiu widziałem zimorodka!

Rzeczka jest malownicza a miejsce wydaje się odludne (byliśmy wszakże ,,po sezonie''). Płynąc Piławą warto zapoznać się z trasą, mieć GPSa albo mapę bo na jeziorach są czasami wątpliwości ,,którędy dalej...''

Następnego dnia poszwendaliśmy się po Bornym Sulinowie oraz zwiedziliśmy kirkut w Jastrowie.

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

sobota, 24 sierpnia 2013

Konwersja z WordPressa do Bloggera

Kol. DM pisze sobie bloga używając WordPressa. Trochę go to kosztuje więc pojawiła się koncepcja żeby przeszedł na bezpłatnego Bloggera. Początkiem tej koncepcji jest oczywiście konwersja WP do formatu Bloggera.

Wpisy kol. DM zawierają tekst i dużo zdjęć oraz innych rysunków. Nie mam bladego pojęcia nt. WordPressa, ale dość szybko ustaliłem, że można wyeksportować treść posługując się stosowną funkcją dostępną z Kokpit→Narzędzia→Eksport (powstaje plik w formacie WordPress eXtended RSS -- WXR).

Plik WXR zapisujemy na dysku. Można go zamienić do formatu Bloggera korzystując z konwertera dostępnego tutaj. Jest wprawdzie napisane, że konwerter obsługuje pliki nie większe niż 1Mb, ale mój miał 4Mb i też poszło.

Plik kolegi DM zawiera tekst oraz prawidłowe linki do niektórych rysunków. Inne rysunki są wstawiane sprytnym czymś co nazywane jest shortcode (cf Shortcode API.) Nie wchodząc w szczegóły, zamiast rysunków w treści postu jest umieszczone np. coś takiego:


[nggallery id=506]

506 z kolei jest identyfikatorem zbioru rysunków, które fizycznie są przechowywane w katalogu:


wp-content/gallery

Każda galeria jest w oddzielnym katalogu, ale nazwami katalogów nie są identyfikatory typu 506 ale coś innego. Logując się do phpMyAdmin byłem w stanie ściągnąć całą bazę (w formacie SQL), w której siedzi WordPress. W jednej z tabel bazy znalazłem przypisanie id_galerii→nazwa-katalogu-z-plikami


INSERT INTO `wp_ngg_gallery` (`gid`, `name`, `slug`,
`path`, `title`, `galdesc`, `pageid`, `previewpic`, `author`) VALUES
(17, 'gottardo_2', '', 'wp-content/gallery/gottardo_2', '', '', 0, 0, 1),
(16, 'gottardo_1', '', 'wp-content/gallery/gottardo_1', '', '', 0, 0, 1),
(15, 'nufenen', '', 'wp-content/gallery/nufenen', NULL, NULL, 0, 0, 1),
... itd ...

Czyli zawartość czegoś, co w treści wygląda jak:


[nggallery id=15]

Znajduje się w katalogu wp-content/gallery/nufenen.

Teraz ściągnąłem cały katalog wp-content na dysk lokalny wykorzystując ncftp


ncftp -u USER -p PASS HOST
get -R -T wp-content

Następnie zamieniłem nazwy plików w następujący sposób:


nr_galerii__nazwa_pliku

Pliki wysłałem na google za pomocą skryptu. Istotne jest to, że skrypt po załadowaniu, zwraca URL zdjęcia pod którym jest ono dostępne na koncie googla:


100__fra_07063.jpg https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnGM8VIJfmKu-dEbNbqqqNEV0DwoloVFw9uktPM6qJpmYSzKJITMugQqH2B0MeTAAFAgCX9o3vRmytf1UvdoBaA5TieHIgp3byMZFEtNmu9RfVCYzzN0xBdtq5wamOf_OMhqbHj4CxwYPt/
100__fra_07064.jpg https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPtWKcJyxiQsoE03R_7UAS-ScRhy-VtXpQ9swfpgaz6S8v_ypfliLJnIFDD92ae9Ctj31J_zLUaara8zC4pPp26Tkv2qzx2jZexmIdHMoX0qIdI9vuw3FE1oiNUCnZZwNSLkxVyYxUBCxX/
itd...

Czyli zdjęcie 100__fra_07063.jpg (oryginalnie należące go galerii o identyfikatorze równym '100') jest dostępne pod adresem:


https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnGM8VIJfmKu-dEbNbqqqNEV0DwoloVFw9uktPM6qJpmYSzKJITMugQqH2B0MeTAAFAgCX9o3vRmytf1UvdoBaA5TieHIgp3byMZFEtNmu9RfVCYzzN0xBdtq5wamOf_OMhqbHj4CxwYPt/

Uwaga: Album ze zdjęciami na koncie googla może zawierać maksymalnie 1000 zdjęć. Jeżeli zdjęć jest więcej trzeba utworzyć więcej albumów.

Skryptem Perla (wyrażenia regularne/regułowe) zamieniam każde [nggallery id=506] na stosowny ekwiwalent. Przykładowo:


&lt;div id='gid_g509'&gt;
&lt;span&gt;&lt; a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGXJg1WrcrBW1kJl3RJn9FPNSWk2hFjiC6dgFfslV3yjdpco2aIMEeYaQXQkirZuahaKiXCTQOqhcW7c1NQAXOpRBjCzyfQWiMptLCozUJy91d83j0gp2YncFkXvcwvHLaSPv3mfaxJJWo/"
imageanchor="1" style="margin-bottom: 1em; margin-right: .1em;"&gt;
&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGXJg1WrcrBW1kJl3RJn9FPNSWk2hFjiC6dgFfslV3yjdpco2aIMEeYaQXQkirZuahaKiXCTQOqhcW7c1NQAXOpRBjCzyfQWiMptLCozUJy91d83j0gp2YncFkXvcwvHLaSPv3mfaxJJWo/s128/509__1106_016.jpg"
height='85' /&gt;&lt;/a&gt;
&lt;/span&gt;
... itd ...

Pozostałe zdjęcia mają `prawdziwe URLe' (a nie jakieś shortcody), ale oczywiście URLe te są złe bo wskazują na starego hosta. Zdjęcia te (z `prawdziwymi URLami') są przechowywane w katalogu ./wp-content/uploads. Ze zdjeciami postępuję, tak jak w przypadku zdjęć z galerii: 1) wysyłam na konto google skryptem; 2) zmieniam oryginalne URLe na URLe z konta google (skryptem Perla).

Przed importem do Bloggera warto sprawdzić czy plik, który ma być zaimportowany jest well-formed:


xmllint plik-do-zaimportowania.xml

czwartek, 22 sierpnia 2013

Problematyczny Lightbox w Bloggerze

Kliknięcie zdjęcia lub obrazu zamieszczonego na blogu powoduje wyświetlenie go w nakładce na stronie. Jest to tzw. widok Lightbox. (cf. Widok Lightbox w Bloggerze):

<div>
<span>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU6xuLcKQQ-_ccqmRlM7tjekEMVB4Jgx2UvxS8wqL5154fLo383vlvKYmL4wvghW9wCu6nIyGyvW5eyEv4TNkScK3qc0zGJxZ4EOAC7Pb0YWWnBFGpDgcrmXwqNFP1au-D_nwrdBMPd78N/" 
 imageanchor="1" style="margin-bottom: 1em; margin-right: .1em;"><img border="0" 
 src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU6xuLcKQQ-_ccqmRlM7tjekEMVB4Jgx2UvxS8wqL5154fLo383vlvKYmL4wvghW9wCu6nIyGyvW5eyEv4TNkScK3qc0zGJxZ4EOAC7Pb0YWWnBFGpDgcrmXwqNFP1au-D_nwrdBMPd78N/s128/epl313_6040342.jpg" /></a>
</span>
<span>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8MsKjD61FOS9mOciTMc2srBAy9YeDnFfq05r_PPhFA8-psqNilfs5hkET159ViIBg07tw9kJBFT2Yy-aI7KplfVUNvmICu07pwX0Q2UPiQenTfmKh11P_ZrAs1_aRZjdeDiHTOyyy-gu6/" 
 imageanchor="1" style="margin-bottom: 1em; margin-right: .1em;"><img border="0" 
 src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8MsKjD61FOS9mOciTMc2srBAy9YeDnFfq05r_PPhFA8-psqNilfs5hkET159ViIBg07tw9kJBFT2Yy-aI7KplfVUNvmICu07pwX0Q2UPiQenTfmKh11P_ZrAs1_aRZjdeDiHTOyyy-gu6/s128/epl313_6040338.jpg" /></a>
</span>
<span>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA059OOx8ZLS7XqpiZ94iAZ7fdepsU3VAnGCeZ01SiDImelMrjHZwBd5g_o9shvBVB4Ut6x-_cfDrT51VvTc8KuQ7VlCYcZhOr0kEFenfurTKIs_rescLpAKu3-QbCtdwMmDEFaehvU3FM/" 
 imageanchor="1" style="margin-bottom: 1em; margin-right: .1em;"><img border="0" 
 src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA059OOx8ZLS7XqpiZ94iAZ7fdepsU3VAnGCeZ01SiDImelMrjHZwBd5g_o9shvBVB4Ut6x-_cfDrT51VvTc8KuQ7VlCYcZhOr0kEFenfurTKIs_rescLpAKu3-QbCtdwMmDEFaehvU3FM/s128/epl313_6040339.jpg" /></a>
</span>
<span>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0jT3S-QbEQ4sUexmIQoryhbi2C53tWrO0yHFrZyhRI-Q3naU_KxDipx0005eXd5t6WTgGwcpHnPDJyYWSG1en1R7aEmtpFxkJbc0tRWjQj3lr2_jNtfNn9B-FAVrtLenz8qLyizwxvOq1/" 
 imageanchor="1" style="margin-bottom: 1em; margin-right: .1em;"><img border="0" 
 src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0jT3S-QbEQ4sUexmIQoryhbi2C53tWrO0yHFrZyhRI-Q3naU_KxDipx0005eXd5t6WTgGwcpHnPDJyYWSG1en1R7aEmtpFxkJbc0tRWjQj3lr2_jNtfNn9B-FAVrtLenz8qLyizwxvOq1/s128/epl313_6040332.jpg" /></a>
</span>
</div>

Wynik jest następujący (kliknij w zdjęcie aby przejść do widoku Lightboksa):

W powyższym przykładzie zawartość atrybutów href i src jest prawie identyczna, bo różni się wyłącznie fragmentem s128/. Jest to przykład zastosowania sprytnego URLa, który spowoduje automagiczne przeskalowanie zdjęcia, tak aby dłuższy wymiar miał maksymalnie 128 pikseli. Jeżeli zamiast s128/ wstawimy s128-c/ albo s128-p/, to spowoduje to automagiczne wycięcie kwadratu o wymiarach maksymalnych 128 pikseli (crop). Przykład:

<div>
<span>
<a href="http://lh3.ggpht.com/…/epl313_6040338.jpg" 
 imageanchor="1" style="margin-bottom: 1em; margin-right: .1em;"><img border="0" 
 src="http://lh3.ggpht.com/…/s128-c/epl313_6040338.jpg" /></a>
</span>
<span>
<a href="http://lh3.ggpht.com/…/epl313_6040338.jpg" 
 imageanchor="1" style="margin-bottom: 1em; margin-right: .1em;"><img border="0" 
 src="http://lh3.ggpht.com/…/s128-p/epl313_6040338.jpg" /></a>
</span>

Symbolem … oznaczono pominiętą część URLa (żeby nie wystawał na margines).

Wynik (kliknięcie w zdjęcie nie powoduje przejścia do widoku Lightboksa):

BTW: Liczba 128 nie jest magiczna, można przeskalować obrazek na inny wymiar.

Jeżeli zdjęcia są różnych wymiarów (portret/pejzaż), to s128-c/ (albo s128-p/) jest lepsze niż zwykłe s128, bo minaturki są jednakowej wielkości, tyle że Lightbox takie zdjęcia ignoruje. Czemu -- nie wiem... Nie wiem też jak to zmienić

Jako obejście problemu można przeskalować miniaturkę do jednakowej wysokości. Przykład:

<div>
<span>
<a href="https://lh4.googleusercontent.com/…/epl313_6040342.jpg" 
 imageanchor="1" style="margin-bottom: 1em;"><img border="0" height='85'
 src="https://lh4.googleusercontent.com/…/s128/epl313_6040342.jpg" /></a>
</span>
<span>
<a href="http://lh3.ggpht.com/…/epl313_6040338.jpg" 
 imageanchor="1" style="margin-bottom: 1em;"><img border="0" height='85'
 src="http://lh3.ggpht.com/…/s128/epl313_6040338.jpg" /></a>
</span>
<span>
<a href="http://lh6.ggpht.com/…/epl313_6040339.jpg" 
 imageanchor="1" style="margin-bottom: 1em;"><img border="0" height='85'
 src="http://lh6.ggpht.com/…/s128/epl313_6040339.jpg" /></a>
</span>
<span>
<a href="http://lh5.ggpht.com/…/epl313_6040332.jpg" 
 imageanchor="1" style="margin-bottom: 1em;"><img border="0" height='85'
 src="http://lh5.ggpht.com/…/s128/epl313_6040332.jpg" /></a>
</span>
</div>

Symbolem … oznaczono pominiętą część URLa (żeby nie wystawał na margines).

Wynik jest następujący:

Kliknięcie w zdjęcie powoduje przejście do widoku Lightboksa.

Być może za czas jakiś problem zniknie. Wyświetlanie dla tego wpisu 10 zamiast 8 obrazków w widoku Lightboksa będzie tego dowodem:-)