PyconPL 2009

No, byłem. Co do konferencji jako takiej to wolę się nie wypowiadać, ale wnioskuję, że nie byłem jej targetem — był może jeden wykład, na którym dowiedziałem się czegoś nowego i jeden, który obejrzałem dla przyjemności. Aspekt społeczny w pewnym stopniu został zaspokojony przez bratanie się z kolegami z Allegro.pl. Infrastrukturę (dostęp do sieci, wyżywienie, zakwaterowanie, napoje, przekąski) pominę milczeniem. W końcu też w niedzielę dałem spicz i odniosłem wrażenie, że pomimo pewnych problemów technicznych się podobał. Czyli: pod względem merytorycznym niejaki sukces.

Dla uzupełnienia:

  • prezentacja do obejrzenia/ściągnięcia jest na SlideShare
  • kod w takiej wersji, jaka była prezentowana, jest na BitBucket

Jeżeli czas pozwoli, to skrobnę też jakiś artykuł na podstawie tego, co zostało powiedziane.

Autentykacja, podejście drugie

Ponownie brudzę sobie ręce w aplikacji zrobionej przy użyciu alternative stack (Werkzeug + Jinja2 + SQLAlchemy + WTForms), trochę przy okazji przygotowań do mojego nadchodzącego wystąpienia na PyconPL 2009. I ponownie wszystko szło gładko, dopóki nie musiałem zabrać do autentykacji uwierzytelniana (nie autoryzacji).

Krąży po mieście plotka, że najlepiej do tego użyć AuthKit lub repoze.who. Jak w każdej plotce, w tej także może być ziarno prawdy, więc kilka dni temu postanowiłem to sprawdzić. Już początki nie były zachęcające (każda z tych bibliotek doinstalowuje w zależnościach połowę Pylons), a potem było jeszcze gorzej.

AuthKit okazał się tak mocno związany z Pylons, że nawet nie ma własnej dokumentacji, tylko jakieś rozdziały w Pylons Book. Jedyne, co nadawało się do użycia bez Pylons, to kilka przykładów w repozytorium. Spróbowałem pokonać niechęć i zapoznać się bliżej z tą biblioteką, ale dałem za wygraną po godzinie zastanawiania się, jak do tego bydlaka podejść. Może jakoś niedługo przyjdzie mi do głowy idea, jak mógłbym z tego skorzystać bez Pylons (a może ktoś to opisze...).

Dokumentacja do repoze.who okazała się dużo lepsza, ale tym razem przerosła mnie idea tej biblioteki. Przeczytałem wprowadzenie i zagotowało mi się pod kopułą — jak to w ogóle działa? I najważniejsze, jak to podłączyć do istniejącego kodu? Jestem pewien, że dokumentacja dokładnie opisuje każdy aspekt działania tej biblioteki, ale ja tego zwyczajnie nie zrozumiałem. Może dlatego, że przez cały czas przed oczami miałem mój use case, który obejmuje jedynie mały fragmencik tego, do czego ta biblioteka została stworzona.

Na dzień 10 lipca 2009 roku konkluzja jest taka, że albo przysiądę fałdów i spróbuję użyć jednej z tych dwóch bibliotek, albo pójdę na skróty i użyję RPX (czy czegoś w tym stylu). Co biorąc pod uwagę obecny trend w branży nie wydaje się być takim głupim rozwiązaniem. Niestety, pomijając całkowite niedopasowanie tego rozwiązania do docelowej grupy użytkowników mojej aplikacji...

Zapraszam na PyconPL 2009

Jeżeli ktoś jeszcze się zastanawia, czy wybrać się na PyconPL do Ustronia w październiku, to może przekonam go tym, że będę tam trzymał spicz na temat przygód Adama Słodowego w krainie ramówek webowych — rozłożę na czynniki pierwsze jakąś ramówkę (pewnie będzie to najbliższe mi Django) i spróbuję złożyć coś podobnego używając zamienników.

Dawno nie dawałem żadnego występu publicznego (od ostatniego WarPY w październiku minie 2 lata...), więc trzeba przygotować lepszy show. :)

Setuptools to szajs

Wiele było już głosów, że setuptools jest pełne błędów i nie powinno być używane. W mojej praktyce na te błędy nie trafiałem, więc poprzestawałem na niechęci, a drobne wpadki powodowały jedynie wzrost przychylności wobec antagonistów setuptools. Tym razem w ciągu ostatnich dni zostałem doświadczony dwukrotnie przez poważne niedoróbki w setuptools, w tym jedna ma znaczenie krytyczne (nie instaluje się część zawartości pakietu):

Setuptools musi odejść!

Oko na RSS

Nie nie chodzi o żadne feedy, tylko o tzw. resident set aplikacji w Django. Obserwuję tę wartość od dłuższego czasu dla tej małej aplikacyjki i z pewnym niepokojem obserwuję jak rośnie, od ~15MB pod koniec 2007 roku przez ~17MB w okolicach wydania 1.0 do ~19MB z wersją 1.1-beta1 (przy wręcz zmniejszającym się feature secie aplikacji). A mój niepokój bierze się z mojej zadziwiająco dobrej pamięci, jak na mój podeszły wiek.

Kiedyś, w zamierzchłych czasach (okolice Slackware 9.0, czyli początek 2003 roku), była sobie fajna, mała przeglądarka WWW, która nazywała się Phoenix. Wyrosła z potrzeby istnienia po prostu przeglądarki i w swoich bebechach była Mozillą (tak się kiedyś nazywała przeglądarka wyrosła z Netscape Communicatora) bez wszystkiego tego, co nie służyło przeglądaniu stron WWW. Była szybka, miała małe wymagania i wszyscy ją pokochali od razu. Pokochali ją tak bardzo, że Mozilla Foundation postanowiła skupić na niej swoje wysiłki developerskie. W szybkim tempie (od wersji 0.4 Oceano z listopada 2002 do wersji 0.8 Royal Oak z lutego 2004) program zbliżył się apetytem na zasoby do swojego rodzica i przestał być postrzegany jako lekki i szybki. Po 7 latach istnienia Mozilla Firefox wciąż bohatersko zwalcza bloat, który był głównym powodem jego wypączkowania z projektu Mozilla Suite.

Na ile ostatnie develpmenta w Django przypominają to, co stało się z Phoeniksem? Na tyle, że nagle wszyscy pokochali Django i zaczęło ono obrastać w rzeczy, które już nie mieszczą się w legendarnych 80% (i django.contrib.gis to naprawdę mały pikuś w tym zestawie). Wygląda na to, że zadowalanie coraz większej rzeszy użytkowników daje w wyniku coraz większe zapotrzebowanie na zasoby...

Rekapitulując, ja też uważam, że martwię się na zapas. Sytuacja sama w sobie nie wygląda jeszcze na niepokojącą, niepokojący jedynie może być ten trend. Czy doprowadzi do tego, że Django przejdzie na ciemną stronę mocy, to się dopiero okaże.

Igranie z przyszłością

Zmiany się szykują... Wspominałem o planach przepisania silnika tego bloga przy użyciu narzędziówki, ale im dłużej nad tym siedzę, tym bardziej jestem przekonany, że nie ma to wielkiego sensu — zbyt wiele rzeczy wymagałoby ręcznej ingerencji, patchowania komponentów i rwania włosów z głowy, bo coś nie działa, jak na przykład odkrycie z wczoraj:

  • nie działa Beaker z powodu błędu w kodzie backendów sesyjnych wykorzystujących bazę danych i memcached (pliki działają OK, ale ich nie chcę);
  • w związku z tym, że nie działa Beaker, nie działa też AuthKit, więc nici z ułatwień autentykacji (np. po OpenID).

Oczywiście, byłbym w stanie naprawić Beaker'a, powstaje jedynie pytanie, czy to się w ogóle opłaca? Alternatywą jest przejrzenie i odchudzenie istniejącej aplikacji w Django, a przy okazji zoptymalizowanie jej nieco, wykorzystując doświadczenie, jakiego nabrałem w ciągu tych kilkunastu miesięcy. To też mogłoby być nienajgorsze rozwiązanie, a na pewno szybsze. Będę żałował Jinja2, ale jak mnie żal przyciśnie, to podłączę sobie ten silnik do Django, żeby stonować trochę ten żal...

Poważnie się zastanawiam i jeszcze nie podjąłem żadnej decyzji — na razie kod wykorzystujący narzędziówkę poszedł do oddzielnego brancha w repozytorium, a w trunku pojawił się kod wersji działającej obecnie, ale nie ma to jakiegoś symbolicznego znaczenia (tak sobie to tłumaczę). Uch, jak ja lubię mieć takie dylematy... :)

Nowe zabawki

