BlipPy - biblioteka pythonowa do Blipa

BLipPyParę dni temu postanowiłem pouczyć się czegoś nowego. Padło na polecanego mi przez wielu znajomych Pythona. Ale jak to ze mną bywa nie umiałem uczyć się “na sucho” i musiałem znaleźć sobie jakiś cel. Postanowiłem zatem napisać prostą bibliotekę komunikacyjną, która umożliwia interakcję z serwisem Blip.pl. Dlaczego akurat Blip? Po pierwsze go używam, a po drugie dowiedziałem się, że ma API. I tak oto powstała biblioteka obsługująca Blipa dla Pythona. Nazywa się BlipPy.

Z czym to się je?

Jedzenie należy zacząć od zassania samej biblioteki. Aktualna wersja, czyli 0.1, jest dostępna w repozytorium subversion. Póki co zawiera jedynie jedną klasę o nazwie Communicator, która zapewnia komunikację z Blipem poprzez API. W planach wersji 0.2 jest napisanie innej klasy, która będzie zarządzała danymi zasysanymi z Blipa. Będzie ona najprawdopodobniej użyta do napisania klienta desktopowego Blipa (kolejny etap mojej nauki). Narazie jest tylko komunikacja - powiedzmy - niskopoziomowa.
Aby pobrać bibliotekę należy mieć zainstalowanego klienta subversion i wydać następującą komendę:

svn co https://blippy.svn.sourceforge.net/svnroot/blippy blippy

Biblioteka jest mała i zawiera się w jednym pliku o nazwie blippy.py. Wystarczy go umieścić w katalogu naszej aplikacji i zaimportować. Należy także doinstalować moduł cjson, który jest używany przez bibliotekę do obsługi formatu JSON. W dalszej części pokrótce opiszę, jak używać BlipPy’ego. Nie będzie to syntetyczny opis wszystkich metod, gdyż do tego lepsze będą komentarze opisujące metody. Tutaj tylko parę przykładów obrazujących jak zacząć biblioteki używać. Zaczynamy…

Inicjalizacja

Do komunikacji z Blipem, jak wspomniałem, służy klasa Communicator. Tak tworzymy jej instancję:

import blippy

com = blippy.Communicator("user", "password")

Za pomocą powyższego kodu zostanie utworzony komunikator uwierzytelniony, czyli działający w kontekście danego użytkownika serwisu Blip.pl. Jako trzeci parametr można podać tzw. user-agent (czyli jak się przedstawiamy serwerowi Blipa). Można także w ogóle pominąć parametry i wtedy komunikator będzie anonimowy. Pamiętajcie jednak, że wiele operacji na zasobach Blipa wymaga podania użytkownika i hasła.

Pobranie bliposfery

Najprostszą czynnością na Blipie jest chyba pobranie bliposfery, czyli n-ostatnich statusów użytkowników. Gdy już mamy obiekt Communicator możemy pobrać tę informację w taki oto sposób:

bliposphere = com.GetBliposphere(10)

Spowoduje to pobranie ostatnich 10 statusów bliposfery. Zmienna bliposphere będzie zawierała tablicę 10 słowników. W każdym słowniku znajduje się para klucz->wartość. Oto przykładowa zawartość pojedynczego słownika:

{
'body': u'Ha, nowiutki statusik :)',
'user_path': '\\/users\\/bayger',
'created_at': '2008-03-29 12:00:00',
'type': 'Status',
'id': 123456789,
'transport': {'name': 'sms', 'id': 2}
}

Z nazw kluczy słownika możemy wywnioskować ich zawartość. Po szczegóły zapraszam do oficjalnej dokumentacji API Blipa, gdzie podane są przykłady zwracanych wartości przez API.

Wysłanie nowego statusu

Równie prostą czynnością jest wysłanie nowego statusu na Blipa. Potrzebujemy do tego uwierzytelnionego Communicatora, a robimy to tak:

com.SendStatus("Oh hai! I iz tryng to blip somtink")

