JJ i CIA

Napisali o mojej twórczości w Jabber Journal, ale moja
wrodzona skromność nie pozwala mi się tym chwalić. Więc się nie pochwalę
:-P

Aby moja sława nie zanikła postanowiłem też zadbać o regularne donosy do
CIA. Niestety na JabberStudio nie mam dostępu
do /CVSROOT/ i nie mogę bezpośrednio instalować commit-skryptów.
Mam jednak możliwość skierowania informacji od commita na dowolny JID lub adres
e-mail i z tej właśnie możliwości skorzystałem. Musiałem tylko napisać skrypt
do konwersji wiadomości z JS na XML zrozumiały dla CIA – niecała godzinka
roboty. Od dziś więc notowane będą moje commity nie tylko do
PLD,
ale także do:
PyXMPP,
CJC,
JJIGW
i
Transportu GG.

Na dwóch kółkach

Wczoraj wracając z wycieczki do Pławniowic przy płytostradzie
zauważyłem tablicę informującą, że w Brzezince jest ferma strusi. Strusie w
Gliwicach — uznałem, że to trzeba zobaczyć.

Dzisiaj więc wyciągnąłem z garażu naszego grata, żeby tam pojechać.
Właściwie to najpierw, z przyzwyczajenia, wyciągnąłem rowerek Krysi, ale
wsiadając się zorientowałem w pomyłce. W plecaku miałem już przygotowany zestaw
narzędzi, żeby móc coś zrobić jak rower się po drodze rozsypie. Do Brzezinki
dojechałem szybko, ale zdążyłem się przy tym nieźle zmęczyć — już chyba
ponad dwa lata nie jeździłem na rowerze. Przez Brzezinkę jechało się fajnie
— prawie cały czas w dół (strach mnie ogarniał na myśl o powrocie).

Dojechałem do końca Brzezinki i całych Gliwic za razem. Już było widać budowę
autostrady w Kleszczowie, a ja żadnego strusia jeszcze nie widziałem. Trudno,
trzeba wracać. Zatrzymałem się pod jakimś barem koło pętli autobusowej, żeby
kupić coś do picia. Rower postawiłem przed barem, przy dwóch innych tej samej
klasy (tam na wsi przynajmniej nie był to taki wstyd na czymś takim
jeździć) i kupiłem kolę. Potem zaczepiłem facetów przed barem, pytając Czy to
na serio są jakieś strusie?
. Oni na to, że to nie tu, tylko w Taciszowie.
Powiedziałem, że na tablicy pisało, że w Brzezince. Zaczęli coś mówić, że jakiś
X miał i może jeszcze ma. Pytali się po co mi one, czy chcę kupić. Ja, że tylko
obejrzeć. Nie uzyskałem zrozumienia z ich strony — To przecież takie
małe konie. Pierzaste.
. Drogi do X mi nie chcieli wytłumaczyć — To
w głębi osiedla. Nawet jakbym Panu wytłumaczył, to by Pan nie trafił
.
Trudno, tak bardzo mi na tych strusiach nie zależy — wycieczka jest fajna.

Nie chciałem wracać tą samą drogą, więc postanowiłem wjechać w głąb
Brzezinki. A nóż, widelec te strusie znajdę. Wjechałem w jakąś Sopocką.
Po przejechaniu kawałka zobaczyłem znak ślepa uliczka. Pomyślałem: ślepa
dla samochodu nie musi być tak całkiem ślepa dla rowerzysty. I rzeczywiście
— ulica się skończyła, to zaczęła się jakaś polna ziemna droga, nawet
biegnąca we właściwym kierunku. Więc pojechałem nią. Po kilkuset metrach z drogi
ziemnej zrobiła się trawiasta. Potem po prostu świeżo skoszona łąka. Ładnie tam
nawet było — pola, łąki, na prawo zabudowania Brzezinki, na wprost fabryki
Specjalnej Strefy Ekonomicznej (ładne one teraz są i nie smrodzą. Nie to co
kiedyś na Śląsku straszyło). Popodziwiałem widoki, posłuchałem skowronków i
postanowiłem jechać dalej. A właściwie iść prowadząc rower — kiepsko się
po trawie jeździ, szczególnie na wąskich oponach.