W końcu się przemogłem i postanowiłem w celach edukacyjnych przemóc się i spróbować zrobić jakąś aplikację na Google AppEngine. Ponieważ chciałem mieć coś więcej, niż tylko naukę odpalania aplikacji pod Django na nowym środowisku, wybrałem sobie narzędziówkę z kosmosu: Werkzeug, Jinja2 i WTForms. I jak do tej pory psioczyłem na AppEngine, to teraz spodobało mi się to środowisko. Co prawda pod względem dołączonych baterii moja nowa narzędziówka jest bardzo uboga w porównaniu do wszystkiego tego, co przychodzi z Django, to jednak dzięki temu zorientowałem się, jak dużo rzeczy z Django tak naprawdę jest mi zupełnie niepotrzebne. Okazało się też, jak prosto można zaimplementować te rzeczy, które są mi potrzebne lub ułatwiają życie.

Więcej na ten temat wkrótce.

What would Brian Boitano do?

Przesiadam się teraz dość regularnie z komputera z desktopem GNOME na Mac OS X 10.5 i mam kilka pomysłów, które mogłyby stać się killer-aplikacjami, gdyby tylko były. Innymi słowy, jest to lista tego, czego brakuje mi w GNOME lub w OS X (albo i w jednym i w drugim).

W GNOME najbardziej brakuje mi czegoś, co działa jak Spotlight w OS X. Celowo napisałem "co działa", bo podobne launchery i dodatki oczywiście istnieją, ale do działania Spotlighta im daleko (są wolne i żrą masę zasobów). Poproszę o coś takiego w najbliższym wydaniu.

I jest coś, czego nie ma ani GNOME, ani OS X — instalator tematów. Coś, co ma Firefox i Opera, ale sam desktop nie. Chciałbym móc otworzyć sobie okienko, przejrzeć listę tematów z gnome-look.org (albo z innego serwisu), nacisnąć guzik "install theme" i już.

Eureka!

Pomimo tego, że robię w Django od paru lat, wciąż zdarzają mi się odkrycia na miarę archimedejskiej eureki. Dziś właśnie zauważyłem, że skrót render_to_response może przyjmować jako pierwszy argument nie tylko nazwę szablonu, ale także listę nazw szablonów. Dzięki temu wiekopomnemu odkryciu kod, który wyglądał dość marnie:

templates = [
    'flagging/%s_flagging_form.html' % obj._meta.module_name,
    'flagging/flagging_form.html',
]
template = loader.select_template(templates)
return HttpResponse(template.render(ctx))

teraz może wyglądać trochę ładniej:

templates = [
    'flagging/%s_flagging_form.html' % obj._meta.module_name,
    'flagging/flagging_form.html',
]
return render_to_response(templates, ctx)

Świadomie używam określeń ładnie i brzydko, bo chodzi tu jedynie o estetykę (obydwa warianty robią dokładnie to samo pod spodem).

Na swoje usprawiedliwienie mogę powiedzieć tylko tyle, że takie zachowanie render_to_response jest obecnie nieudokumentowane (ale zgłosiłem odpowiedniego patcha).

Introducing django-confirmation

I'm pleased to announce my first (hopefully) reusable app for Django: django-confirmation. The idea for this app came from my personal need to handle confirming object's creation on one of my sites. I found few apps performing similar tasks, but both are targeting single classes of objects, while I needed more generic approach (I hate this word...) — there are several classes of objects that need to be confirmed separately but using the same mechanism.

The use case for this app is as follows:

  • non-registered/not-logged-in user creates an object;
  • application sends an email asking user to click (within configurable period of time) on provided link to make the object "active";
  • user clicks a link and makes the object "active" or
  • key expires after specified amount of time.

The implementation is based on what I found in other apps, specially django-registration and django-email-confirmation, but with added support for confirming generic Django model instances (as long as they can have different activity states, that is).

Code reuse that isn't

Django jest fantastyczne m.in. w tym, że istnieje masa podłączalnych aplikacji, które w sposób wystarczająco generyczny realizują często spotykane zadania, jak np. django-registration do rejestrowania użytkowników, czy django-tagging do etykietowania obiektów. Część z tych aplikacji jest naprawdę wysokiej jakości, w dodatku łatwo konfigurowalnych i możliwych do dopasowania w dość szerokim zakresie. Są jednak takie, które dobrze się zapowiadają od dłuższego czasu, jednak na tym się kończy. Co bardziej zaskakujące, wszystkie te potencjalnie użyteczne aplikacje pochodzą z projektu Pinax.

W jednym z projektów potrzebuję dodać funkcję powiadamiania użytkowników o wystąpieniu pewnych zdarzeń. Jest aplikacja django-notification, ale w stanie obecnym nie nadaje się do wykorzystania poza Pinaxem (lub w sposób jakkolwiek różny od tego, jak to jest robione w Pinaksie). Zgłoszoneproblemy z tym związane, jednak zostały odłożone na lepsze czasy. Będę musiał wziąć kod django-notification i wzorując się na nim napisać swoją własną aplikacyjkę, bo na te lepsze czasy się nie doczekam.

Inny przykład. Niedawno potrzebowałem dodać do pewnego projektu możliwość tworzenia obiektów przez niezalogowanych użytkowników — wymagane jest wtedy podanie adresu email i potwierdzenie dodania obiektu przez standardowe kliknięcie w przesłany link. Znalazłem aplikację django-email-confirmation, która robi coś podobnego, ale nie nadaje się do potwierdzania jakichkolwiek innych obiektów, niż jej własne (a ja potrzebowałem zastosować ten mechanizm do 3-4 różnych klas obiektów). Trzeba było napisać własną, na szczęście okazało się to dość proste, przyjmując django-email-confirmation za wzór.

I to samo mam za każdym razem, gdy trafiam na aplikację, która mogłaby mi się przydać, a pochodzi z Pinaxa — bez zakodowania własnego rozwiązania bazującego na tym kodzie się nie obejdzie. Rozumiem, że Pinax jest rozwijany w normalny dla OS/FS sposób, to znaczy w czasie wolnym i nikt nie bierze za to pieniędzy, ale skoro tak to wygląda, to jaki jest sens wydzielać aplikacje jako niby reużywalne, skoro tak naprawdę nie dają się użyć nigdzie poza aplikacjami typu Pinaxa i ich reużywalność to głęboki mit?

MySQLdb zje także i Twojego psa

Przynajmniej Pythoniarze powinni się trzymać z daleka od tej bazy, bo jej adapter jest obciążony kilkoma bardzo, ale to bardzo poważnymi błędami (abstrahując zupełnie od problemów, jakie ta baza ma sama ze sobą):

Moim zdaniem kicha. Pierwszy daje się obejść (kosztem nieprzenośnego kodu), ale drugi zupełnie mnie zabija, zwłaszcza, że płacę m.in. za zużycie pamięci...

Środa, więc będzie o środowisku

Czas przyszedł, żeby pochwalić się środowiskiem developerskim. Na linuksie było różowo, na Macu już tak różowo nie jest, ale wydaje mi się, że doszedłem wreszcie do stanu, że infrastruktura nie przeszkadza mi w programowaniu, a środowisko z czasem mi się zintegrowało. Więc jak wygląda to środowisko programisty aplikacji webowych?

TextMate

The missing editor. Vim jest bardzo dobry jako edytor. Jest tak dobry, że nie ma lepszych, ale to tylko edytor. TextMate to coś po środku między Vimem a Eclipse — to jeszcze nie środowisko zintegrowane, ale już dużo więcej niż edytor, głównie za sprawą bundles, czyli dodatkowych funkcji związanych z trybem edycyjnym. Na linuksie kiedyś podobnie bogate w funkcje było Kate, ale już nie jest, odkąd jakaś mądra głowa postanowiła wyrzucić z niego funkcję projektu. Do podobnego poziomu obecnie próbuje doszlusować PIDA, ale idzie to bardzo opornie (z tego co wiem, to z powodu braku siły roboczej — taka mała podpowiedź dla tych, co chcieliby się wykazać w jakimś projekcie). Dla łyżki dziegciu — PIDA ma hook do wykonywania automatycznych akcji przy zapisie bufora, za to TextMate ma okno wyboru pliku do otwarcia z inteligentnym podpowiadaniem (pod Cmd+T).

Od For fun and profit
Od For fun and profit

Virtualenv

Nie zna życia, kto nie służył w marynarce, a nie zasmakował programowania w Pythonie ktoś, kto nie potrzebował kiedyś mieć zainstalowanych dwóch różnych wersji tej samej biblioteki. Lub wręcz z podwórka Django: 0.96.x, 1.0.x i trunk równolegle. Zamiast robić dziwne myki z PYTHONPATH, tworzy się izolowane środowisko z oddzielnym interpreterem i oddzielną biblioteką. Żyć, nie umierać i tworzyć izolowane środowiska. Wygoda polega przede wszystkim na tym, że utworzenie takiego środowiska jest szybkie i nie wymaga szczególnych zabiegów.

Firebug

Tylko dla niego trzymam Firefoksa na Macu. Debugger JavaScriptu jest wielki. Można go określić jako missing plugin for Safari.

SQLite/PySQLite

