Zaloguj się

Jog Jajcusia

xmpp:jajcus@jajcus.net

Kalendarzowo

Ja mam pamięć dobrą, ale krótką – jak to mój tata mówi. Potrafię zapomnieć o wszystkim, jak mi się w porę nie przypomni. Pół biedy jak zapomnę, że właśnie posłodziłem herbatę i wrzucę kolejne trzy łyżeczki (serio, zdarza mi się), gorzej jak się np. z kimś umówię, a potem nawalę.

Dlatego zawsze ciągnęło mnie trochę do elektronicznych przypominaczy. Jednak zwykle i tak nie znajdowałem dla siebie nic odpowiedniego. Nie może to być coś, do czego miałbym ciągle zaglądać (dlatego odpadają papierowe terminarze), najfajniej by było, jakby nie trzeba było nawet tam nic wpisywać (ale tego to już się raczej nie przeskoczy)... Dobrze, żeby wpisać można było wszystko, i przypominać o ważnych sprawach mogłoby to mi zawsze i wszędzie (no chyba, że śpię – budzić mnie nie może)...

Próbowałem paru kalendarzy komputerowych. Kombajnów typu Evolution nawet nie tykałem – do poczty mam mutta, a nie kalendarz! W ogóle chciałem uniknąć GUI – uruchomienie Xów nie powinno być wymagane dla przypomnienia o ważnej sprawie. Z drugiej strony... jak już te Xy mam odpalone (zwykle mam), to fajnie jakby przypomnienie było w jakimś okienku... Konsolowe programiki tego typu miały jeszcze jeden feler – jakiś własny format danych niekompatybilny z niczym. Właściwie obsługa czegoś takiego niewiele się różniła od obsługi crontaba – do sensownego używania trzebai by sobie to nieźle oskryptować. A ja przecież chciałem coś, co by mi samo przypominało, a nie wymagało programowania...

Oczywiście praktycznie wszystkie rozwiązania oparte o komputer miały pewną wadę: mogły mi o czymś przypomnieć tylko wtedy, gdy akurat byłbym przy komputerze. Czasem nawet wymagały, żeby je specjalnie uruchomił. Dlatego doceniłem aplikację kalendarza w telefonie. Wtedy to był jakiś pierwszy Sony-Ericsson. To była pierwsza przypominajka, którą w miarę regularnie używałem. Jakieś wizyty u dentysty itp. tam wpisywałem. Potem, w dużo prostszym Samsungu X200 też. Już wtedy uznałem, że fajnie byłoby komórkowy terminarz synchronizować z komputerowym, ale szybko się przekonałem, że raczej nic mi z tego nie wyjdzie. Po pierwsze wciąż brakowało mi odpowiedniego kalendarza w komputerze, a po drugie wymiana jakichkolwiek danych między tym Samsungiem a Linuksem była praktycznie niemożliwa (odniosłem umiarkowany sukces jedynie w przypadku książki adresowej).

Używając sobie po trochy komórkowego kalendarza wciąż kombinowałem z kalendarzami w komputerze. Gdy usłyszałem, że Google Calendar potrafi wysyłać SMSy, to postanowiłem to wypróbować. Nie bardzo mi się podobało, że swoje plany, czy wręcz rozkład dnia, miałbym publikować w sieci, ale coś za coś. Wyglądało na to, że w tej aplikacji Google mógłbym łatwo wprowadzać swoje terminy, a przypomnienia przychodziłyby mi na komórkę. Przy okazji dostałbym parę łebdwazerowatych bajerów, jak publikacja kalendarzy, czy rozsyłanie terminów do znajomych. Przez jakiś czas się tym bawiłem, powpisywałem różne terminy... czasem dziwne rzeczy z tego wychodziły (aplikacja nie działała idealnie). A najgorsze było to, że Google potrafiło mi wysyłać SMSy w środku nocy, co było dość nieprzyjemne, gdy zapomniałem wyłączyć telefon... No i aplikacja webowa, to nie to, co tygryski lubią najbardziej.