Łąka się skończyła, ale drogi ani śladu. Po lewej centrum dystrybucyjne
Lidla, gdzieś dalej po prawej domy, a przede mną haszcze. Ale ktoś już tędy
szedł, bo część chaszczy wydeptane. Nawet możnaby stwierdzić, że ktoś jak ja się
tamtędy z rowerem przedzierał. Trawy położone w jednym kierunku, a więc ten ktoś
nie wracał — wniosek: tam jest jakieś przejście. No to lezę w te
haszcze.

Haszcze coraz większe, miejsca między ogródkami, a siatką Lidla coraz mniej,
a wydeptana ścieżka znikła. Poza tym trzeba pamiętać, że na polskiej wsi
się szamb nie opróżnia, tylko zapewnia odpływ nadmiaru nieczystości do
najbliższej rzeki albo rowu. Kolor i zapach cieczy w rowie po lewej sugerował,
że mieszkańcy (wydawałoby się cywilizowani) domów po prawej kultywują tę
tradycję. Więc starałem się patrzeć pod nogi, żeby nie wpaść w cuchnącą
niespodziankę. W pewnym momencie haszcze były już wyższe od roweru (mógłbym go
tam łatwo zgubić), składały się głównie z pokrzyw, a miejscami też drzew i
krzaków. Zacząłem mieć wątpliwości, czy dalej da się wogóle przejść mimo, że
widziałem już ulicę przed sobą.

Udało się. Wydostałem się na jedną z wewnętrznych ulic Specjalnej Strefy
Ekonomicznej. Przy ulicy była ścieżka rowerowa (tam są wszędzie, pewnie
dlatego, że prawie nic poza tym tam nie ma). Stamtąd już bez problemu wróciłem
w nasze okolice. Dokładniej to do parku, gdzie już były moje dziewczyny. O dziwo
nie byłem nawet strasznie zmęczony, nawet mniej niż wtedy, gdy dojechałem do
Brzezinki. Pewnie odchoruję jutro.

WP Jellonki

Wiele już było na Joggerze (moim nawet nie) o Jellonkach.
Niektórzy sądzą, że problem dotyczy jedynie GG. Niestety, jest
znacznie gorzej. W GG zaczepiani są właściwie tylko Polacy,
a Jabber ma charakter międzynarodowy. Na razie jellonki atakują
głównie konferencje (rozmowy grupowe).

Jest sobie np. taki pokój
jdev@conference.jabber.org
— jest to miejsce spotkań developerów Jabberowych różnej
maści — autorów klientów, serwerów, usług — oraz
innych Jabberowców. W każdym razie rozmawia się tam głównie
o Jabberze i w języku angielskim. Ale dla przeciętnego (??, mam
nadzieję, że jednak nie) użytkownika WP Kontakt liczy się to, że
jest tam zawsze sporo osób, więc można pogadać. Oto przykłady
takich inteligentnych rozmów z ostatnich paru godzin:

[10:56]<arek19gliwice> dfjklvf vg
[10:56]<arek19gliwice> b
[10:56]<arek19gliwice> 12.13 150
[10:57]<arek19gliwice> 259
[10:57]<arek19gliwice> ]250
[10:57]<RyDeN> arek19gliwice: don't be silly please...
[10:57]<arek19gliwice> co?
[10:57]<RyDeN> stupid...
[10:58]<arek19gliwice> 
[11:00]<tomcio1> witajcie
[11:00]<arek19gliwice> czesc tomcio:)
[11:00]<arek19gliwice> b
[11:01]<arek19gliwice> a
[11:03]<arek19gliwice> y
[11:04]<arek19gliwice> a
[11:07]<arek19gliwice> n
	
[12:46]--- mackel has become available
[12:46]<mackel> cye
[12:47]--- mackel has left
[12:49]--- mackel has become available
[12:49]<mackel> cze
[12:49]<mackel> pogadamz
[12:49]<mackel> pogadamy
[12:49]<mackel> ??????????????????????????????????