Nie ma aplikacji webowych bez baz danych, a dzięki ORM można nie babrać się z ustawianiem MySQL czy innego PostgreSQL tylko po to, żeby sobie podevelopować. Dopóki aplikacja porusza się w obrębie tego, na co pozwala ORM, to nie ma powodu, żeby używać innej bazy danych, bo po prostu od strony storage nie widać różnic. Niezwykle bardzo cenię sobie to, że start z aplikacją jest tak prosty i później naprawdę nie ma dla mnie różnicy, na jakiej bazie stoi moja aplikacja (tak długo, jak długo mogę zrobić django-admin.py dumpdata --format=xml). SQLite to fajna, bezobsługowa baza danych, która ma wszystko to, co jest potrzebne w momencie developmentu.

Rzeczy, których jeszcze nie używam, ale pewnie będę używał w niedalekiej przyszłości

Pozostałe rzeczy mają znaczenie drugorzędne (albo nawet trzeciorzędne), bo są albo specyficzne dla moich upodobań (subversion, MacPorts), albo specyficzne dla moich upodobań (Django), albo dla odmiany specyficzne dla moich upodobań (jQuery). Jestem w stanie robić programy w każdym środowisku, ale z moich ostatnich doświadczeń wynika, że jedyny warunek jest taki, żeby to było środowisko przynajmniej trochę uniksawe. :)

Cron nie odpala zadań z crontaba? Mamy cię!

Jeżeli po aktualizacji Ubuntu do 8.04 (lub po przeniesieniu systemu np. z FreeBSD na 8.04) Twój crond przestał zauważać zadania wpisane w crontabie (po prostu jakby ich tam nie było...), to sprawdź, jak wygląda Twoja tabela zadań i czy ma to coś:

$ crontab -l | grep MAILTO
MAILTO=""

Bez tego nie pojedziesz.

Na wykrycie tego straciłem kilka godzin, więc pomyślałem sobie, że zapiszę tutaj, gdyby kogoś zgnębił podobny problem.

Framework to nie hop-siup...

Przyglądając się WebOb i dołączonym do niego przykładom można wreszcie zobaczyć, jak dużą rzeczą są ramówki webowe. O ile WebOb dostarcza podstawy do zbudowania własnej ramówki, to porównanie tej podstawy z gotowym frameworkiem, np. Django, uświadamia, jak wiele rzeczy trzeba napisać, żeby wszystko razem zagrało. Oczywiście, zazwyczaj używa się tylko pewnej części ramówki i wydaje się, że napisanie własnej spowoduje, że będzie szybsza, lżejsza i w ogóle lepsza, bo przecież pozbawiona kodu (a więc i funkcji), którego się i tak nie używa. Ale to, co pozostaje, to i tak ogromna ilość kodu i ogromna ilość funkcji, które trzeba zaimplementować. I to zaimplementować poprawnie, przewidując sytuacje niezwykłe (dziwnego klienta, któremu się coś pieprzy z HTTP i czegoś-tam zapomina wysłać albo nie rozumie) i awaryjne.

Ja w każdym razie dziękuję, zostanę przy cudzej robocie. :)

Jestem mały, głupi i nazywam się port

Chodzi mi o program port, ten od MacPorts. Jego działanie jest dla mnie źródłem załamywania rąk nad głupotą. A właściwie lepiej byłoby to nazwać badziewnością sączącą się z samego źródła.

Wyoraźmy sobie sytuację (nie całkiem hipotetyczną): w nowej wersji biblioteki libsqlite3 poprawiony zostaje bardzo denerwujący błąd, który miał wpływ na działanie wielu programów. Błąd był bardzo denerwujący i chciałbym się go pozbyć także z moich aplikacji w Pythonie, które działają z PySQLite. Wpisuję więc w terminalu sudo port -R upgrade sqlite3 i...

Ile razy zostanie przebudowane subversion? Ile razy zostanie przebudowany Vim? Ile razy zostanie przebudowane gnutls?

Przykro mi, ale na 2 pierwsze pytania nie umiem udzielić odpowiedzi. Liczenie ile razy budowało się subversion zakończyłem po 15 razie, ale ile razy budował się Vim po 25 razie. Łącznie ponad 40 razy zostały zbudowane 2 programy, które ze sqlite3 nie mają nic wspólnego.

Gnutls budowało się dokładnie raz. O jeden raz za dużo. Bo jedynym pakietem, który od sqlite3 zależy w moich portach jest py25-sqlite3.

Przybywa

Przybywa dokumentacji w moich django-tutors — skończyłem (a przynajmniej tak mi się wydaje) odcinki o uploadowaniu plików do ścieżek określanych statycznie i dynamicznie, właśnie kończę odcinek o upload handlers. Na napisanie czeka jeszcze odcinek o storage backends, a potem... A potem to się zobaczy.

Padła propozycja, żeby napisać coś o uploadowaniu wielu plików na raz przy użyciu jakiegoś flashowego uploadera, ale nie wiem, czy taki dość specyficzny temat mi odpowiada. A może ktoś zechciałby napisać taki artykuł? Projekt django-tutors jest otwarty, kto chce może dostarczyć co chce, to niekoniecznie musi być komplet (dokument + przykładowy kod), jeżeli czegoś będzie brakowało, to w razie potrzeby się dopisze. Wymaganie właściwie jest tylko jedno, to musi działać z fabrycznym Django 1.0 (czyli bez przeróbek w kodzie ramówki).

Jeżeli ktoś chce dołożyć swoje 3 grosze do projektu, to proszę się zgłosić mailem na moje konto na gmailu (jarek.zgoda i tak dalej), albo odezwać się na jabberze, też na moje konto na gmailu.

django-tutors

Moje niedawne przejścia z uploadem plików popchnęły mnie do tego, żeby spisać moje doświadczenia w postaci samouczków. Na początek poszedł właśnie upload plików, jak do tej pory napisałem o uploadzie do statycznej ścieżki.

django-tutors

Wszelka pomoc mile widziana — fragmenty szkoleniowego kodu, samouczki, itp. Jeżeli ktoś chciałby zredagować jakiś artykuł, to oczywiście zapraszam. Język: polski. Na razie wyłącznie.

Musi poczekać

Od kilku tygodni mamy w Django nową ramówkę do komentarzy. Kod jest pokłosiem projektu Google Summer of Code™ i trafił do repozytorium Django właściwie bez poważnego przejrzenia, w wielkim pośpiechu, już po wydaniu którejś bety. Resultatem jest fura błędów i niedoróbek, które znalazły się w finalnym wydaniu Django. Nie chodzi bynajmniej o to, że ktoś to marnie napisał — dla każdego projektu programistycznego normalne jest to, że pierwsza wersja służy temu, by poprawić podstawowe błędy i doszlifować ją w trakcie używania. Nowa ramówka nie miała szansy sprawdzić się w boju, pod czujnym okiem dziesiątek czy setek użytkowników.

Próbowałem doprowadzić do tego, by zmiana ramówki komentarzy była niedostrzegalna dla moich czytelników. Niestety, okazało się, że w obecnym stanie ramówki jest to po prostu niemożliwe bez napisania... własnej ramówki. Nie wszystko daje się owrapować i nie wszystko można podmienić, nawet przy bardzo dynamicznej naturze Pythona. Dlatego wspomniane prace konserwatorskie zostają odłożone na bliżej nieokreśloną przyszłość, gdy ramówka otrzyma wreszcie wymaganą konfigurowalność. W sumie, patrząc na to z innej strony, skoro działa, to po co poprawiać? ;)

Przerwa technologiczna

W ciągu najbliższych kilku dni będę musiał wyłączyć komentarze na godzinę czy dwie, żeby przeprowadzić aktualizację do nowszego Django (z nową ramówką do komentarzy). Ale jeszcze chwilę poczekam, może poprawią zgłoszone przeze mnie błędy. ;)

Jest Django-1.0

Wydane

jarek:~/install/django$ svn log | grep zgoda | wc -l
         17
   

Niewiele, ale duma mnie rozpiera — dokonaliśmy tego!

Będzie, czy nie będzie?

Dziś ma zostać wydane Django 1.0.

Będzie?

Nie będzie?

Urządzenia MTP na nie-Windows

Co to jest MTP to wie każdy, kto ma w miarę nowy odtwarzacz. Wszystkie (albo prawie wszystkie) nowe Samsungi, iRivery i Creative (żeby wymienić tylko kilka) komunikują się z komputerem przy użyciu tego protokołu. Do niedawna jedynym programem, który dobrze go obsługiwał, by Windows Media Player 10. Oczywiście, tylko na Windows. I do niedawna było to wielkim problemem, bo już nie jest. Teraz jest tylko pewnym problemem, bo do urządzeń MTP można się podłączać także z innych systemów.

Musiałem to spraktykować, bo mój nowy Samsung YP-T10 to właśnie urządzenie MTP. Podobno wgrywając koreański firmware można go przestawić w tryb UMS, ale wolałem najpierw sprawdzić metody mniej inwazyjne.

Na Macu:

  • jedyny program to XNJB, ma koszmarne GUI, ale zasadniczo działa, nie radzi sobie z niektórymi tagami ID3 i czasem nie potrafi wysłać pliku — w takiej sytuacji pomaga mu odłączenie odtwarzacza i ponowne podłączenie.

