Jakiś czas temu otrzymaliśmy list z zapytaniem jak prosto stworzyć sajt taki jak 7thguard. Jeśli czasu starczy, postaram sie przedstawić w sposób łopatologiczny stworzenie tego typu mikroserwisu. UWAGA: kod stanowi tylko przykład, jest brzydki, w ogóle nie przemyślany; nie zaimplementowano obsługi błędów (która nawiasem mówiąc zasługuje na oddzielny artykuł) i wielu, wielu innych rzeczy. Ma stanowić jedynie inspirację i ilustrację prostoty Pythona 😉
Założenia: po pierwsze, sajt musi być lekki. Sytuacja, w której PIII ze 128 MB RAM nie daje rady przy kilkudziesięciu równoczesnych odwołaniach (jak miało to miejsce na 7g zanim dorzuciliśmy nastepne 128 MB) jest niedopuszczalna. Po drugie – musi być lekki. Jego instalacja czy przeniesienie musi byc maksymalnie proste i możliwe dla zwykłego użytkownika. Wreszcie, musi być lekki: kod powinien być prosty i nieskomplikowany, by administrator mógł go znać na wylot.
Te „trzy lekkości” rozwiążemy następująco: po pierwsze, statyczny html będzie generowany tylko raz, po dodaniu newsa czy komentarza. Jest to o wiele bardziej wydajne rozwiązanie niż generowanie go w sposób dynamiczny za każdym razem; pozwala na postawienie serwisu na starym 486. Wadą jest sztywność: nie będzie możliwe dopasowanie go do upodobań użytkownika (możemy co najwyżej przygotować kilka statycznych wariantów). Po drugie, zbudujemy go tak, by można go było zainstalować w katalogu domowym użytkownika; nie będzie też korzystał z żadnych dodatkowych modułów Pythona. Osobiście wykorzystałem w tym celu serwer boa, niewielki i łatwy w obsłudze; dzięki temu autor serwisu nie jest uzależniony od dobrej lub złej woli administratora, który może lub nie musi pozwalać na strony domowe w katalogach domowych użytkowników, o możliwości uruchamiania skryptów CGI nie wspominając. Po trzecie: kod będzie zbudowany w Pythonie, przy wykorzystaniu CGI i – częściowo – bazy danych bsddb. Wszystkie skrypty znajdują się w jednym miejscu, zaś administracja serwisem i mechanizm działania uproszczone są do granic możliwości.
Pierwsza część poświęcona będzie stworzeniu serwisu od strony zewnętrznej. Jak często można zauważyć, serwisy tego typu mają zwykle artykuły oraz elementy rozpraszające, takie jak głosowania, newsy z grup dyskusyjnych itp, co sprawia wrażenie, że na serwisie wiele się dzieje. Nasz sajt będzie wyglądał następująco: główna, lewa częśc będzie zawierała artykuły, po prawej zaś będą newsy z grup dyskusyjnych i inne linki. Jeśli chodzi o layout, skorzystamy z pomocnego Open Source Web Design. W tym przykładzie wybrałem projekt z cieniowanymi ramkami. Oczywiście nic nie stoi na przeszkodzie, by skorzystać z bardziej graficznych layoutów, np. ze wspomnianego niedawno GUIStuff, czy nawet stworzyć własny 😉
Dodanie listy newsów jest bardzo proste dzięki pythonowemu modułowi nntplib. Wykorzystamy go do zrobienia listy newsów (zawierającej jedynie tematy wiadomości) dodamy też możliwośc ich czytania online. Tutaj przedstawię jedynie prymitywną wersję; jesli chcemy przekształcić ją w coś bardziej funkcjonalnego (jak NewsReader LN), będziemy musieli włożyć weń trochę pracy. Znacznie prościej jest zamieścić odnośniki np. do Google Groups czy NewsReadera.
Tutaj można obejrzeć kod modułu generującego indeksy dla grup dyskusyjnych (sam moduł tutaj ); jest napisany bardzo nieelegancko ale spełnia swoje zadanie. Dla każdej grupy tworzy plik z indeksem, który wykorzystamy później na głównej stronie, jak również plik z zawartością postów. Przykład zawiera jedynie ostatnie 10 wiadomości z danej grupy. Skrypt jest wywoływany okresowo, np. co godzinę.
Począwszy od
s = NNTP('news.tpi.pl', readermode='reader')
ma miejsce łączenie się i pobieranie nagłówków a następnie samych wiadomości z podanego serwera (news.tpi.pl należy oczywiście zastąpić czymś stosunkowo bliższym i szybszym). Jeśli grupa jest polskojęzyczna (pl.* lub alt.pl.*), dodawany jest nagłówek z iso-8859-2 (if ((group[:2] == 'pl') or (group[:6] == 'alt.pl')):file.write(polstopka)). Uwaga: nie są sprawdzane błędy!
Pora teraz na główną stronę. Główny plik podzielimy sobie na części odpowiadające początkowi i końcowi strony, jak również tabelkom z artykułami i newsami. Do próbnego wygenerowania pustego serwisu możemy posłużyć się tym skryptem (wersja do uruchomienia tutaj). Jego działanie jest banalne: Wkleja podany tekst w odpowiednie miejsca pliku html. Z zawartych w nim funkcji skorzystamy później, przy właściwym generowaniu stron. Jesli chodzi o ramki z newsami, wklejana jest do nich surowa zawartość plików z indeksami wiadomości z grup dyskusyjnych.
Teraz dodawanie newsów: w następnym odcinku zademonstrujemy dodawanie newsów do bazy, teraz zaś zajmiemy się jedynie podstawowym mechanizmem obsługi formularzy przez Pythona. Python posiada standardowy moduł cgi.py, w którym znajduje sie metoda FieldStorage(), która zwraca słownik z parami wartości z formularza.
Wykorzystamy ją następująco:
form = cgi.FieldStorage() print "Content-Type: text/htmlnn" print make_header() print make_article("Tytuł","Rodzaj",form["news"].value, form["name"].value,time.ctime(time.time())) ...
Tak wygląda dodawanie newsa:
A tak news „dodany”:
(właściwe dodawanie newsów zostanie omówione w kolejnej części).
Czasem zdarza się, że skrypt nie działa, a „Server Error” wiele nie mówi. Dlatego jeśli coś idzie źle warto dołączyć na początku skryptu linijki
sys.stderr=sys.stdout print "Content-Type: text/plainnn"
dzięki którym błąd znajdzie się w źródłach strony.
Archiwum z kodem całej „witryny” można znaleźć tutaj.
Archiwalny news dodany przez użytkownika: arturs.
Kliknij tutaj by zobaczyć archiwalne komentarze.