Ten ostatni osobnik okazał się bardzo towarzyski i wykazał
działalność typowo jellonkową — zagadał do mnie na
priva:

[12:50]<mackel> cye
[12:50]<mackel> cze
[12:50]<mackel> ile masz lat
[12:50]<mackel> ???????????????????????
[12:50]<jajcus> a co Ciebie to obchodzi?
[12:51]<mackel> tak sie pytam

Problem nie jest nowy. Parę miesięcy temu nawet pisałem w tej
sprawie na abuse@wp.pl. Obiecali coś zrobić,
ale jest jeszcze gorzej niż było. Pewnie skończy się banem dla
*@wp.jabber.pl na wszelkie poważniejsze
konferencje. Na razie normalni użytkownicy pokoju próbują
odsyłać tych idiotów w lepsze miejsce do rozmów:

[11:26:40] <Alejka> Hi:)
[11:26:51] <stpeter> hi
[11:26:54] --- lisica19457 has joined
[11:26:57] --- lordceta has joined
[11:26:57] <stpeter> ?? pl
[11:26:57] <ChatBot> [pl]: See http://www.jabberpl.org/ -- for chat, join wroclaw@conference.jabber.org
[11:27:04] <lordceta> tu?
[11:27:20] <lisica19457> o widze że nasi tu są
[11:27:21] <Alejka> what's going down?:)
[11:27:30] <Alejka> :D
[11:27:37] <lisica19457> nom
[11:27:40] <lordceta> nasi tu byli
[11:27:45] <lisica19457> hehehe
[11:27:50] <stpeter> Alejka: this is a geek room -- Polish chat is in the wroclaw room
[11:27:56] <lisica19457> trzeba narobić zamieszania

Jak widać nieskutecznie. Po dłuższym czasie takiej rozmowy
skończyło się to tak:

[11:32:27] <lisica19457> WYJEBALI MNIE
[11:32:29] <deval> ?? pl
[11:32:29] <ChatBot> [pl]: See http://www.jabberpl.org/ -- for chat, join wroclaw@conference.jabber.org
[11:32:45] <lisica19457> HEHEHEHE
[11:32:52] <lisica19457> ALE FAJNIE NAPISAŁEŚ
[11:32:59] --- lisica19457 has left: [Banned] you have been banned
[11:33:11] <stpeter> lisica19457 has been banned from the room
[11:33:15] <stpeter> anyone else?

Nie widziałem podobnych nadużyć w innych językach. Niedługo wstyd
będzie się tam przyznać, że też jest się z Polski.

Obfalkać drzwi…

Gdy wychodziliśmy z Krysią na spacerek kichnąłem. Tak porządnie i w kierunku
drzwi sąsiadów. Krysię bardzo to rozśmieszyło. Zażartowałem, że obsmarkałem
drzwi sąsiadów
. Śmiała się jeszcze bardziej, powtarzając obfalkał
drzwi
. Później jej przeszło.

Gdy wracaliśmy, piętro pod naszymi drzwiami Krysia pociągnęła mnie w kierunku
drzwi, mówiąc: obfalkać drzwi!, ja na to nie obsmarkam drzwi sąsiadom,
ona: dzidzia obfalka!. Podeszła do drzwi i dmuchnęła nosem. Była bardzo
z siebie zadowolona.

A za chwilkę zabieram się za optymalizacją PyXMPP. Teraz w CJC jak napisze
/chat ktos@ i nacisnę dwa razy TAB, to ponad minutę muszę czekać aż
dostanę dwa pasujące JIDy do wyboru. Tak raczej być nie może. Myślę, że cache
JID-ów i wyników stringprep pomoże. Wcześniej muszę jednak z JID-ów
zrobić obiekty immutable i nie wiem czy dużo nie będę musiał poprawiać
(API się zmieni odrobinkę).

Porządki w kodzie i na Joggerze