Jakiś czas później trafiłem na ogłoszenie o nowym wydaniu Sunbirda. Pomyślałem sobie, że to może wreszcie będzie jakaś użyteczna aplikacja kalendarzowa pod Linuksa. Trudno, że GUI. Przynajmniej używa jakiś otwartych standardów... i nawet jest wtyczka do Google Calendar. Zainstalowałem sobie więc tego słonecznego ptaszka i zasubskrybowałem swój googlowy kalendarz. Rzeczywiście dało się tego używać. Żeby nie publikować wszystkich swoich spraw w Google zrobiłem sobie dodatkowy lokalny kalendarz. Potem z lokalnego zrobiłem sieciowy (opublikowany przez WebDAV na moim serwerku), bo przecież nie z jednego komputera korzystam. Pobawiłem się trochę... i jakoś nie zacząłem regularnie z tego korzystać. Jak coś było na tyle ważne, że potrzebowałem przypomnienia, to i tak wpisywałem w komórkę. Dla innych spraw nie chciało mi się kalendarza odpalać.

W końcu kupiłem sobie nową komórkę. Już wybierałem pod kątem obsługi jakiś standardów wymiany informacji. Zakładałem, że taką nowoczesną komórkę, obsługującą standardy łatwo ze swoim Sunbirdem zsynchronizuje. Rzeczywistość okazała się niestety nie taka piękna. Do sychronizacji takich urządzeń pod Linuksem jest właściwie tylko OpenSync (inne aplikacje zwykle korzystają z tej biblioteki), a ja nieźle musiałem się nagimnastykować, żeby tym jakiekolwiek dane między komputerem a telefonem wymienić. A przy synchronizacji kalendarza znikały z terminów informacje o przypomnieniu, czyli to, co dla mnie najważniejsze. Zgłosiłem swoje problemy na odpowiednią listę mailową i nic. Nie wygląda, żeby w tej kwestii miało się coś zmienić.

Nie poddałem się jednak. Skoro telefon ma funkcje synchronizacji, to musi się dać to wykorzystać. Jest funkcja synchronizacji online, może to się nada? Najpierw sprawdziłem Google Calendar, przecież taka aplikacja, takiej poważnej firmy musi mieć taką funkcjonalność... gdzie tam. Wygląda na to, że Google SyncML zignorowało. No to rozejrzałem się za jakimiś publicznymi serwerami SyncML. Spośród paru kandydatów najbardziej przekonało mnie ScheduleWorld. Po poprzednich doświadczeniach miałem spore wątpliwości czy to zadziała, ale spróbowałem... i zadziałało.

Teraz na komputerze mam Sunbirda, w nim swój sieciowy kalendarz i wtyczkę (rozszerzenie) ScheduleWorld. Jak dodam na komputerze termin i wcisnę sync, to po uruchomieniu synchronizacji w telefonie i tam się ten kontakt pojawi. Tak samo w drugą stronę – kontakt dodany w telefonie pojawi się na komputerze. Zachowane są przy tym informacje o przypomnieniach. Był jeden problem – zdarzenie wpisane w komputerze na całą dobę w telefonie było widoczne jak dwudniowe (od 00:00 jednego dnia, do 00:00 drugiego dnia). Okazało się jednak, że wystarczy zaznaczyć jedną opcję w ScheduleWorld i problem zostaje rozwiązany. Jest tam też sporo innych przełączników, umożliwiających ominięcie potencjalnych problemów z innymi urządzeniami.

Do pełni szczęścia brakowało mi jeszcze jednej funkcji – jakieś minimum funkcjonalności bez potrzeby odpalania Xów. No to napisałem sobie Pythonowy skrypt, przy użyciu biblioteki icalendar, który wyciąga dzisiejsze i jutrzejsze terminy z mojego kalendarza (niech żyją otwarte formaty plików!). Lista ta jest wyświetlana przy logowaniu. Wydaje mi się to rozsądnym sposobem przypominania mi o rzeczach, dla których alarm z telefonu byłby przesadą.

No to wydaje mi się, że już mam użyteczny zestaw, z którego będę w stanie regularnie korzystać. Jedyna słabość, to publiczny serwer, który pośredniczy w synchronizacji z komórką... no cóż, czasem można poświęcić odrobinę prywatności dla wygody. I chyba nie mam zbyt dużych powodów, żeby ScheduleWorld nie ufać.

Teraz pytanie: czy rzeczywiście będę z tego wszystkiego korzystał, czy dalej tylko raz na ruski rok coś sobie w komórkę wklepię?

6 komentarzy do wpisu „ Kalendarzowo”


Praca dla pythonowców