Na linuksie możliwości jest sporo więcej:

  • Amarok i Rhythmbox bez problemów gadają z urządzeniami MTP, jedyna niedogodność w przypadku tego drugiego, to możliwość wrzucania jedynie muzyki (nie wiem, jak jest z Amarokiem);
  • gnomad2 to program podobny do XNJB (właściwie to XNJB jest wzorowany na gnomad2 i wykorzystuje te same biblioteki), ale wersja, którą mam na Ubuntu 8.04, nie daje dostępu do struktury katalogów na odtwarzaczu, co uniemożliwia np. wgranie aktualizacji firmware;
  • mtpfs to obsługa systemu plików na urządzeniach MTP dla FUSE; montuje się urządzenie w dowolnym katalogu i jest dostęp do struktury systemu plików urządzenia, jedyny mankament: nie zawsze chce się odmontować, twierdząc, że device is busy; spodziewałem się jakiejś współpracy mtpfs z Nautilusem, ale niczego takiego nie stwierdziłem, w sumie dobre i to, co jest.

Jak widać, linuksiarze mają znacząco lepiej, szczególnie z powodu mtpfs/FUSE. A z innej strony: jest dla mnie całkowicie niezrozumiałe, czemu iTunes nie współpracuje z urządzeniami MTP. Szczerze mówiąc otarłem się o szok.

Nowe comments w Django

Dziś w Django pojawiła się zrefaktoryzowana ramówka do komentarzy. Tym razem przed aktualizacją powstrzymuje mnie comment-utils, które chroni ten piękny kawałek internetu przed spamem. Parę dni i będzie, a jak nie, to popracuję nad tym osobiście. :)

Wsparcie dla iRiver H10Jr. na Macu

Oficjalnie nie ma. Nieoficjalnie jest, w postaci biblioteki pmplib, ale skompilowanie jej pod OSX to straszliwy ból tyłka. Jak się to robi:

  1. zainstaluj z portów pakiety libid3tag, libogg i libvorbis;
  2. ściągnij źródła ze strony pmplib i rozpakuj je gdzieś, od tej pory $ROOT będzie oznaczać wypakowany katalog ze źródłami pmplib;
  3. w pliku $ROOT/lib/pmp_iriverplus3/util.c zmień wpis #include <malloc.h> na #include <sys/malloc.h> (na początku pliku);
  4. skonfiguruj używając polecenia: ./configure --disable-js --with-libiconv-prefix=/opt/local --with-id3tag-header=/opt/local/include --with-id3tag-library=/opt/local/lib --with-ogg-prefix=/opt/local --with-vorbis-prefix=/opt/local;
  5. zbuduj i zainstaluj: make && sudo make install;
  6. sprawdź czy easypmp działa.

Mnie działa, choć nie bez problemów. Pomimo odmontowania H10 przez cały czas pokazuje, że jest busy, żeby go odzyskać trzeba kilkakrotnie wyciągać z niego wtyczkę i ją wkładać (co czasem powoduje ponowne zamontowanie).

Na szczęście mój śliczny nowy Samsung YP-T10 przyjedzie do mnie już za kilka dni.

Mac i Python, Python i Mac

Jak wiedzą wszyscy (albo wszyscy w mieście), Apple dostarcza jakiegoś Pythona ze swoim OSX. Mogłoby to wskazywać, że Python jest first class citizen, jeżeli chodzi o języki programowania na OSX, podobnie jak jest to w przypadku Ubuntu. A figę (chcialem napisać bardziej dosadnie, ale podobno nieletni czytają)!

Robienie aplikacji na Maka w Pythonie to droga przez mękę. Serio. PyObjC obecnie oficjalnie jest w wersji, która ledwo wspiera poprzednią wersję OSX (10.4), zresztą pisanie w tym czymś przypomina programowanie aplikacji na Win32 używając PyWin i MFC. A chyba nawet gorzej. Z normalnych ramówek GUI są oczywiście wszystkie, ale w takim przypadku bez Py2App nie ma co się do tego zabierać. Normalnie jak na Windows.

Która to konkluzja doprowadza mnie do szerzej ujmującej makowo-osxową rzeczywistość konstatacji — ogólnie Mac jest jak Windows, tylko trochę bardziej. Odczuwam taki sam brak wolności (w sensie free speech) i podobne podejście ludzi, którzy robią oprogramowanie na Maki — byle tylko zarobić i nic nie pokazać. Na linuksie może nie ma aż tak wyczesanych efektów wizualnych, może też nie wszystkie ficzery tak ładnie działają (zamknij klapę laptoka, a się uśpi, podnieś, a się obudzi — i WiFi przeżyje), ale pod względem aplikacji skierowanych na produktywność po prostu nie ma porównania. Instalujesz Ubuntu i masz dosłownie wszystko, czego potrzebujesz, a to, czego jeszcze nie masz, jest na odpalenie apt-get install.

Co doprowadza mnie do kolejnej konkluzji, że moim kolejnym prywatnym komputerem nie będzie Mac, tylko jakiś fajny normalny laptop z matrycą 13'4. Jak na przykład twoja Toshiba, Smoku...

Prawie, prawie

Django jest coraz bliżej mitycznego "1.0" — właśnie wyszło 1.0-alpha-2, w którym dostaliśmy zrefaktorowane pola FileField i pochodne (czyli również ImageField), przebudowę przeszedł także podsystem sygnałów.

To tak gwoli kronikarskiej ścisłości, bo to są rzeczy, które albo wymagały ode mnie przepisania kawałka kodu, albo długo na nie czekałem.

Sława, sława!

http://oebfare.com/blog/2008/jun/24/django-code_swarm/

Około drugiej minuty, w prawym górnym rogu...

Sztuczny tłok

Dużo się ostatnio dzieje w Django — co chwilę ktoś commituje zmiany do repozytorium i można odnieść wrażenie, że opublikowanie daty wydania wersji 1.0 obudziło w developerach nowy zapał i chęć do posprintowania na zakończenie wyścigu.

To mylne wrażenie. Przytłaczająca większość pojawiających się w repozytorium zmian to są poprawki w dokumentacji, w docstringach oraz style fixes. A kod poprawiający rzeczywiste problemy czeka sobie na lepsze czasy.

Ten wpis był tytułem ochłodzenia emocji, gdyby ktoś widząc tempo commitów wnioskował z tego, jak dużo i szybko kod w Django jest poprawiany... ;)

Zdrada? To się dopiero okaże...

No i będę miał w pracy MacBooka. Niby zwykłego, ale tak nie do końca, bo czarnego. Nigdy nie miałem Maca, nigdy też go nie używałem, więc zacząłem od czytania, co też mnie czeka po przesiadce z linuksa. Nie zapowiada się różowo, głównie z powodu problemów z bibliotekami. Ale może jakoś to przeżyję...

Przegrywam z maszyną

Od kilku tygodni (a dokładnie odkąd mam Ubuntu 8.04) zastanawia mnie zużycie prądu na poziomie 14W/h. Niby niewiele, ale zmniejsza mi to znacząco czas używania laptopa na baterii. Naczytałem się, że tu i ówdzie świeżo zainstalowany 8.04 zużywa 10.5-11W/h, a to przecież sporo mniej. Próbowałem dojść przyczyny, ale nie znalazłem niczego konkretnego.

Wciąż najważniejszym źródłem przebudzeń procesora jest przełączanie zadań między rdzeniami. Nie pomogła na to ani aktualizacja biosu, ani wyładowywanie kolejnych modułów (po co mi parport, skoro nie używam drukarek, ani nie mam portu równoległego?), zużycie prądu uparcie nie chce zejść poniżej 13.5W/h. gnome-power-manager też nie był tym głównym winowajcą, bo po przełączeniu się na KDE 3.5 minimalny poziom zużycia prądu nawet wzrósł do 14.5W/h — cały zysk z wyłączenia tego potwora został przejedzony gdzie indziej.

Ostatecznością (po którą nie chciałbym jednakowoż sięgać) jest próba z nowszym kernelem. A że jestem wyjątkowo leniwy i nie chcę się babrać z budowaniem kernela debiany-way, oznacza to próbne zainstalowanie Fedory Core 9... O, jak mi się nie chce tego robić.

Halo, czy ktoś mi naprawi komputer? ;)

Cierpię

Po raz kolejny cierpię, jak za każdym razem, gdy muszę zmontować jakiś layout dla serwisu. W tej dziedzinie mam dwie lewe ręce i zezowate oko, więc staram się (przynajmniej na początku) znaleźć coś gotowego. I ciągle mam ten sam problem — szablony które udaje mi się znaleźć mają w większości ustaloną szerokość circa about 800px, czasem pomijalnie większą. To jest rzecz, która dyga mnie za każdym razem, jak potrzebuję wygrzebać jakiś gotowy szablon: przytłaczająca większość szablonów jest robiona na fixed width, przez co masa przestrzeni się marnuje. Nie wspominając o tym, że wszystkie wyglądają jak odbite z jednej matrycy z niewielkimi zmianami.

Nie chce mi się już robić we webie.

Patch applied

