strona główna

Archive for the 'serwis w tydzień' Category

Django na TechAuli

Friday, June 27th, 2008

Na dzisiejszej TechAuli opowiedziałem o Django – dlaczego jest fajne, szybkie i warto używać. Były trafne i ciekawe pytania z sali, być może też udało mi się namówić kilka osób do wypróbowania go w praktyce, więc prezentacja wyglądała na udaną.

Oiola.com - nowa wersja

Wednesday, June 4th, 2008

Od dzisiaj na oiola.com można zobaczyć efekty ostatnich dwóch miesięcy pracy: dużo zmian, pełen spis na Oiola-blogu.

Tym razem, pomimo szczerych chęci, więcej kodu napisałem niż znalazłem. Jedyny nowy moduł znaleziony w sieci to strip-o-gram – sensownie działający konwerter z HTML na czysty tekst, przez Oiolę wykorzystwany podczas wysyłania poczty (od teraz można dowolnie zmieniać tekst powiadomień i wysyłać listy do uczestników bezpośrednio z oiola.com).

Z ciekawostek: w tej chwili Oiola, w części serwerowej, to 5433 linie kodu, z czego 2329 to testy – ta część serwisu, która zajmuje się tylko i wyłącznie sprawdzaniem, czy reszta działa poprawnie – więc sama aplikacja to 3104 linie. Wykorzystałem biblioteki zawierające w sumie 22543 linii, nie licząc samego Django i oczywiście biblioteki standardowej Pythona, co oznacza że zdecydowaną większość kodu napisał i zdebugował już ktoś inny. I to właśnie jest podstawa szybkiego tworzenia aplikacji: platforma, dla której istnieje mnóstwo bibliotek tak wysokiej jakości :)

Komiksy w sieci

Friday, February 15th, 2008

Wczoraj wieczorem dokręciliśmy ostatnie śrubki w drugim z cyklu
projektów-w-tydzień. Tym razem z lekkim poślizgiem, w planach
mieliśmy zamknięcie prac w zeszłym tygodniu, w praktyce –
rzeczywiście intensywne prace zaczęliśmy w piątek, skończyliśmy
wczoraj (środa). Pierwszy
użytkownik
powoli kończy przeprowadzkę.

Nowy serwis to WebComicsPot,
narzędzie do możliwie prostego publikowania w sieci komiksów, także
wielojęzycznych. Założenia były takie: samo umieszczenie plansz w
sieci jest proste i tanie, kłopotem jest za to złożenie sensownego
interfejsu pozwalającego na ich przeglądanie i przełączanie się między
tłumaczeniami. WebComicsPot rozwiązuje właśnie ten kłopot.

Jak w favpico, obsługa jest
uproszczona do granic możliwości: autor podaje tylko listę adresów pod
którymi znajdują się kolejne plansze. Serwis zakłada, że każdy adres
zawiera datę w formacie RRRR-MM-DD. Dodatkowo możliwe jest wklejenie
w stronę komiksu swojego kodu HTML i dodanie arkusza styli CSS.
Jednocześnie, to jest nasz pierwszy serwis wspierający OpenId – koniec z
wymyślaniem kolejnych haseł :)

Coś o stronie technicznej i organizacyjnej; zaletą tak małych
projektów jest to, że można w krótkim czasie sprawdzić w praktyce
sporo nowych narzędzi: jeśli się sprawdzą to świetnie, jeśli nie – to
upośledzają tylko jeden drobny projekt, nie ma sensu go przepisywać.
Tym razem znalazłem sporo przydatnych rzeczy.

Django-authopenid
zachowuje się bardzo sensownie, wymagała tylko drobnych poprawek
(które muszę jeszcze spakować w jeden sensowny diff i wysłać).

Instant Django to
świetny sposób na udostępnienie serwisu nieprogramiście
(np. grafikowi) pod Windows – zawiera, w jednej paczce, 2.5, django, sqlite, dość sensowny edytor tekstu i
parę skryptów które odpowiednio konfigurują środowisko. Wystarczy
dodać skrypt uruchamiający serwer (z syncdb przed startem), nauczyć
grafika korzystać z TortoiseSVN
i już, właśnie załatwiliśmy stronę techniczną współpracy.

FeedParserFeedJack – świetne biblioteki do
obsługi RSS, używałem
ich już wcześniej w Planemoo. Tym razem FeedParser przydał się też do
czyszczenia kodu HTML wpisywanego przez autora komiksu: ze względów
bezpieczeństwa serwis usuwa część konstrukcji.

Cssutils
– podobnie jak w przypadku HTML, możliwość wpisania
dowolnego kodu CSS to dziura bezpieczeństwa ze względu na @import i
javascript w adresach. Sam cssutils nie potrafi tego wyczyścić, ale
wystarczyło utworzyć własną podklasę CSSSerializer, żeby usunąć i
@import, i podejrzane adresy:

 
URL_WITH_CALL_RE = re.compile(r'^url[(]["\']https?://\S+$')
 
class SanitizingSerializer(cssutils.CSSSerializer):
    """
    Overrides some stuff in CSSSerializer to make it safer.
 
    1. disallow ALL URLs not starting with 'http://' or 'https://'
    2. remove @imports
    """
 
    def do_css_CSSValue(self, cssvalue):
        if cssvalue and isinstance(cssvalue, CSSPrimitiveValue):
            if cssvalue.primitiveType == CSSPrimitiveValue.CSS_URI:
                if not URL_WITH_CALL_RE.match(cssvalue._value):
                    return u'url("")';
        return super(SanitizingSerializer, self).do_css_CSSValue(cssvalue)
 
    def do_CSSImportRule(self, rule):
        return u''
 
cssutils.setSerializer(SanitizingSerializer())
 

Django zawiera bibliotekę do komentarzy, bardzo przydatną ale z
paroma ograniczeniami; przeszkadzał mi, przede wszystkim, ścisły
rozdział komentarzy użytkowników zalogowanych i anonimowych, w
praktyce uniemożliwiający dyskusję między jednymi a drugimi. Tutaj
poszukiwania innej biblioteki niestety nie dało rezultatu, trzeba było
dostosować django.contrib.comments.

Drobiazg, ale jak przydatny: slughifi zamienia "zażółć gęślą jaźń"
na "zazolc-gesla-jazn", więc jest wersją funkcji slugify, mądrzejszą o
znajomość wielu znaków narodowych, w tym cyrylicy.

Musiałem też nieco rozbudować własną bibliotekę do obsługi tłumaczeń,
django-multilingual;
eksperymentalne zmiany okazały się bardzo przydatne więc niedługo znajdą
się też w wersji publicznej.

Napisałem też trochę kodu wspomagającego testy modułowe Django,
teraz duża część moich testów wygląda tak:

 
def test_adding_a_comic(self):
    self.login()
    self.get('/')
    self.click('m-your-account')
    self.click('publish-now')
 
    self.click('cancel')
    self.assertLocation('/account/ed/')
 
    # okay, now go and publish it
    self.click('publish-now')
    self.assertContains(self.response, 'name="short_name"')
    self.assertContains(self.response, 'name="main_language_id"')
    self.assertContains(self.response, 'name="add" value="save"')
 

Gdzie 'm-your-account' i 'publish-now' to identyfikatory (nie tekst!)
odsyłaczy na stronie; oczywiście każdy click przechodzi do strony
wskazywanej przez dany odsyłacz. Pozwala to łatwo przetestować całe
sekwencje zdarzeń, i to w sposób niezależny od aktualnie włączonej
wersji językowej interfejsu.

A za miesiąc, wszystko na to wskazuje, coś bardziej skomplikowanego :)