Po wykonaniu się powyższej operacji powinniśmy na kokpicie użytkownika i bliposferze zaobserwować nowy status. Dodam tylko, że metody klasy Communicator oczekują łańcuchów znaków w kodowaniu UTF-8.

Wysłanie wiadomości do użytkownika

Kolejną rzeczą, jaką udostępnia API Blipa jest wysyłanie tzw. wiadomości skierowanych do użytkownika. Nie są one tak naprawdę prywatne (każdy może je zobaczyć), ale ukazują się tylko na kokpicie adresata. Tak wysyła się wiadomość skierowaną:

com.SendMessage("nick_adresata", "wiadomość_do_adresata")

Jeśli wszystko pójdzie dobrze to adresat powinien dostać wiadomość.

Obsługa błędów

Błędy obsługiwane są standardowo, czyli za pomocą wyjątków. Jeśli coś pójdzie nie tak to dana metoda rzuci jednym z następujących wyjątków:

  • NotFoundException - gdy brak szukanego zasobu na serwerze
  • BadArgumentsException - gdy źle podaliśmy argumenty wywołania (np. w niedozwolonym formacie)
  • BadCredentialsException - gdy próbujemy zrobić coś, co wymaga uwierzytelnienia a podaliśmy zły login/hasło (lub nie podaliśmy)
  • ServerBusyException - gdy serwer jest bardzo zajęty i nie może obsłużyć naszego żądania; należy spróbować ponownie
  • BadOperationException - gdy wystąpił bliżej nieokreślony błąd

Update: Dodatkowo metody mogą rzucić wyjątkami, gdy coś na linii protokołu HTTP będzie nie tak.

Co innego udostępnia BlipPy?

Ponieważ wszystkie przykłady użycia biblioteki są dość proste wymienię tylko możliwości jakie daje w obecnym kształcie BlipPy:

  • pobieranie bliposfery i kokpitu użytkownika
  • wysyłanie i kasowanie statusów i wiadomości skierowanych
  • pobieranie informacji o obrazkach, nagraniach, linkach, filmach
  • pobieranie informacji o avatarch i tłach użytkowników
  • ustawianie avatara i tła użytkownika
  • dodawanie i usuwanie obserwowanych użytkowników
  • pobieranie informacji o użytkownikach

Co dalej?

Kolejna wersja biblioteki (0.2) będzie najprawdopodobniej udostępniała klasę zarządzającą komunikacją z Blipem. Innymi słowy będzie to podstawa do napisania klienta desktopowego dla Blipa. Jego kształt dopiero rodzi się w mojej głowie. Poza tym muszę zbadać co oferuje Python jeśli chodzi o programowanie UI. O postępach nie omieszkam powiadomić na łamach bloga. Poza tym dodam do Communicatora obsługę offsetów, które umknęły mi w czasie lektury API.

Przypominam także, że jest to mój pierwszy kod w Pythonie i, być może, nie jest on najlepszy. Starałem się wpasować w język jak tylko na daną chwilę umiałem. Chętnych proszę o testowanie i wysyłanie ewentualnych uwag, bugów, sugestii na mój adres email (patrz: strona O mnie) lub po prostu w komentarzach poniżej. Z góry za nie dziękuję!

Do, do it now!

Podręczny pomocnik

W repozytoriach nowego Ubuntu 8.04 (tak, przesiadłem się na Ubuntu) znalazł się wspaniały program ułatwiający życie w środowisku graficznym. Nazywa się GNOME Do. Cóż to takiego? W kilku słowach określiłbym Do jako podręczną wyszukiwarkę plików, aplikacji i innych zasobów. Podręczną dlatego, że uruchamia się skrótem klawiszowym Win+Spacja. Przypomina mi on bardzo Mac OSowego Quicksilvera. Po wciśnięciu rzeczonej kombinacji klawiszy pokazuje się na środku ekranu takie okienko:

GNOME Do