W pracy używamy kilku różnych bibliotek third-party. W ogniu walki często okazuje się, że mają one jakieś mankamenty, albo brakujące funkcjonalności, od których zależy działanie naszej aplikacji. Czasem kończy się to zgłoszeniem błędu, ale częściej razem ze zgłoszeniem dostarczamy poprawkę. Czuję się szczególnie doceniony, gdy moja poprawka trafia do upstream — mam wtedy megalomańskie uczucie, że dzięki mnie świat staje się lepszy. Chociaż w niewielkim zakresie... ;)

jQuery mi się podoba

Po raz kolejny zastrzegam: to nie jest miłość (bo miłość może być tylko jedna). Ale jQuery mi się podoba.

Dzisiaj miałem zrobić taki pokręcony formularz z trzema select-ami, gdzie środkowy przyjmuje elementy z dwóch naokoło niego na kliknięcie. Biorąc pod uwagę moją niechęć (i co tu dużo ukrywać, nieznajomość też) do JavaScriptu, planowałem sobie to na co najmniej dzień roboty, a najprawdopodobniej półtora. Tymczasem usiadłem do roboty około 10, a o 12 miałem już to zrobione. 35 linijek kodu i żadnego znużenia. Więcej takich ułatwiaczy poproszę.

JavaScript może czuć się przeproszony

Nigdy nie lubiłem JavaScriptu. Syntaktycznie mi się ten język nie podobał, jego idea wydawała mi się poroniona (co najmniej), a różnice w implementacjach przez różne platformy zwyczajnie dyskredytujące. Tym niemniej zapoznałem się z nim przynajmniej na tyle, żeby znać go z widzenia. Ogólnie konieczność pisania kodu w JavaScripcie napawała mnie obrzydzeniem.

Do niedawna. Bo niedawno wypatrzyłem jQuery i całe moje podejście do JavaScriptu zmienniło się diametralnie. Miłością nie zapałałem (bo miłość może być tylko jedna), ale polubiłem JavaScript. Dziękujemy Ci, jQuery!

PIDA mnie rozczarowuje

Większość mojego kodu w Pythonie (a właściwie kodu w ogóle, włączając w to HTML i skrypty SQL) piszę w PIDA. Jak dla mnie to środowisko pozostawia mi ultrawygodnego Vima, dodając to, czego potrzebuję podczas pracy: zarządzanie grupą plików jako projektem, kilka podstawowych poleceń systemu kontroli wersji, przeglądarkę klas i integrację z pyflakes. Niestety, PIDA ma wciąż sporo błędów i — to jest prawdziwe niestety — nie są one w ogóle poprawiane (prawdopodobnie dlatego, że nie ma kto tego zrobić, i nie, ja też tego nie dam rady zrobić). Bardzo to wkurzające, przede wszystkim zważywszy fakt, że żaden z wolnodostępnych edytorów nie oferuje tego, co PIDA...

Tak łatwo to jeszcze nie było

Znalazłem kilka dni temu samouczek pisania własnych ramówek webowych w Pythonie w oparciu o WSGI i bibliotekę WebOb. Tak łatwo to chyba jeszcze nie było...

Na szczęście minęły czasy pączkujących ramówek (w tempie dwóch tygodniowo, strach było otworzyć lodówkę), ale może takie samouczki pokażą pretendentom, co ich czeka od strony kodu. Bo tego, co ich czeka od strony użytkowników to się nie da opisać żadnymi słowami. ;)

QS-RF w trunku Django

Queryset-refactor zlądował w trunku Django. Wspominam z kronikarskiego obowiązku, bo nie zauważyłem żadnych problemów z moimi aplikacjami w związku z tym.

Ubuntu 8.04 RC1 na HP 6510b

Z rzeczy wkurzających:

  • żeby uruchomić instalatora w trybie tekstowym (alternate), do linii poleceń uruchomienia jądra trzeba dopisać vga=771 (w 7.10 wybierało się rozdzielczość z listy);
  • nadal występuje problem z twardym zwisem po zamknięciu pokrywy z powodu nieprawidłowej konfiguracji hotkey-setup, trzeba zrobić to samo, co w 7.10.

Z porażek kompletnych:

  • Firefox 3.0b5, działa może szybciej, apetyt na pamięć ma może mniejszy, ale ma dobrze widoczne bugi (np. nie daje się odinstalować ani zainstalować żadnych rozszerzeń i tematów).

Z sekcji próbowaliśmy, ale się nie udało:

  • klient BitTorrent Transmission jest śmieszny. Wzorcem metra w tej dziedzinie jest Azureus i chłopaki od KTorrent całkiem nieźle sobie poradzili z zadaniem napisania natywnego klienta, który nie odstawałby od Azureusa funkcjonalnie. O Transmission tego się nie da powiedzieć.

Walki z SuSE (open) ciąg dalszy

Do pisania aplikacji w Django ten system się raczej nie nadaje — nie ma w nim całej masy bibliotek, a przede wszystkim nie ma psycopg.

Kicha.

Dorobiłem się

W dzikim widzie zainstalowałem sobie OpenSuSE 10.3 z KDE. Omatko. OMG. Co za dno. Po 3 godzinach walki z systemem mam wyjący komputer, którego desktop wygląda rzygowicznie, a każda rzecz, której się tknie, działa zupełnie inaczej, niż jest to napisane.

Szajs. Szajs jakich mało. SuSE to szajs.

Free Software lockdown

Pomyślałem sobie, że skoro za niecałe 2 tygodnie ma wyjść nowe Ubuntu, to dam sobie parę dni na przetestowanie jakiejś innej dystrybucji. Padło na SuSE, ale z tego padnięcia nic nie wyszło — po pół godzinie kombinowania w pierwszych krokach instalacji zrezygnowałem nie doszedłszy do menu wyboru pakietów. Ubuntu nie każe wybierać żadnych pakietów...

Jakiś problem z Akismet

Akismet robi jakieś hocki-klocki, gdy w komentarzu wpisuje się link do strony z plikami listy mailowej WARPY. Trzeba będzie to zbadać.

Jak umierają idee (w Polsce)

Idee w Polsce umierają po cichu.

Jesienią ubiegłego roku zaczęliśmy robić prelekcje o Pythonie w ramach WarPy. Odbyło się 3 spotkania, po czym współorganizator ze strony WO@PW i WarLug-a poprosił o przerwę z powodu sesji. Gdy sesja się skończyła, organizatorom i potencjalnym prelegentom z kolei zaczął się gorący okres w pracy.

WarPy ma swoją listę mailową, w żadnym przypadku nie jest organizacją zamkniętą, która w tajnych głosowaniach ustala kto i o czym ma opowiadać. Ja nie mam ostatnio czasu zadać pytania, czy są w ogóle jacyś chętni, a chętni sami się nie zgłaszają. W ten sposób po cichu i bez rozgłosu kończy się kolejna idea.

Hi, all, I'm official

Mój pierwszy commit do repozytorium Django, jako oficjalnego maintainera polskiego tłumaczenia.

Ludzie mają problemy

A my nie! (My, czyli kilka naszych aplikacji)

Iwan Sagalajew, pracujący dla yandex.ru, podzielił się kilkoma spostrzeżeniami po nieudanym odpaleniu nowego serwisu społecznego. Czytałem to z niekłamanym zadowoleniem — większość problemów, które tam opisał, nie ma nawet szans, żeby nas dotyczyć. Po kolei:

  • zbyt długi czas zapisu danych sesji, nie dotyczy nas, bo sesje trzymamy w memcache;
  • efekt "dog-pile", nie dotyczy nas, bo rzeczy kosztowne robimy poza aplikacją (poniekąd asynchronicznie);
  • pomimo nacisków naszego DB-speca, nie normalizujemy naszego modelu nadmiernie.

Nie mam złudzeń, że w pewnym momencie będziemy musieli troszkę przyciąć nasz radosny bałaganik, ale aplikacja została zaplanowana z tak dużym zapasem, że to na pewno nie nastąpi w ciągu najbliższych kilku miesięcy...

Mała aktualizacja, pod wpływem komentarza Bluszcza — to on to wymyślił. A żeby nie rozpłynął się w samozachwycie, to wymyślił też parę marnych rzeczy, ale tego co marne pozbędziemy się prędzej czy później...

Dziwne potrzeby, oczywiste rozwiązania: polib

Ktoś (imienia nie wymienię) wysłał klientowi teksty do przetłumaczenia... w Excelu. Klient zadowolony, że nie musi używać żadnych hackerskich narzędzi typu poEdit, oczywiście przetłumaczył teksty w tymże Excelu, a nam przyszło załamać ręce. Ale tylko na chwilę.

Dzięki bibliotece polib załatwiliśmy sprawę w pół godziny. A żeby zaoszczędzić stękań na przyszłość, następne partie tłumaczeń też będziemy wysyłać w Excelu. A co!

Bosskie :D

Rzadko coś linkuję, ale to jest słodkie...

Ballada o SQLittle

Release early... Ale to nie my