Wywaliłem z PyXMPP wsparcie dla Pythona 2.2 i spróbowałem użyć modułu
datetime do obsługi timestampów. Okazało się, że jednak nie
rozwiązuje on moich problemów. Zapewnia interfejs do zamiany czasu
pomiędzy lokalnym a UTC, ale… tylko wtedy jak mu się poda klasy
reprezentujące odpowiednie strefy czasowe. A Python w module
datetime udostępnia jedynie abstrakcyjną klasę bazową.
Resztę trzeba sobie napisać. UTC to nie problem, ale przecież nie będę
pisał klas opisujących strefy czasowe wszystkich potencjalnych
użytkowników CJC! Jest gdzieś w sieci moduł zawierający gotowe klasy,
ale ja nie chcę dodawać kolejnej zależności, szczególnie, że przecież
w systemie już jest informacja o strefie czasowej użytkownika.

Zajrzałem do dokumentacji glibc, żeby zobaczyć jak się to w C robi. Jest
tam nawet potrzebna mi funkcja, nazywa się timegm,
ale:

*Portability note:* `mktime’ is essentially universally
available. `timegm’ is rather rare. For the most portable
conversion from a UTC broken-down time to a simple time, set the
`TZ’ environment variable to UTC, call `mktime’, then set `TZ’
back.

Fajnie, że podali przenośny sposób, ale zastosowanie jego w aplikacji
wielowątkowej to byłaby zbrodnia. A więc sposobu praktycznie nie ma.
Jednak nie będę przecież użytkownikom pokazywał czasu UTC, więc zacząłem
kombinować i nawet coś wykombinowałem: zamiana czasu UTC na lokalny
medodą kolejnych przybliżeń. Z moich testów — z czasem letnim
i zimowym z różnymi ustawieniami zmiennej $TZ
wynika że to nawet działa :-). Ciekawe jak bardzo
przekombinowałem.

Dzisiaj, nie mając wiele do roboty w pracy, urządziłem bug fixing
day
dla CJC. Poprawiłem już dwa błędy zgłoszone na JS oraz
kilka zgłoszonych przez Jabbera. Poczekam jeszcze na jakieś bugreporty
i może zrobię kolejne wydanie PyXMPP i CJC. MUC jeszcze dość
niekompletny, ale używalny, a wydać warto chociażby z powodu błędów
poprawionych w stosunku do 0.4.

Oprócz porządków w kodzie zrobiłem też porządki na Joggerze. Uzupełniłem
polecane Jogi o nowe pozycje i atrybuty title na linkach.
Usunąłem też linki erotycznie, ale nie dlatego że nagle sporządniałem
— po prostu nie chciało mi się ich uaktualniać. Poprawiłem jeszcze
ostatnią notkę — zamieniłem na w kilku
miejscach. Od dziś postaram się trzymać zasad typografii. Z poprawianiem
starszych notek byłoby za dużo roboty.

Zaginiona entropia i stary Python musi odejść

Wczoraj w firmie przeżyliśmy chwilę grozy. Zaczęło się niewinnie. Nie mogłem
commitnąć zmian w systemie zarządzania użytkownikami. svn commit
zawisał, strace pokazywało, że na dostępie do /dev/random. Nie
było to pilne, więc bardzo się tym nie przejąłem. Potem dzwonił gościu, że
poczty nie może odebrać. Chwila śledztwa wykazała, że zacina się na autoryzacji
DIGEST-MD5. Od razu skojarzyłem to z problemami z /dev/random.
Potem było już tylko gorzej — przy niedziałającym /dev/random posłuszeństwa
odmówił też PostgreSQL. A ja ciągle nie wiedziałem co się dzieje.
/proc/sys/kernel/random/entropy_avail pokazywało 0 i nie chciało
nawet drgnąć. Nie pomogło też wybicie procesów korzystających z /dev/random i
/dev/urandom. Wyglądało na to, że coś się zacieło. Ten serwer już długo działał,
a jeszcze nie było takich problemów.

Pomyślałem o sprzętowym generatorze liczb losowych — podobno niektóre płyty
takie coś mają. find /lib/modules -name "*rng*" pokazało dwa
moduły. Jeden (amd768_rng) miał nazwę podobną do chipsetu płyty.
Załadowałem i nawet działa — cat /dev/misc/amd768_rng pokazywało
krzaczki. Jednak aplikacje odwoływały się do /dev/random, a tam
dalej bez zmian. Spróbowałem ln -s /dev/misc/amd768_rng /dev/random
Permission denied, mv /dev/random /dev/random.orig — to
samo. Cholerny devfs – próbuje być mądrzejszy ode mnie! Zawsze lubiłem ideę
devfs — w /dev/ jest tylko to co mam w komputerze, a dysk o
konkretnym SCSI-id podłączony do konkretnego kontrolera ma zawsze tę samą nazwę,
a nie zależną od tego co jeszcze jest podłączone. Jednak implementacja jest
fatalne, a ten przypadek przeważył — devfs wyleciał z tego serwera. I tak
robiliśmy reboot, bo innych pomysłów nie było.

Po reboocie okazało się, że /dev/amd768_rng nie jest całkiem
zgodny z /dev/random — po podlinkowaniu niektóre aplikacje (w
szczególności SVN) zawisały przy próbie korzystania z tegoż. Jednak
/proc/sys/kernel/random/entropy_avail było już większe od zera,
więc problem chwilowo zniknął. Jednak nie na długo — entropy_avail
zaczęło się zmniejszać i znowu doszło do zera blokując wiele usług. Zamiany
/dev/random na /dev/urandom nie brałem pod uwagę – po
to używam SSL, SASL itp. żeby było bezpiecznie, a /dev/urandom bez
entropii generuje liczby bardzo pseudolosowe, a więc do kryptografii
niespecjalnie się nadające. Na szczęście kumpel znalazł winowajcę —
iptables -m random. Jedna taka regułka była w naszym firewallu i po
podłączeniu któregoś klienta najwyraźniej zabrakło na nią entropii. Po zamianie
tego na coś innego entropy_avail urosło do sensownej wartości i
wszystko zaczęło znowu działać. Ufff…

W PyXMPP i CJC obsługa MUC zaczyna działać. Można już wejść na takiego czata
i pogadać. Ale pierwszym felerem, który się rzuca w oczy, są niewłaściwe czasy
przy wiadomościach z historii pokoju. Jest tam czas aktualny, zamiast tego
podanego w <x xmlns="jabber:x:delay"/>. JEP-91 jest banalnie prosty,
więc postanowiłem go od razu zaimplementować. Oczywiste było, że przydałby się
typ opisujący czas, którego w Pythonie zawsze brakowało. Zwykle używałem
mx.Datetime, ale nie chciałem dla takiej dupereli do PyXMPP dodawać
kolejnej zależności. Więc użyłem modułu time, ale on jest do bani.
Można pobrać aktualny czas, przedstawić ją w postaci UTC, czy czasu lokalnego,
czy skonwertować tekst o znanym formacie na czas — ale tylko w czasie lokalnym.
Na zamianę czasu UTC w postaci tekstowej na czas lokalny nie znalazłem sposobu.
Poczytałem dokumentację — z niej wynikało że %Z w formacie
dla time.strptime czasem może działać — u mnie nie działa.
Pogooglałem i okazało się że moje wiadomości na temat braku typu dla czasu są
nieaktualne. W Pythonie 2.3 jest moduł datetime, który daje
wszystko co potrzebuję wraz z sensownym interfejsem. Dotychczas jednak PyXMPP
działało także na pythonie 2.2.x. Chyba przestanie — już dawno zastanawiałem się
nad porzuceniem wsparcia dla Pythona 2.2 — chociażby dlatego, że nie ma w nim
obsługi stringprep, czy IDN (oba standardy wymagane przez XMPP). Teraz PyXMPP
zawiera moją własną implementację stringprep dla Pythona 2.2 (wraz z wymaganą przez nią
normalizacją Unicode — to było sporo roboty), a IDN po prostu nie są obsługiwane gdy używany jest Python 2.2
(użycie znaku nie-ASCII w domenie JID powoduje bład). Ciekawe dla ilu
użytkowników takie podniesienie wymagań będzie dużym kłopotem. A może w ogóle
się tym nie przejmować? W końcu już teraz użytkownicy Debiana muszą kombinować,
żeby z PyXMPP skorzystać, bo standardowo mają historyczne wersje Pythona i
libxml2. Chyba jednak wywalę obsługę pythona 2.2 — kodowi wyjdzie to tylko na
dobre.

Co by tu…

Ostatni tydzień upłynął pod znakiem Crossfire.
Pisałem już że to niebezpieczny pożeracz czasu? No to piszę.
Czas na grę został zabrany na niekorzyść telewizji oraz snu.
Czasami wyglądało to tak, jakbym się z żoną prześcigał kto później
w nocy wymięknie. Żona wygrywała, ale to pewnie dlatego, że ona nie musi
o 6:20 wstawać do roboty.

W weekend w Gliwicach była Grająca Starówka – kilka różnych
koncertów w małych uliczkach w okolicach Rynku. Wybraliśmy się tam
z Krysią i w sobotę i w niedzielę. W sobotę wracaliśmy wcześniej –
odprowadziłem dziewczyny kawałek w kierunku domu, a sam poszedłem na
GNU/Browarek (w moim przypadku GNU/Kola). W niedzielę, też długo
nie siedzieliśmy, bo Krysia zaczęła marudzić. Powodem złego humorku był
chyba balonik, który jej mama kupiła. Krysia ostatnio zwykle dostawała
baloniki napełnione powietrzem, a teraz dostała latający. Niestety nie
doceniła. Szczególnie nie podobało jej się, że balonik został do niej
przywiązany. Za którąś zmianą miejsca zaczepienia stwierdziła Bim
bam! Bim bam!
(po polsku: kur.., kur…!) i wydawało się,
że się z sytuacją pogodziła. Jednak nie do końca i trzeba było wracać.
Dopiero w połowie drogi do domu przypomniała sobie, że Gra! i że
chciałaby jednak jeszcze posłuchać, ale było już za późno.

Mimo wszystko udało mi się znaleźć też odrobinkę czasu na moje
programiki. Przepisałem od nowa obsługę rostera w PyXMPP. Zmieniłem przy
tym API (a najlepsze, że nawet je udokumentowałem), ale stare było
niewygodne, a poza tym stary kod był wolny i zupełnie niezgodny ze
standardem jeśli chodzi o traktowanie znaków Unicode (zupełnie olewał
profile stringprep). Nowy kod w CJC niczego nie popsuł, a nawet naprawił
parę błędów.

Miałem też problemy z JJIGW, które od czasu do czasu zżerało 100% CPU na
serwerze. Postanowiłem to zbadać Pythonowym profilerem. Okazało się to
niełatwe. Profiler sam z siebie olewa wątki poza głównym. Dokumentacja
i Google nie wiele mówią na ten temat, ale jakoś udało mi się odpalić
tego profilera także dla innych wątków z zapisywaniem statystyk do
innego pliku dla każdego wątku. Znowu się potwierdziło że wątki
w Pythonie są mocno niedopracowane.

Wczoraj natomiast zacząłem implementować klienta MUC w PyXMPP. Jak
dobrze pójdzie, to niedługo będzie można używać CJC wraz z JJIGW
oraz innymi implementacjami MUC i będę mógł porzucić tkabbera.

SPAM na blogu – a fe!

Przed chwilą odebrałem powiadomienie o komentarzu do mojego Joga. Ucieszyłem
się, bo dawno nikt nie wykazał zainteresowania moimi wypocinami. Radość znikła
gdy obejrzałem komentarz. Zupełnie nie dotyczył on tematu, było tylko jakieś
Super strona i URL. Co gorsza URL przekierowujący do jakiegoś sklepu
z narkotykami. Czegoś takiego tolerować nie będę. Komentarz został skasowany,
IP (z internetdsl) zablokowany, a nadużycie zgłoszone do
abuse@telekomunikacja.pl. Zresztą, może powinienem reagować (mniej brutalnie
oczywiście) już przy pierwszych, niewinnych spamach – z adresem strony o
filmach.