Teraz wystarczy zacząć wstukiwać litery, aby Do zaczął działać. Np. wpisując ‘pid’ program podpowiada, że może uruchomić Pidgina. Gdy wpiszemy kawałek adresu strony WWW Do zachęci nas do przejścia na stronę o takim adresie (domyśli się pełnego adresu z zakładek przeglądarki). Do potrafi także wyszukiwać pliki w naszym katalogu domowym (a nawet je przenosić czy kopiować). Wystarczy, że wpiszemy kawałek nazwy i już. Oto krótka prezentacja jego możliwości:


Gnome Do in action! umieszczone na Vimeo.

Fajne, prawda? Program obsługuje się bardzo prosto. Jak napisałem wystarczy wstukać kilka literek, aby Do coś podpowiedział. Jeśli to nas nie satysfakcjonuje wystarczy nacisnąć klawisz strzałka-w-dół, aby zobaczyć więcej podpowiedzi. Poza tym możemy przechodzić pomiędzy elementami klawiszem Tab. Przydatne jest to, gdy chcemy wybrać inną operację przypisaną do znalezionego zasobu niż domyślna.

Dokładnie rzecz biorąc Gnome Do potrafi za pomocą swojego okienka dać nam szybki dostęp do m.in. następujących rzeczy:

  • pliki w katalogu domowym użytkownika
  • programy dostępne z menu startowego
  • adresy WWW z przeglądarki (z zakładek)
  • definicje słowa w słowniku angielskim (za pomocą programu Dictionary)

A to są tylko rzeczy dostępne w podstawowej wersji.

Wtyczki

Prawdziwą siłą Gnome Do jest możliwość rozszerzania go poprzez wtyczki (plugins), których jest sporo. Dla przykładu mamy wtyczki współpracujące z takimi programami, jak Pidgin, Rythmbox czy Evolution.
Wtyczki instalujemy poprzez skopiowanie ich do katalogu ~/.local/share/gnome-do/plugins i restart programu. Dla przykładu tak wygląda szukanie muzyki w Rythmboksie:

Do i Rythmbox

Polecam

Nie pozostaje mi nic innego jak polecić Wam wszystkim ten mały użytek. Na koniec mała uwaga: program uzależnia i gdy usiądziemy przy systemie bez Do odruchowo będziemy wciskać Win+Spacja. Ja już nie mogę bez niego żyć. :)
PS. Do stworzenia screencasta posłużyłem się wiedzą zawartą w artykule z Fabrikum9. Także polecam!

Logitech MX600 pod Linuksem

Myszka Logitech MX600Szybka notka o tym, jak skonfigurować myszkę Logitech MX600 pod Linuksem. Dodam tylko, że myszka ta znajduje się między innymi w zestawie Cordless Desktop MX3000. Wszyscy jej posiadacze cierpiący na niedziałające klawisze Back/Forward znajdą tutaj na to lekarstwo.

Konfiguracja myszki pod X.org 7.2 (Ubuntu 7.10)

System Ubuntu 7.10 (czy też np. Debian Lenny) jest właściwie w pełni gotowy na obsługę myszek z więcej niż 3 przyciskami (poprzez serwer X.org 7.2 jeśli się nie mylę). Sęk w tym, że zazwyczaj nie jest do tego skonfigurowany. Więc co zrobić? Należy otworzyć plik /etc/X11/xorg.conf i wyszukać sekcję dotyczącą myszki (powinna mieć identyfikator: “Configured Mouse”). Jej zawartość zastąpić należy poniższą:

Section "InputDevice"
        Identifier      "Configured Mouse"
        Driver          "mouse"
        Option          "CorePointer"
        Option          "Device"        "/dev/input/mice"
        Option          "Protocol"      "ExplorerPS/2"
        Option          "Buttons"          "7"
        Option          "ZAxisMapping"     "4 5"
        Option          "ButtonMapping"    "1 2 3 6 7 4 5 6"
EndSection

Teraz wystarczy zapisać zmiany i zrestartować X-y. Powyższa konfiguracja powinna także działać dla wielu innych modeli myszek firm Logitech czy Microsoft. Trochę mi brakuje w Debianie i Ubuntu jakiegoś prostego sposobu na wybranie modelu myszki. Zresztą społeczność też się tego domaga. :)