Django zdaje się być całkiem w poprzek przyjętej zasadzie w świecie OS/FS: release early, release often. Ostatnie oficjalne wydanie Django miało miejsce 11 miesięcy temu, (23 marca 2007 roku). Rozumiałbym to, gdyby w projekcie niewiele się działo i rzeczywiście nie byłoby co wydawać, ale działo się wiele. Od tamtego czasu doprowadzono do używalności newforms, wprowadzono pełną wewnętrzną unikodowość, znacząco zmieniono także wyjście wprowadzając automatyczne eskejpowanie zmiennych podczas renderowania szablonów. Każde z tych wydarzeń (a pewnie i kilka innych) zasługiwałoby na wydanie, choćby po to, by nie powiększać przepaści pomiędzy kodem wydanym oficjalnie, a kodem rozwojowym.

Nie podoba mi się to.

Czego warto zazdrościć Javie

Na pewno nie średników i klamerek. ;)

Java jako język może nadawać się najwyżej do programowania pralek. Jako platforma może być przegniła do korzenia. Ale ma coś, czego co jakiś czas brak odczuwam bardzo mocno programując w Pythonie — zestaw specyfikacji do J2EE. Specyfikacja jak to specyfikacja, to suchy papier, może być bez sensu, ale złe są dopiero implementacje. Spośród tych wszystkich większość jest dość specyficzna dla Javy ("stwarzamy problemy by bohatersko je pokonywać", czy jakoś tak to było), ale są dwie, które ja uważam za perełki. I to są te dwie, których brakuje mi najbardziej:

  • JNDI, czyli uniwersalne usługi katalogowe;
  • JMS, czyli integracja komponentów aplikacji przez komunikaty.

Cała reszta może się schować, ale tych dwóch naprawdę mi brakuje. Nie to, żeby Python potrzebował takich specyfikacji, ja potrzebuję standardowych implementacji. O, jakby mi ułatwił życie taki serwer JMS z interfejsem w Pythonie (nie, ActiveMQ + Stomp to jeszcze nie jest to!)...

Kolory się mienią

Sprawdzanie schematów kolorów do Vima bywa męczące. Czasem nawet bardzo. Dlatego strona, na której można zobaczyć kilkaset schematów w działaniu na raz, może być zbawieniem. Szkoda tylko, że nie można obejrzeć tam kodu w Pythonie, to by mi najbardziej ułatwiło życie...

HP Compaq 6510b, dobre i złe strony

Nie ma komputerów doskonałych. Niestety. I mój nowy 6510b także nie jest doskonały, ma dobre i złe swoje strony.

Najpierw plusy:

  • obraz jak żyleta, matryca jest naprawdę dobra;
  • moc, szczególnie jak dołoży mu się dodatkowe 1GB RAM;
  • cichy HDD;
  • jest zimny;
  • karta wifi Intela (nie wymaga ndiswrappera!).

A teraz wreszcie minusy:

  • hibernacja działa, ale jest bez sensu, bo komputerowi mniej czasu zajmuje wyłączenie się i włączenie, niż zahibernowanie i odhibernowanie;
  • wygaszacz (xscreensaver) potrafi zawiesić X na twardo;
  • czas pracy na bateriach nie dociąga do zapowiadanych 5 godzin, a nawet 4 przy umiarkowanym użytkowaniu (PIDA, terminal z 4 zakładkami, serwer developerski Django, Firefox, Quodlibet) nie udało mi się osiągnąć, maksimum to 3:40.

Nie mogę powiedzieć, ogólnie jestem zadowolony, chociaż po zapowiedziach producenta spodziewałem się więcej...

Trick do Vima, który zmienia życie

Długo szukałem, aż wreszcie znalazłem. Jak zmieniać colorscheme w zależności od typu pliku i to tak, żeby działało to również przy przełączaniu między buforami z plikami różnego typu?

"colorschemes based on file type
augroup ColorSchemeOnFileType
    autocmd!
    autocmd BufEnter * if(&ft == 'htmldjango') | colorscheme oceandeep | else | colorscheme django | endif
augroup END

Udało się wreszcie... A już zaczynałem być zdesperowany. ;)

Mam kolejnego gadżeta

Tym razem zupełnie niechcący. Kończyła mi się umowa u komórkowców, więc ją sobie przedłużyłem, przy okazji wymieniając telefon na nowy. Dopiero po powrocie do domu, przeglądając instrukcję obsługi, znalazłem logo Symbiana i coś na temat S60... Czyli mam fona z S60! :D

Pierwszą rzeczą, którą sobie zainstalowałem był (a jakże inaczej) PyS60...

Jest nas dużo, ale wciąż za mało

Na Django People jesteśmy teraz na 4 miejscu, razem z Niemcami. Uważam to za całkiem niezły wynik. Przed nami są Brazylia, Wielka Brytania i US of A (w tym przypadku chyba bardziej sprawiedliwe byłoby liczenie według stanów, ale się nie upieram), więc raczej kraje albo dużo bardziej liczne ludnościowo od nas, albo bardziej ambitne, jeżeli chodzi o pokazanie się. Mogę się mylić (i pewnie się mylę), ale każde miejsce wśród pierwszych 7-8 powinno nas zadowalać, choćby z powodu tego, ile osób przychodzi na WARPY (w tym tygodniu zostało odwołane). Python zajął już poczesne miejsce w galerii języków programowania, a Django jest już powszechnie rozpoznawane.

To dobrze. Roboty jest dużo, a ten wózek musi się toczyć.

Ubufox is a shit

Odkąd przesiadłem się na ubuntu 7.10 przez cały czas miałem problemy z wtyczką Flash do Firefoxa. A to twierdził, że jej nie ma, a to że jej nie chce, a to znowu coś innego. W pewnym momencie doprowadziłem swojego FF do tego, że musiałem usunąć cały profil i utworzyć go na nowo. Pakiet flashplugin-nonfree był oczywiście zainstalowany przez cały czas, ale ćwok uparcie twierdził, że nie jest. Mało tego, proponował ciągle zainstalowanie pakietu flashplugin-nonfree i po chwili rezygnował, stwierdzając, że przecież jest zainstalowany. Po wypieprzeniu ubufoksa zainstalowałem sobie wtyczkę prywatnie.

Panowie od ubuntu, wasz ubufox to kawał gówna.

Tutoriale mnie dygają

W szczególności tutoriale do ramówek webowych. Każda ramówka w pewnym momencie dorabia się "20 minutes wiki tutorial" (czasem nawet w formie screencastu), ale w większości przypadków są one całkowicie bez sensu — nie pokazują tego, jak ramówka działa, nie uczą, jak jej używać, nie opisują jej komponentów. Zaczęło się od niesławnego screencastu RoR, a potem było już z górki. Pamiętam kilka lat temu, gdy w krótkim czasie wystartowały TurboGears i zaraz potem Django, że początkowo TG wygrywało popularnością właśnie z powodu posiadania takiego screencastu (i uzyskiwało opinię łatwiejszego do nauczenia). Lista mailowa TG pękała w szwach, zapowiadano nowe, ekscytujące możliwości kolejnych wydań ramówki, ale minęło kilka-kilkanaście miesięcy i to Django przejęło inicjatywę. Po kolejnych kilku-kilkunastu miesiącach TG uchroniło się przed zniknięciem, ale jak na pioniera radzi sobie coraz gorzej, już nie jest nawet numerem 2, bo w staraniach o przejęcie władzy nad sercami i umysłami developerów wyprzedziło je Pylons. Na szczęście, Pylons również posiada 20 minutes wiki tutorial, więc pozycja Django (które posiada jedynie nieoficjalny screeencast wiki na ShowMeDo) wydaje się być niezagrożona. ;)

Tak sobie właśnie przypomniałem... Jakiś czas temu prorokowałem, że z pierdyliarda ramówek webowych w Pythonie (był taki okres, kiedy powstawała jedna ramówka dziennie...), pozostanie nam 2-3 liderów i plankton — i tak się właśnie stało. Kto wymyśli tę, która zdetronizuje obecny numer 3 i stanie do wyścigu o pierwsze miejsce?

64MB RAM na Megiteam.pl

To mało czy dużo? Zależy... Moja aplikacja daje radę. Działa na jednym procesie FastCGI, swoje przydziałowe (?) 64MB RAM wykorzystuje w 100%. Szukałem jakichś wskazówek, jak ograniczyć apetyt aplikacji Django (uruchamianej na FastCGI) na RAM, ale znalazłem niewiele, a już na pewno nic nowego, nic, czego bym już nie wiedział. Być może nie jestem jeszcze aż tak bardzo zdesperowany, bo nie odczuwam, żeby aplikacji brakowało pamięci. Może to jest całkiem wystarczająca ilość, skoro aplikacja się jeszcze nie krztusi?

E, tam, nie mam chyba większych problemów... Jeszcze kilka lat temu nie przeszłoby mi przez myśl, że będzie mnie stać na hostowanie gdziekolwiek aplikacji w czymkolwiek innym, niż PHP. Zanim dorobiłem się hostingu na megiteam.pl nawet zastanawiałem się, czy nie iść na taniochę i nie przeprosić się z PHP. A tu — prawie jak spełnienie marzenia.

Aktualizacja z 18 stycznia: pani Magda Zarych, właścicielka megiteam.pl, uściśliła moje domysły. Aplikacja nie spożywa 64M, lecz w granicach 18M. Patrzyłem nie na to, co trzeba. Swoją drogą, przyjemnie, że firma wsłuchuje się w bicie serca klientów. ;)