Podobno mogą mnie czytać jacyś miłośnicy Pythona, więc kolega mnie poprosił o podlinkowanie ogłoszenia. Proszę bardzo, może rzeczywiście komuś się przyda:

Praca Python Django Warszawa - praca stała

Sam bym się zainteresował tą ofertą, gdyby nie ta Warszawa...

2 komentarze do wpisu „ Praca dla pythonowców”


Committed revision 666.

Mam dosyć sztywnego trzymania się niektórych zasad dobrego stylu programowania. Pisząc CJC starałem się w ogóle nie używać zmiennych globalnych, bo przecież każdy wie, że tak trzeba. No i dało się, jednak z tak zrobionego kodu nie byłem zadowolony. Mam tam takie trzy obiekty, właściwie singletony, do których dostęp potrzebny był w bardzo wielu miejscach. No i dostęp ten odbywał się właściwie na dwa sposoby: albo referencja do takiego obiektu była przekazywana w konstruktorze i potem zapisywana w atrybucie obiektu który tego potrzebował, albo dostęp odbywał się przez inne obiekty (np.: self.plugin.app.screen) – jedno i drugie nie wyglądały najlepiej. Standardowym, Javowe, rozwiązanie, w postaci statycznej metody zwracającej instancję singletona, niespecjalnie mi pasowało – to takie niepythonowe odwoływać się do klasy, gdy tylko jej instancja jest potrzebna. Do tego to więcej pisania by było, a przecież miałem API uprościć.

W końcu zdecydowałem się na rozwiązanie proste i skuteczne – zrobiłem moduł cjc_globals z trzema zmiennymi globalnymi. I wszystko byłoby dobrze, gdyby nie komunikat przy commicie, wyraźnie sugerujący, że za moją decyzją stoi Zło: Committed revision 666. ;-)

6 komentarzy do wpisu „ Committed revision 666.


Pythonowe frameworki...

(wpis z wczoraj)

Pierwszy Pythonowy framework dla aplikacji webowych jaki poznałem to był Zope 2. Potrzebne mi było coś takiego do stworzenia interfejsu użytkownika dla naszego systemu zarządzania siecią. W PHP babrać się nie miałem zamiaru, a robienie całości jako CGI to byłaby mordęga. Padło na Zope'a, nic innego nie było, a przynajmniej nic na tyle popularnego, żeby obiło mi się o uszy. Zope, z jednej strony potężna maszyna, z drugiej wkurzające monstrum. W szczególności, że źle się za niego zabrałem. Wszystkie szablony robiłem w DTML (bo wyczytałem w ZopeBook, że równie dobrze jak ZPT, a dla programistów nawet lepsze), a cały kod rozwijałem through the web, a więc to było bardziej skryptowanie a'la PHP, niż poważne tworzenie aplikacji. W końcu przekonałem się do ZPT (bardzo porządny język szablonów, pozwalający w miarę dobrze oddzielać logikę od prezentacji i utrudniający tworzenie niepoprawnego XHTML), ale kod dalej rozwijany jest TTW, bo zmiana tego, to byłoby pisanie aplikacji (sporej już) od zera.

Widząc słabości Zope zacząłem się rozglądać za alternatywami. Żeby alternatywę poznać to trzeba spróbować, postanowiłem więc pobawić się czymś innym. Po wstępnym rozpoznaniu tego co jest na rynku, postanowiłem spróbować od CherryPy. Próba polegała na przeportowania mojego generatora i przeglądarki statystyk dla Joggera (ta czerwona kropa poniżej) na ten framework. Wcześniej to było zrealizowane w postaci skryptów CGI z prymitywnymi printami. Zrezygnowałem z języka szablonów wbudowanego w CherryPy, bo znając ZPT nie chciałem się babrać w czymś nie opartym o XML (nie pilnującym składni generowanego kodu), użyłem więc SimpleTAL. Sportowałem tak dużą część tego generatora statystyk, z błędami i dałem sobie spokój (zająłem się innymi rzeczami). CherryPy na początku zrobiło niezłe wrażenie jak prosto się w tym aplikację WWW buduje, a potem okazało się raczej prymitywne. Architektura CherryPy wręcz wymuszała bałagan, zamiast porządkować kod (to IMHO jedna z funkcji frameworków) — na dłuższą metę reprezentacja hierarchii URL poprzez atrybuty obiektów to niezbyt dobry pomysł. Do tego stan aplikacji (aktualne żądanie, odpowiedź, etc.) trzymany w zmiennej globalnej (i dostępny przez tę zmienną)... wiem że to działa, ale wydaje się niezbyt eleganckie. Krótko mówiąc CherryPy mnie nie zachwycił.

