Czy Python nie jest piękny?

Podczas dłubania w jednym skrypcie wyszło mi coś takiego (no tam było trochę czytelniej,
na potrzeby Joggera upiększyłem:

x=[x for x in x if x]

Każdy Pythonowiec od razu zrozumie, że ta instrukcja usuwa puste
(None, "", 0, itp.) elementy z listy
:-). Wiem, w Perlu dałoby się jeszcze mniej czytelnie, pewnie krócej
i na 100 różnych sposobów, ale na pewno nie tak ładnie ;-)

Oczywiście nie polecam takiego programowania — wypadałoby przynajmniej
zmienić jedno x na coś innego.

MAILER-DAEMON ma nowych przyjaciół.


From: jakiś_luser
Subject: Luser
To: "Mail Delivery System" <MAILER-DAEMON@mój-server>

Wróciliśmy cali i zdrowi . Jak na nasze polskie warunki drogowe - udało się
przejechać w ciagu jednego dnia 800 km. Wyjechaliśmy 4.20 rano a wróciliśmy
20.30 wieczorem . Byliśmy na grobach rodziny w Bygdoszczy i po drodze
odwiedziliśmy Licheń . Nie wiem czy się orientujesz , jest to miejscowość koło
Konina , gdzie wybudowano duże Sanktuarium . Muszę kończyć póżniej napiszę
więcej.
narazie
Luser

Robota…

Wczoraj wyczerpała mi się bateria w komórce, a ładowarki nie mogłem znaleźć.
Dzisiaj rano też nie, więc pojechałem do pracy z rozładowaną komórką. Komórka
nie dzwoniła, to o niej zapomniałem… aż do momentu gdy bardzo potrzebowałem
pewnej informacji w niej zapisanej. Wkurzyłem się strasznie i po powrocie
wywróciłem pół domu do góry nogami, żeby tę ładowarkę znaleźć. Była
mniej-więcej tam gdzie zawsze, ale przysypana górą papierów.

Jak tylko podłączyłem komórkę przyszło 44 SMSów. Głównie od automatów, które
zwykle siedzą cicho. Zadzwonił też kumpel, że coś tam się rozłącza. Z SMSów
wynikało, między innymi, że wszystko na serwerowni pojawiało się i znikało,
więc diagnoza była prosta — znów przerwy zasilania w budynku TPSA, gdzie
mamy tę nieszczęsną szafę. Zalogowałem się na jeden z serwerów i sprawdziłem
stan baterii w UPS: 45%, UPS był On-Line. Uznałem, że był problem ale już go
nie ma i olałem sprawę. I to był mój błąd. A ja jeszcze poszedłem do parku do
rodzinki, stając się znowu nieosiągalny, bo komórka ładowała się w domu.

Gdy wróciłem już czekała na mnie wiadomość na sekretarce, że coś dalej nie
działa. Okazało się, że rzeczywiście — jeden z naszych głównych routerów
szalał. Miałem z nim jakiś kontakt przez konsolę szeregową, więc próbowałem
reanimować go zdalnie. Kontakt polegał na tym, że router sypał tonami
komunikatów i w ogóle nie reagował na jakąkolwiek próbę interakcji. Ale czasem
robił sobie przerwy, w których można było coś sprawdzić i próbować maszynę
rebootować. Za którymś rebootem nie wstał. No cóż, trzeba było jechać na
serwerownię. Tam się udało sytuację opanować i wygląda na to, że jak na razie
wszystko działa.

Najgorsze jest to, że rzeczywiście nawaliłem. No i w poniedziałek czeka
mnie pewnie dywanik u szefa. Oczywiście sporo winy jest po stronie TPSA, która
pozwala sobie na takie jaja z zasilaniem (dojazd elektryka, który może
wymienić odpowiednie bezpieczniki trwa czasem ponad godzinę), ale ja
powinienem zareagować szybciej. Zamiast tego wolałem uznać, że jest OK i
lecieć do żonki i córci. A jak jest wszystko OK, to czasem zamiast zajmować
się rodzinką to siedzę przed kompem, robię jakieś pierdoły i udaję (przed
samym sobą), że ciężko pracuję. Ech…

No i stało się

Przed chwilą dokonałem zmian w PyXMPP w kierunku który doradził Jarek,
ostatecznie zrobiłem tak:

  • fr -> from_jid
  • to -> to_jid
  • typ -> stanza_type
  • sid -> stanza_id

Dla ułatwienia życia sobie, a także innym developerom używającym PyXMPP
(są tacy?) przygotowałem też skrypt poprawiający kod pythona używający starych
nazw. Mnie nawet ten skrypt nic nie popsuł.