Pylons zniechęca

Podkusiło mnie i postanowiłem zrobić tutorial Pylons, trochę z ciekawości, a trochę podążając za modą. Ogólne wrażenie było raczej... marne. Zarówno jeżeli chodzi o Pylons, jak i o sam tutorial.

Przede wszystkim, tutorial stanowił nie lada wyzwanie. W pewnym momencie zalecane do wykonania polecenie zakończyło się bardzo brzydkim tracebackiem, który niewiele mówił. Nie wiedząc, co zrobiłem źle, darowałem sobie dalsze przerabianie materiału, ale następnego dnia zaświtała mi pewna idea i po sprawdzeniu okazało się, że miałem rację — kilka sekcji dalej omówione zostało ustawienie konfiguracji, którego brakowało. Po pokonaniu tej przeszkody udało się dobrnąć do końca.

Teraz trochę o wrażeniu, jakie robi automatycznie wygenerowany szkielet aplikacji. Zawiera on dużo więcej, niż szkielet, jaki generuje Django. W prawie każdym pliku używana jest konstrukcja from package.module import * co powoduje, że właściwie nie wiadomo, skąd co pochodzi. Dodatkowo autor tutoriala ma zadziwiający zwyczaj używania jednoliterowych skrótów, jak np. "h" dla "helpers" czy "c" dla "context" (wygląda to na dość powszechny obyczaj). Ilość tekstu do napisania się zmniejsza, ale traci na tym czytelność. Do tego dokłada się jeszcze duża ilość modułów, które importowane są na wszelki wypadek, a przynajmniej bez jakiegokolwiek wytłumaczenia. Wszystko to składa się na ogólne wrażenie chaosu.

A teraz o samej ramówce, a raczej o tym, co jest zalecane jako jej elementy w wersji 0.9.6.1 (bieżącej w chwili pisania tego artykułu). SQLAlchemy jest potężne, skomplikowane i nieprzyjemne. Routes jest potężne, skomplikowane i nieprzyjemne. System szablonów Mako jest potężny, skomplikowany i nieprzyjemny. Paster jest potężny, skomplikowany i nieprzyjemny. W efekcie Pylons jako całość jest potężne, skomplikowane i nieprzyjemne. Zupełnie jak Spring. Na pewno można przy jego użyciu zrobić milion sprytnych rzeczy, ale nie chodzi o to, żeby robić sprytne rzeczy, tylko żeby zrobić co trzeba i mieć przy okazji trochę dobrej zabawy.

Konkluzja jest dość oczywista — dopóki nie będę musiał, nie porzucę Django dla Pylons. Z pracy przy projektach w Django mam przynajmniej sporą dozę radochy...

Próbowałem, poddałem się (na razie)

Chciałem podłączyć moją usługę (webservice zrobione na podstawie twisted.web) do serwera Zeroconf i okazało się, że to całkowicie niemożliwe w obecnej sytuacji. Jedyna dobra biblioteka do tego, czyli avahi, jest tak mocno zintegrowana z DBus, że wymaga... głównej pętli programu zrobionej na GObject, żeby móc działać asynchronicznie. Porażka. Znalazłem wstęp do implementacji usług związanych z mDNS przy użyciu Twisted, ale oczywiście niepełną.

Chyba trzeba będzie sobie wreszcie ubrudzić ręce trochę poważniejszym kodem...

Książki, książki

Po Pro Django, Web Development Done Right szykuje się kolejna książka o tej ramówce — James Bennet zaanonsował, że pisze książkę, która omawia Django od strony praktycznej. Książka jest już listowana na Amazon.com, więc sprawa wygląda na poważną. Wypada się tylko cieszyć. Przyda się taka książka wszystkim początkującym.

Jednym z zagadnień przez tę książkę poruszanych ma być pierwsza aplikacja w Django, czyli właśnie silnik blogowy. Ja swój napisałem w ciągu kilku wieczornych sesji, właśnie jako projekt szkoleniowy z migracji na nową wersję Django (choć wcale nie był pierwszą aplikacją, moją pierwszą aplikację można już podziwiać od dłuższego czasu w Rumunii, na Węgrzech i w Wielkiej Brytanii). Trudno jednak wymagać, by ktokolwiek zaczynał zaznajamianie się z Django od dużego, komercyjnego projektu na zlecenie międzynarodowego klienta...

Co z tym Django?

Coraz bardziej niecierpliwię się tym, że Django wciąż nie ma oficjalnego wydania wersji, która miałaby pełne wsparcie dla unikodu i działające newforms. Pojawiły się pogłoski, że następne wydanie to nie będzie oczekiwane przez wszystkich 0.97, ale od razu 1.0 — to by oznaczało, że ilość rzeczy, jakie trzeba będzie zrobić podczas migracji będzie podobna, jak przy 0.91. Tutaj nie ma to wielkiego znaczenia, ale w pracy będziemy mieli dylemat...

WARPY #2

Dziś na PW kolejny wykład w ramach WARPY. Z powodów osobistych się nie wybiorę, niestety.

Następny wykład będzie 10 stycznia 2008, o ile nie zajdą jakieś nieprzewidziane okoliczności. I będę się starał wygłosić prelekcję o PyGTK.

Dobre wieści, Django znowu działa

Mądrzejsi ode mnie znaleźli błąd, poprawili i Django znowu działa przez FastCGI. Chwała nam i naszym kolegom, wiadomo komu precz!

Dell hell

Dzień w plecy z powodu kreatywności firmy Dell. Moja maszynka w pracy to niestety Dell Optiplex 320 — tak, niestety, właśnie ten szajs. Zainstalowanie na niej jakiegokolwiek linuksa graniczy z cudem, a Ubuntu 7.10 zainstalować się na nim nie da wcale z powodu buga w jądrze 2.6.22 (7.04 się udało, pomimo gimnastyki z grub2). Wydaje się, że przyczyną większości problemów jest kontroler SATA firmy (a jakże!) ATi, ale regresja względem poprzedniego wydania to nie jest coś, czego bym się spodziewał...

Buggy weekend

Dwa straszliwe bugi objawiły się w projektach, które są mi z różnych powodów bardzo bliskie. Mało tego, żaden nie został jeszcze poprawiony.

Gajim ma problem z GnuPG — pewnym obejściem jest używanie gpg-agent (w sumie i tak powinienem go używać, ale chyba nie jestem jeszcze aż takim paranoikiem), ale jest możliwość doprowadzenia swojej konfiguracji do takiego stanu, że Gajim nie da się uruchomić. Wystarczy odhaczyć w ustawieniach konta "Używaj gpg-agent" i mieć wybrany jakiś klucz GPG do szyfrowania. Gajim daje segfaulta podczas uruchamiania. Sprawdzę jutro w pracy, czy ma to coś wspólnego z oprogramowaniem, jakie mam na domowej maszynce.

Django z powodu przeciekającego skądś obiektu SafeString zwraca nieprawidłową zawartość HttpResponse. Z tego powodu Flup odmawia współpracy i ogólnie w tej chwili trunk Django nie nadaje się do użycia przez FastCGI. Sprawdziłem to tymi rękami, na tym sajcie — nie działa. Nie jestem aż tak dobrze obeznany z internalsami Django, żebym zabierał się za zmiany w kodzie, zwłaszcza, że byłoby to grzebanie w HttpResponse... Nie da rady, trzeba czekać.

Trunk Django nie nadaje się do użycia!

Od rewizji 6778 trunk Django nie nadaje się do użycia przez FastCGI! Czujcie się ostrzeżeni, choć jeszcze nie wiadomo, skąd bierze się ten problem (Malcolm T. twierdzi, że SafeString nie powinno się tam pojawić...).

WAR-PY

Albo WARPY, albo może WarPy... Nie wiem, jaka jest oficjalna pisownia tego dziwnego skrótowca, nawet pomimo tego, że w jego powstawaniu brałem udział kilka tygodni temu w pubie Wetlina. Dość, że robocza nazwa staje się powoli nazwą oficjalną.

We czwartek 29 listopada o 19.00 na Politechnice Warszawskiej w sali AL odbędzie się pierwsza prelekcja, którą wspólnymi siłami (Grono.net, Sensisoft, WARLUG i WO@PW) urządzamy celem popularyzacji Pythona. Zacznie Marek Pułczyński z Grona, od standardów pisania kodu w Pythonie. Z agendy wnoszę, że będzie głównie opowiadał o trzymaniu się konwencji, dokumentowaniu kodu przy użyciu docstrings i budowaniu pakietów, ale temat może odpłynąć, bo zagadnienie jest... dość nośne. Kolejne spotkania będą się odbywać co dwa tygodnie.

Na prelekcję za dwa tygodnie ostrzy sobie zęby Rafał Zawadzki, więc ja się wstrzelę pewnie dopiero za 6 tygodni. Na razie planuję opowiedzieć coś o PyGTK, ale przecież wszystko może się odmienić...

Platforma dla programisty