Kolejny był Nevow, oparty o Twisteda. Od początku wydawał się bardziej skomplikowany niż CherryPy. Ale po doświadczeniach z prostotą (prymitywizmem) CherryPy to mnie nie zrażało. Nevow intensywnie korzysta z interfejsów i adapterów (jak się później okazało, zapożyczonych od Zope3), ma własny, ciekawy język szablonów — oparty o XML i jeszcze bardziej niż ZPT oddzielający prezentację od logiki (w szablonach nie ma nawet pętli). Portowanie prostego CGI do Nevowa to była droga przez mękę, bo trzeba było się nauczyć nowego, skomplikowanego narzędzia. Niektóre rzeczy w tym frameworku okazywały się ostatecznie proste i logiczne, przy innych trzeba było się nakombinować. Doprowadziłem conieco (prezentację listy wejść) do działania, ale nie rozwiązałem wszystkich problemów i walka z Nevow mi się znudziła. Ostateczne wrażenie raczej pozytywne, chociaż miejscami było pod górkę. Doceniłem też wsparcie na IRCu.

Jakiś czas temu na grupie pl.comp.lang.python przeczytałem sporo dobrego o Zope3. Wtedy to było jeszcze eksperymentalne Zope-X3. Framework przepisany od zera, docelowo mający zapewniać częściową kompatybilność wstecz (czy raczej wsparcie dla portowania starych aplikacji) z Zope2. Co do tego że Zope należało przepisać od zera, nie miałem wątpliwości. W to, że w Zope krył się potencjał też. Więc, gdy pojawiły się release candidate Zope 3.1, postanowiłem spróbować. Poczytałem dokumentację, zacząłem łapać o co w tych interfejsach i adapterach (dużo intensywniej używanych niż w Nevow) chodzi i zabrałem się za portowanie statystyk. Znowu początki były ciężkie, ale prawie na każdy problem Zope oferował jakieś fajne rozwiązanie. Wszystko w postaci przejrzystego obiektowego podejścia. W przeciwieństwie do takiego CherryPy Zope3 zachęca do porządku i przemyślenia co jest obiektem, co jego prezentacją. Daje potężne mechanizmy kontroli dostępu, bezpieczeństwa kodu, i18n, skórkowania, tworzenia i walidacji formularzy i wielu innych rzeczy które w aplikacji są potrzebne. Jest to architektura i zestaw narzędzi, czyli to czym framework powinien być. I się sprawdza. Dzisiaj skończyłem portowanie statystyk i efekt jest lepszy niż oryginał, a ewentualny dalszy rozwój będzie banalnie prosty (prostszy niż w przypadku CGI).

Już po rozpoczęciu swojej zabawy z Zope3 stwierdziłem, że warto to zastosować w firmie zamiast Zope2. Większość systemu (interfejs administratora, serwisu, BOKu) zostanie na starym Zope'ie, bo przepisanie tego to znowu byłoby wiele miesięcy, ale już interfejs użytkownika końcowego robię na Zope3. Tego jest niewiele i i tak muszę to przepisać od zera. Obie części komunikują się przez bazę danych i chodzą na różnych maszynach, więc zastosowanie dwóch Zope'ów nie jest problemem. Mam nadzieję, że tej decyzji nie będę za jakiś czas żałował, jak tego, że wpakowałem się z Zope2 i aplikację rozwijaną TTW. No i to, że w ogóle wpakowałem się w kodowanie zamiast adminowania...

Jest jeszcze wiele innych frameworków i, do tego, ciągle powstają nowe. Części w ogóle nie znam, o części poczytałem w sieci i zrezygnowałem, bo ich założenia mi nie pasowały. Niektóry zdawały się zbytnio iść w kierunku PHP, którego przecież celowo unikam, inne miały jakąś dziwną architekturę, np. Webware składające się z iluś komponentów, w których nie udało mi się ujrzeć spójnej całości. Ciekawe co wygra — na świecie i wśród moich narzędzi.

21 komentarzy do wpisu „Pythonowe frameworki...”


Coś dla nieprzekonanych do dynamicznego typowania