Update: MX600 pod X.org 7.3 (Ubuntu 8.04)

W najnowszej wersji serwera X.org został nieco zmieniony sterownik myszki. Teraz aby myszka MX600 działała poprawnie wystarczy poniższy wpis:

Section "InputDevice"
        Identifier      "Configured Mouse"
        Driver          "mouse"
        Option          "CorePointer"
        Option          "Device"        "/dev/input/mice"
        Option          "Protocol"      "auto"
        Option          "Buttons"          "12"
EndSection

Jak widać wszystko właściwie dzieje się automatycznie. Tylko trzeba podać ilość przycisków (myszka MX600 ma logicznie 12 sztuk). Fajna sprawa, choć przy upgradzie z 7.10 -> 8.04 (prawie beta) znowu przyciski przestały działać i należało poprawić znowy xorg.conf

Pliki graficzne w C/C++ - biblioteka FreeImage

freeimage-logo.jpgJakiś czas temu na forum linuxowo.pl pojawił się temat obsługi plików graficznych z programów w C. Ponieważ temat ten jest mi bliski postanowiłem napisać krótki tutorial jak tego dokonać posiłkując się darmową biblioteką FreeImage. Biblioteka FreeImage integruje w sobie dobrodziejstwa wielu innych bibliotek obsługujących pliki graficzne (libjpeg, libpng, …) w postaci prostego, zwięzłego i jednolitego API. Ponieważ opiera się na dobrze sprawdzonych komponentach jest niezawodna i szybka. Dla mnie odkrycie jej było lekarstwem na koszmar obsługi plików graficznych w C/C++. Zapraszam do przeczytania i komentarzy. Chętnie napiszę coś więcej na jej temat, jeśli będzie taka potrzeba.
Do tutoriala użyłem mojego Debiana Lennego, ale z powodzeniem powinno to wszystko działać także pod Ubuntu czy ogólnie dowolnym Linuksem. Pod systemem Windows także można użyć biblioteki FreeImage, lecz trzeba mieć kompilator (np. z Visual Studio C++ Express), ręcznie poustawiać kilka rzeczy i oczywiście sciągnąć bibliotekę.

Przygotowanie środowiska

Tutaj sprawa jest niezwykle prosta i sprowadza się do zainstalowania odpowiednich pakietów. Będziemy potrzebować dwóch z nich. Pierwszy to build-essential, który zawiera wszystkie potrzebne nagłówki standardowych bibliotek. Drugi to pakiet samej biblioteki o nazwie libfreeimage-dev. Instalka sprowadza się zatem do:

sudo apt-get install build-essential libfreeimage-dev

Dodam jeszcze, że w Ubuntu pakiet biblioteki FreeImage znajduje się w repozytorium Universe. Należy zatem zadbać o to, aby ów repozytorium było dodane do /etc/apt/sources.list.

Szybki przykład - konwersja formatów

convert-gif-jpg.jpg

Dla zobrazowania podstaw użycia biblioteki FreeImage rozpatrzymy prosty przykład: konwersję pliku GIF na JPEG. Weźmiemy na warsztat bardzo popularny obraz lenna.gif, który spróbujemy przekonwertować właśnie na JPEGa.

Proponuję zacząć po prostu od kodu:

// freeimage-test.c - przykładowy program używający FreeImage
#include 
#include 
#include 

int main(void)
{
	int return_value = EXIT_SUCCESS;
	FreeImage_Initialise(TRUE);
	puts("Loading...");
	FIBITMAP* bitmap = FreeImage_Load(FIF_GIF, "lenna.gif", 0);
	if (NULL != bitmap)
	{
		puts("Saving...");
		FreeImage_Save(FIF_JPEG, bitmap, "lenna.jpg", 0);
		FreeImage_Unload(bitmap);
	}
	else
	{
		puts("Image couldn't be loaded");
		return_value = EXIT_FAILURE;
	}

	FreeImage_DeInitialise();
	puts("Exit");

	return return_value;
}