Używam linuksa (jak to się teraz modnie mawia: lennoxa) od wielu lat. Od wielu lat słyszę, jakoby system był nieprzyjazny, nieintuicyjny i wiele innych nie na jego temat. Nie będę się teraz rozpisywał, jak to z gruntu fałszywe są to opinie (bo mam jeden dowód na to w domu w postaci żony i drugi w bloku naprzeciwko w postaci mojej matki). Są jednak tacy ludzie, dla których linux jest jedną z najbardziej przyjaznych platform.

Programiści.

Niezliczone ilości narzędzi (darmowych!), biblioteki do prawie każdego zadania i języka, jakie tylko można sobie zamarzyć. Kod źródłowy, który może służyć za przykład, nie zawsze najwyższej jakości, ale przecież jest. Żyć nie umierać, tylko pisać kod. Nie powiem, pisałem programy na własne potrzeby i dla własnej przyjemności także i wtedy, gdy używałem najpopularniejszego systemu operacyjnego, ale zawsze było to trochę utrudnione — a to nie działało to czy tamto, a to jakiejś biblioteki nie było sportowanej, a zdarzały się dziwne zachowania programu wynikające z idiosynkrazji tego innego systemu operacyjnego.

A najgorsze było to, że Vim działał jakoś dziwnie na tym całym Windows®...

Übersatan

Niejaki problem z Flupem

Jak wiadomo, Django używa pakietu Flup żeby uruchamiać aplikacje w środowisku serwera oferującego FastCGI (Apache + mod_fastcgi, nginx, lighttpd). Trafiłem na coś, czego jeszcze do tej pory nie widziałem na oczy. Nigdzie i nigdy.

Nasza aplikacja nigdy nie wyrzuca błędu. Nie mówię o 500, w końcu istnieją aplikacje doskonałe, ale nawet 404, i to pomimo tego, że w kodzie w wielu miejscach leci wyjątek django.http.Http404. W takiej sytuacji aplikacja wyświetla jakąś statyczną stronę (nie ma to nic wspólnego z naszym szablonem 404.html czy 500.html) i zwraca 200. Dogrzebałem się, że jest to efekt działania ErrorMiddleware z Flupa, który w ten sposób próbuje zwrócić na siebie uwagę (przy okazji wysyła maila do administratora, ale u nas to nie występuje...). Podobno występuje to wtedy, gdy błąd taki nie zostanie obsłużony przez aplikację, co w naszym przypadku jest o tyle dziwne, że podobno przecież Django obsługuje wszystkie wyrzucone wyjątki przy użyciu odpowiedniej dla typu wyjątku funkcji.

Co ciekawsze, okazało się, że najnowsza wersja Flup-a (1.0) nie zawiera już tego middleware, więc gdyby się okazało, że Django bez problemu działa z tą wersją, to może oznaczać tylko głębokie problemy z naszą konfiguracją na styku mod_fastcgi i Django.

Budzi się pragnienie

Powoli budzi się we mnie pragnienie (a może i potrzeba) wymiany laptoka na nową sztukę. Mój obecny HP nx6110 z najniższej półki wciąż jeszcze mi dobrze służy (chyba przede wszystkim dlatego, że mam niewielkie wymagania...), ale zaczynam już odczuwać potrzebę poprawienia mojej sytuacji życiowej. Lepsze jest wrogiem dobrego, a już na pewno jest wrogiem słabego.

  • 15' matryca mojego HP jest chyba jedną z najgorszych, jakie były produkowane dwa lata temu; wiem, że są gorsze (mają je np. najtańsze Acery z tamtego okresu), ale wcale nie zmienia to faktu, że kolory odwzorowuje tragicznie, szczególnie na bitmapach;
  • procesor Celeron-M360J (1.4GHz) nie jest demonem prędkości i nie ma co się nad tym rozwodzić;
  • dysk 40GB dawno już został zapełniony i muszę się posiłkować dodatkowym dyskiem podłączanym przez USB;
  • 3 kilogramy na ramieniu potrafią przygiąć do ziemi każdego.

Nie za bardzo mam ochotę kupować sobie MacBooka, wolałbym jakieś fajne HP z matrycą 13.1'... Ale takich nie ma. Przynajmniej na moją kieszeń.

W każdym razie, i tak muszę poczekać do przyszłego roku. Obiecałem, że w tym roku nie kupię sobie komputera...

Cache obiektów w Django - jak się nie zgubić?

Zdarza się tak, że domyślny sposób buforowania, używany przez Django (buforowanie całych stron, buforowanie całego serwisu) nie wystarcza i trzeba buforować pojedyncze obiekty lub ich listy. Gdy się już zacznie, trudno jest przestać i wtedy okazuje się, że nie sposób dojść do tego, pod jakim kluczem co jest zbuforowane. Sytuacja komplikuje się dodatkowo, gdy używa się memcache, a już całkiem, gdy w buforze trzyma się dane sesji. Najłatwiej byłoby zrestartować memcached, ale przecież polecą sesje użytkowników... Zaczyna się gorączkowe szukanie klucza i strzelanie w ciemno, ale to naprawdę głupiego robota, bo klient memcache zawsze zwraca 1, gdy nie wystąpi żaden krytyczny błąd. Rozwiązaniem byłoby przejrzenie listy kluczy (np. przeiterowanie przez nie), ale czegoś takiego nie ma.

Wpadłem na pomysł prostego rejestru kluczy w postaci zbioru (set). Zdaje się to działać na tym serwisie (który jest trochę poligonem...), a jak działa w naprawdę dużym serwisie, to się dopiero okaże jutro, jak sprawdzę to w pracy. Na razie jestem dobrej myśli, bo idea zdaje się nie mieć słabych punktów... ;)

Naprawili na gorsze

Zaktualizowałem sobie [Ubuntu[(http://www.ubuntu.com/) w moim domowym lapku z 7.04 (z którego byłem więcej niż zadowolony) do najnowszego 7.10 i od kilku dni mam nieodparte wrażenie, że to już raz było, że podobne rzeczy działy się półtora roku temu, gdy po dwóch miesiącach opóźnienia pojawiła się wersja 6.06, która podobno dopracowaniem miała na głowę pobić wszystko, co widziano w świecie linuksa. Po zainstalowaniu tamtej wersji nagle mój laptop zaczął się grzać, niemiłosiernie hałasował, a system zaskakiwał mnie co chwilę swoimi idiosynkrazjami typu zużycie 100% mocy procesora co kilka sekund.

Teraz jest tak samo. Hałasuje, grzeje się, bateria ładuje się całe wieki, a poprawiony silnik renderowania czcionek TrueType w efekcie daje rozmyty, ohydny i męczący na dłuższą metę obraz. Jestem coraz bardziej przekonany, że powrót do 7.04 jest tylko kwestią czasu.

More power to the people

Będąc code junkie (jak o nas mawiają marketoidy), nie mogę się powstrzymać, żeby czegoś nie ulepszyć (co wcale nie jest zepsute). Przyszło mi do głowy, że mógłbym poćwiczyć z OpenID, więc należy się spodziewać, że wkrótce gdzieś na stronie pojawi się charakterystyczny symbol i posiadacze OpenID będą mogli się wcielić w jakąś specjalną rolę w serwisie. Jeszcze nie wiem jaką, ale będę musiał coś wymyślić, żeby wynagrodzić im wszystkie trudy... ;)

Trzy kolory

Jeśli edytor, to wiadomo: Vim. A jeśli pisanie w nim kodu, to wiadomo, co jest jedną z podstaw: podświetlanie składni tak, żeby wszystko było dobrze widoczne, a jednocześnie w takim zestawie kolorów, który nie męczy oczu, nawet wtedy, gdy trzeba patrzeć w ekran po kilka godzin. W takich przypadkach wygrywają zestawy raczej mało kontrastowe i raczej te z ciemnym tłem. Oto trzej moi faworyci, w kolejności niekoniecznie przypadkowej:

  • oceandeep, utrzymany w zielono-niebieskiej tonacji, prawie bez mankamentów;
  • desert, brązowo-beżowy, cokolwiek nudny, ale bardzo spokojny;
  • zenburn, faworyt wielu, dla mnie trochę więcej niż akceptowalny, jakoś nie przekonuje mnie aż tak niski kontrast, ale czasem (szczególnie późno w nocy) jest ukojeniem dla oczu.

Mam archiwum XYZ

Zrobiłem dziś archiwum według miesięcy, przy czym trochę bardziej z ciekawości niż z rzeczywistej potrzeby użyłem pakietu Babel (chciałem mieć ładne nazwy miesięcy itd). Przy okazji znalazłem babola w ostatnim wydaniu, tymczasowo poprawiłem ręcznie żeby w ogóle działało. Poczułem się trochę zawiedziony, że tak zachwalany mi przez kolegów pakiet (i w wersji 0.9.1, a taki numerek powinien już zobowiązywać) nie ma testów, które potrafiłyby wykryć taki problem. Ale co ja psioczę, moje projekty w ogóle nie mają testów... ;)

A na razie cieszę się tym nowym, wspaniałym archiwum i już spoglądam w przyszłość, co następne w kolejce do zrobienia.