Natrafiłem dzisiaj na artykuł Bruce'a Eckela Strong Typing vs. Strong Testing. Autor, znawca języków programowania, znany autorytet w tej dziedzinie (autor słynnej książki Thinking in Java), opisuje w nim jak przekonał się do dynamicznego typowania mimo, że wcześniej za jedyne słuszne uznawał statyczne systemy typów. Oczywiście język z dynamicznym typowaniem, którym się zachwyca, to Python. Interesująca jest też kontynuacja tematu — odpowiedź na list profesora, który z poprzednim artykułem się nie zgadza. Blog Bruce'a Eckela dodałem do linkowni — czuję, że będę tam często zaglądał.

Miłe jest, że do Pythona przekonuje się coraz więcej znawców poważnych języków i miłe jest, że potrafią opisać czemu Python jest taki dobry — zawsze to kolejne argumenty do przekonania nieprzekonanych. Co do statycznego typowania, to też nie uważam tego za coś niezbędnego, ale raczej, że w większości przypadków przeszkadza, jednak nie jestem też przeciwnikiem wprowadzenia takich, opcjonalnych oczywiście, rozszerzeń do Pythona. Dobrze czasem jest mieć możliwość zaznaczyć w kodzie dla jakich argumentów jest on przygotowany. Często jest to istotna informacja dla innych developerów (ale tu wystarcza odpowiednia dokumentacja) i dla interpretera/kompilatora (pozwala na lepszą optymalizację krytycznych elementów kodu). Problem polega na tym, żeby wprowadzić to nie psując przejrzystości i elastyczności języka i aby nie było to nadużywane.

16 komentarzy do wpisu „ Coś dla nieprzekonanych do dynamicznego typowania”


PyXMPP — coraz poważniej

Zrobiłem w końcu stronę WWW dla PyxMPP. To dopiero początek, ale na jakiś czas powinno starczyć. Zacząłem też robić zestawy testów jednostkowym (opartych o PyUnit — moduł unittest) do testowania całości. Na pierwszy ogień poszło pyxmpp.jabber.vcard do którego już jakieś testy były i trzeba było je tylko przerobić na PyUnit i uzupełnić. Oczywiście wyszło parę błędów, które poprawiłem. Później pyxmpp.jabber.disco, w którym chciałem uzupełnić API, testy miały mi pomóc zrobić to tak, żeby nic nie zepsuć. Pomogły, a przy okazji poprawiłem w testowanym module sporo błędów. Ogólnie fajna rzecz takie testy i wbrew pozorom nie tak bardzo upierdliwa (mniej niż uzupełnianie docstringów).

Dzisiaj zrobiłem jeszcze małą rewolucję. Wkurzało mnie już to, że importowanie jakiegokolwiek modułu z pyxmpp powodował importowanie całości (prawie). Wynikało to z tego, że dla wygody developerów pakiet pyxmpp importował najważniejsze obiekty ze swoich modułów. Od dłuższego czasu głowiłem się na tym, jak to rozwiązań nie tracąc tej wygody i nie psując za bardzo kompatybilności wstecz i w końcu coś wymyśliłem. Teraz samo z siebie nic niepotrzebnie się nie importuje, ale jak ktoś chce po staremu, to wystarczy że raz sobie zaimportuje pyxmpp.all, i/lub pyxmpp.jabber.all albo pyxmpp.jabber.all (jeśli któregoś z nich używa). W ten sposób chyba i wilk syty i owca cała.

Następnie zabrałem się za CJC. Wkurzało mnie długie ładowanie konfiga, okazało się, że to przez częste wywoływanie logging.debug() — wywaliłem i jest lepiej. Potem postanowiłem porawić pewnego upierdliwego i często zgłaszanego buga — część wpisów w rosterze pojawiało się przed zamiast za nazwą grupy. Okazało się, że porównywanie JIDów z innymi obiektami było w PyXMPP spieprzone i niektóre JIDy były mniejsze od None. I znowu testy jednostkowe się przydały, a zgłoszenie mogłem zamknąć.

I po cholerę to wszystko piszę? Nie wiem... może, żebyście wiedzieli jak wygląda prawdziwie geekowski sylwester... Nie, żebym nie imprezował — specjalnie z tej okazji mam tu colę (z cytrynką) i chipsy ;-).

9 komentarzy do wpisu „ PyXMPP — coraz poważniej”



[szpieg] Jesteście obserwowani...