A w pracy wkurzałem się na interfejs WWW zarządzania switchy DLink
i access-pointów Proxima. Chcę dać na zewnątrz (żebym miał w domu,
czy gdzieś w terenie) dostęp do tych urządzeń. Że urządzenia nie mają SSL, to
nie mogę tego po prostu przeroutować, więc robię to przez reverse-proxy na
Apache z mod_ssl. Pierwszy problem to bezwzględne linki na stronach tych
interfejsów. Ale to załatwia (teoretycznie) mod_proxy_html.
Tylko, że mod_proxy_html parsuje otrzymany HTML, poprawia co
trzeba i serializuje od nowa. Ale jak to ma działać na czymś co do HTMLa jest
tylko miejscami podobne (tak jest w przypadku Proxima — po prostu
koszmar)? No nie całkiem działa. Do przeglądarki dochodzi już poprawny HTML,
ale wyrażający nie całkiem to co autor miał na myśli. Miejscami prześwituje
kod JavaScript, inne rzeczy poprzestawiane itp. Z tym pewnie będę jeszcze
długo walczył.

mod_proxy_html poprawia też skrypty JavaScript w kodzie
HTML, robi to na głupa, ale jak się postarać, to można uzyskać ciekawe
efekty. Gorzej ze skryptami zewnętrznymi, w osobnych dokumentach. W przypadku
switchy nie jest niby źle, bo w zewnętrznych skryptach nie ma zaszytych
żadnych ścieżek, ale za to są serwowane jako text/html, a co za
tym idzie mod_proxy_html próbuje z nich robić poprawnego
HTMLa. No i taki skrypt po dodaniu <html><body> na początku
i po przetworzeniu tagów w środku nie bardzo chciał działać. Musiałem więc tak
skonfigurować mod_proxy_html, aby zajął się jedynie
dokumentami *.html.

Proximy za to mają zaszyte ścieżki w plikach *.js, jednak
serwowanych poprawnie, jako text/javascript.
mod_proxy_html w ogóle tego nie rusza, za to znalazłem
jeszcze mod_ext_filter (standardowa część Apache 2.x). Przy pomocy tego
moduliku można serwowane dokumenty przepuścić przez zewnętrzny program. A więc
przepuściłem przez seda i poprawiłem ścieżki gdzie trzeba.
Nawet zadziałało. Chyba tego samego modułu wraz z sedem, albo
jakimś mądrzejszym skryptem w
perlu/awku/pythonie będę
musiał użyć do tego paskudnego HTMLa z Proxima. To jest do zrobienia,
ale może być z tym kupa roboty i nie wiem czy się wcześniej nie poddam.

Pożeracz ramu

Przed chwilą ktoś się mnie spytał, czy to normalne, że transport GG zżera 64MB pamięci
(pole VIRT na topie). No normalne to nie jest, ale sprawdziłem u siebie… odpaliłem top,
dałem u jabber i moim oczom ukazało się
913MB w polu VIRT procesu jggtrans. Hmmm…
chyba mamy mały wyciek… Tylko kiedy ja to zbadam i poprawię?

Czyszczenie PyXMPP

Najwyraźniej jest jakieś zainteresowanie moją pythonową biblioteką
XMPP. Ludzie (przynajmniej paru) chcą tego używać, ale wielu od razu się
zniechęca brakiem dokumentacji, inni po próbach zrozumienia o co w tym biega.
Nie dziwię się — kod zamotany jak rzadko, a dokumentacji praktycznie brak.
Bardziej dziwię się ludziom takim jak pete, czy Zgoda, którzy tego używają i nawet mnie
z tego powodu nie męczą. Jednak uznałem, że trzeba coś z tym zrobić…

Więc od paru dni zamiast dodawać nowe ficzery do CJC, poprawiać
w nim bugi, czy implementacje protokołów w PyXMPP to ślęczę nad kodem PyXMPP
i, terroryzowany przez pylinta czyszczę kod,
co jakiś czas robiąc: cvs commit -m "cleaning up...". Przy jakiś
czas coś psuję głupimi literówkami, albo zamierzonymi zmianami w API PyXMPP
(sorry developerzy), np. zamiana nazwy parametru konstruktora klasy Stanza
z type na typ, bo ta pierwsza nazwa zakrywała nazwę wbudowanej
funkcji. Jak już wspominałem większość marudzenia pylinta dotyczy braku
docstringów, a więc je dodawałem na bieżąco. Oczywiście nie
"", ale w miarę konkretną dokumentację, która się może jakiemuś
developerowi przydać. I tu wkracza Epydoc

Normalnie do przetwarzania dokumentacji w pythonie służy narzędzie
pydoc. Jednak jest ono głupie, bo traktuje docstringi jako
czysty tekst, bez formatowania czy hyperlinków. Taka dokumentacja jest mało
czytelna i niewygodna. Już jakiś czas temu szukałem informacji na temat
robienia porządnej dokumentacji do kodu Pythona i dowiedziałem się, że the
right way
to jest (lub raczej będzie) używanie w docstringsch reStructuredText.
Narzędzi do przetwarzania tego wtedy nie znalazłem (słabo szukałem, albo
jeszcze nie było), znalazłem tylko docutils które, między innymi,
takim narzędziem mają się stać, ale na razie umieją tylko parsować
reStructuredText i konwertować to do mądrzejszych formatów.
Mimo braku narzędzia do obróbki tego jednak już wtedy postanowiłem
reStructuredText używać. I nawet użyłem w tych skrawkach
dokumentacji które zdążyłem zrobić.