No to jedziemy po koleji - co powyższy kod robi:

  • używa odpowiednich nagłówków; w przypadku biblioteki FreeImage załączamy plik nagłówkowy FreeImage.h poprzedzony dwoma standardowymi nagłówkami biblioteki standardowej języka C
  • inicjalizuje bibliotekę FreeImage; do tego celu służy wywołanie metody FreeImage_Initialise(TRUE); bez tego użycie funkcji biblioteki jest niemożliwe
  • wczytuje plik graficzny w formacie GIF; sprawa jest dość prosta, gdyż wystarczy użyć funkcji FreeImage_Load; jako parametry podajemy kolejno: typ pliku, jego nazwę oraz zero; jeśli operacja skończy się sukcesem funkcja ta zwróci wskaźnik do struktury FIBITMAP, która to zawiera wszelkie informacje o wczytanym obrazku; jeśli się to nie powiedzie to dostaniemy NULL
  • zapisuje plik graficzny w formacie JPEG; sprawa jest analogiczna do wczytywania; używamy w zamian funkcji FreeImage_Save; tutaj znowu podajemy parametry, czyli: format pliku, wskaźnik do struktury FIBITMAP, nazwę pliku wyjściowego i znowu zero
  • zwalnia miejsce zajmowane przez obrazek; właśnie po to jest wywołanie FreeImage_Unload; jeśli byśmy tego nie uczynili obrazek ciągle by okupował pamięć, co jest już niepotrzebne, bo nie będziemy go więcej używać
  • deinicjalizuje bibliotekę; gdy już nie potrzebujemy korzystać z usług biblioteki FreeImage należy ją o tym poinformować funkcją FreeImage_DeInitialise, aby mogła zwolnić pamięć przez siebie zajmowaną

Po więcej informacji zapraszam do oficjalnej dokumentacji FreeImage (znajduje się tam plik PDF).

Kompilacja

Na sam koniec tego mikro-tutoriala instrukcja jak to wszystko skompilować. Użyjemy kompulatora GCC, który jest standardowo dostępny w każdym Linuksie. Skompilować program można np. tak:

gcc freeimage-test.c -lfreeimage -o freeimage-test

Zostanie utworzony plik binarny freeimage-test, a kompilator do linkowania użyje, prócz standardowych bibliotek, także bibliotekę FreeImage (przełącznik -lfreeimage). Po tej całej operacji program jest gotowy do użycia. Wystarczy umieścić plik lenna.gif w katalogu z binarką i uruchomić program. Po tej czynności powinniśmy znaleźć nowy plik lenna.jpg.

Proste? Proste!
Powodzenia w bojach z FreeImage! :D
UPDATE: FreeImage posiada także wrapper dla C++, który nieco ułatwia zabawę. Więcej informacji w dokumentacji FreeImagePlus (rzeczony wrapper).

Roczek minął

Dnia 9 marca roku 2007 został przeze mnie napisany pierwszy wpis na blogu. Dzisiaj zatem powinienem świętować pierwszą rocznicę, ale prawdę mówiąc nie wydaje mi się to stosowne. Powodem ów niestosowności jest fakt, że blog był przez długi czas przeze mnie zaniedbywany. Odżył właściwie dopiero w tym roku, kiedy to obiecałem sobie go nieco sumienniej prowadzić. Zatem formalnie blog ma dokładnie 1 rok, ale tak w sumie to nie ma czego świętować.

Przy okazji tej niby rocznicy mogę jednak obiecać, że będę dalej pisał o Linuksie, nieco o programowaniu, grafice komputerowej i pewnie kilku innych rzeczach. Spodobała mi się ta zabawa, a i może przy okazji ktoś z tego skorzysta. Doszedłem do wniosku, że dobrze mieć takie swoje miejsce, gdzie można przekazać innym swoje rady, doświadczenia. spostrzeżenia czy przemyślenia. Niby ilość stałych czytelników zapewne zamyka się w liczbie ledwo dwucyfrowej, ale mimo wszystko sprawia mi to dużą satysfakcję.

Pozdrawiam wszystkich czytaczy. A na kolejne blogowe podsumowanie zapraszam 9 marca 2009. :)