Teraz przy czyszczeniu kodu znowu szukałem narzędzia do generowania
dokumentacji z kodu. Tym razem znalazłem. Docutils wciąż nie
umieją wyciągać dokumentacji z kodu Pythona, ale mogą być wykorzystane
przez Epydoca, który to potrafi.
Ma on niby swój markup dla docstringów, ale potrafi, przy pomocy
docutils obsłużyć także reStructuredText (ale tylko tworząc
dokumentację w HTML). Więc to właśnie podpiąłem pod doc/Makefile.
Okazało się, że stare kawałki dokumentacji musiałem popoprawiać, żeby
Epydoc sobie z tym poradził. Nowe tworzyłem od razu pod
tandem Epydoc+docutils. I nawet są jakieś
efekty. Otrzymana dokumentacja wygląda nieźle, jest dość przejrzysta… tylko
ma olbrzymie braki. :-( Kiedy ja to wszystko opiszę?

Wieczorem sam w domu…

Przez moją sklerozę żona poszła się upić. )-; A ja zostałem w
domu dziecka (śpiącego na szczęście) pilnować.

Może ten czas spożytkuję na porządki w kodzie PyXMPP.
Do pomocy zatrudniłem pylinta, który mi
pokazuje wszelkie moje grzechy w kodowaniu. Teraz plik
TODO.pylint liczy 1158 linii (905 ostrzeżeń, 68 błędów) mimo,
że i tak pomocnika trochę uciszyłem. Ale lista się kurczy co oznacza,
że jest chyba coraz lepiej. Najczęstrzym moim grzechem jest brak
docstrings, a więc dokumentacji kodu. A w przypadku biblioteki to spore
przewinienie… Jak dobrze pójdzie, to dzisiaj przynajmniej ten największy z
modułów — pyxmpp.stream — uporządkuję.

Plugin świra

Właśnie napisałem plugin Joggera dla swojego CJC. Oczywiście
jeszcze można wiele w nim zrobić, ale już powinno dać się wysyłać
wiadomości. A nawet nie tylko. Dla każdej wiadomości można wybrać poziom,
a przed wysłaniem jest walidowana wybranym DTD (domyślnie XHTML Strict).
A więc koniec wpisów psujących joggera! :-) Oczywiście edycja
odbywa się w edytorze wybranym przez użytkownika (domyślnie
$EDITOR lub vi, jak to w UNIXach). To będzie
pierwsza wiadomość wysłana z tego plugina na prawdziwego joggera, więc ciekawe
czy i jak dojdzie.

W przedostatnim wpisie pisałem o planowanym przejściu na
ejabberd. W kolejnym krótko napisałem, że się udało. Krótko,
bo było za wcześnie aby mówić o wielkim sukcesie no i dlatego, że nie miałem
plugina w CJC. Z dokładną oceną chciałem trochę poczekać i już chyba nadszedł
odpowiedni czas.

A więc z nowego serwerka jestem bardzo zadowolony. Większość użytkowników
chyba nawet nie zauważyła zmiany. Niektórzy wręcz założyli, że skoro dalej
wszystko działa, to znaczy, że wróciłem do starego. Po prostu działa.
Rozczarował mnie nieco interfejs administratora — zarówno z WWW jak i z
tkabbera. Okazało się, że nie da się przez to zakładać użytkowników. Trzeba z
shella za pomocą ejabberdctl albo pozwolić userom samym się
rejestrować, a tego nie chcę.

A co do tytułu wpisu… Dzisiaj byłem u psychiatry. Dostałem receptę. To już
chyba jestem oficjalnie świrem ;-). Prawdopodobnie ta wizyta to
tylko pieniądze wyrzucone w błoto, ale spróbować zawsze warto.

Linux naucza muzyki

Googlałem za oprogramowaniem które ułatwiłoby moje zabawy z gitarą. Dokładnie to chciałem znaleźć jakiś program do tabulatur, co umiałby zaimportować tabulatury ASCII i je potem zagrać jako MIDI. Na razie nic takiego nie znalazłem, ale znalazłem ten oto ciekawy artykulik. Mimo, że nie wspomina o tym, czego szukałem, to i tak zaraz zabieram się za ściąganie opisanego tam oprogramowania.

ejabberd…

O dziwo wszystko (tak mi się wydaje) na tym ejabberd działa. Stanowczo za gładko to poszło… Zobaczymy co będzie jutro, czy jacyś użytkownicy będą się skarzyć.

Jedynie z SSL miałem problemy — najpierw w ogóle nie działało, bo spieprzyłem paczkę z Erlangiem dla PLD (oczywiście już poprawiona), a potem się rozłączało zaraz przy próbie połączenia — potrzebny był patch na Erlanga, do którego namiary były w bug-trackerze ejabberd.