w maju po raz wtóry odwiedziłem Debreczyn, wydarzenia podczas tego spotkania były początkiem lawiny, która zakończyła moją półtoraroczną pracę w SensiSofcie;
Recently I had to make a widget for Django admin to display movies (H.264 encoded, MPEG-4 and FLV). We already have a widget for displaying the movie inline within the admin change form, but I had to create a widget that opens separate entity (lightbox-like overlay or popup browser window). For a start I took the popup browser — this seemed easier because one of the requirements was that the movie player will not load with the page (I am not that good in javascript, mind you...). What it takes to have a widget that shows some content in separate browser window?
you can open window by manually appropriate javascript code, but I prefer to use some ready-made plugin for jQuery, like jquery-popupwindow;
you'll need Django view (and template) that displays actual page with embedded player;
to embed the player (which is Flash object) you'd need swfobject and the player itself, like JW Player (it plays both mp4 and flv movies — but watch out, it's free only for strictly non-commercial use);
a Django's forms widget that will have something that can be clicked to open new window.
Now for the fun part: actual code. The widget code is a mish-mash of my previous experiences in writing custom Django widgets:
The code above produces a widget that has a clickable link with the title of movie URL. The anchor is linked to the URL of the view that produces HTML to display, like the code below:
The only variable that is passed in the context is the URL of the movie, but you are free to include as much as you'd like. Of course, nothing forces you to use urls, you can call the view with a PK to the movie-holding object, but this will require changes to the above view code.
But that's not all. You have to register your model in Django admin application. If you just register it with default modelform, the instances will display themselves with default admin widget. Two more classes are required:
class MovieAdminModelForm(forms.ModelForm):
movie = forms.FileField(widget=widgets.AdminPopupMovieWidget)
class Meta:
model = Movie
class MovieAdmin(admin.ModelAdmin):
form = MovieAdminModelForm
Jeff Atwood napisał kolejny tekst, który trafia do mnie, tym razem o ludziach, którzy nie powinni zajmować się programowaniem. Zarzewiem był pewien wątek na pewnym forum, w którym ktoś zastanawiał się nad opuszczeniem branży programistycznej. Trudno mi się z tym artykułem nie zgodzić — w końcu zajmuję się programowaniem od ponad 10 lat. W tej branży 10 lat to jak od epoki brązu do atomu.
Wielokrotnie w ciągu tych 10 lat spotykałem ludzi, którzy programowaniem zajmowali się tylko przejściowo, między studiami a pójściem w managery, na szczęście nie musiałem z nimi współpracować, więc nie napsuli mi wiele krwi. Zawsze jednak dziwiło mnie to, że najpierw poświęcili 5 lat na uczenie się inżynierii oprogramowania na studiach i potem przez 5 lat pisali kod tylko po to, żeby wreszcie wskoczyć na najniższe stanowisko w managemencie IT, mając w dodatku perspektywę, że od najwyższego stanowiska, które będą w stanie osiągnąć na normalnej drodze kariery, dzieli ich tylko jeszcze jedno. Coś mi się tu nie zgadzało: poświęcać 15 lat na to, by osiągnąć szczytowe stanowisko w branży? Przecież można je osiągnąć szybciej, powiedzmy w 10 lat. I co ważniejsze, co dalej? Co potem?
OK, w porządku, nie jestem w stanie myśleć tak, jak myśli 98% ludzi, uważających się za normalną większość — od ciągłego obcowania z komputerami (a pewnie i z powodu szczątków klasycznego wykształcenia) wszystko co robię musi być przemyślane i mieć sens. Artykuł Jeffa Atwooda jest oparty nie tylko na przemyśleniach, sporo w nim emocji, co bynajmniej nie odbiera mu wartości, bo dobrze określa tych, którzy zostają w branży jako ludzi, którzy po prostu kochają pisać kod. Dla niektórych dziwnie wygląda 40-letni programista, dla innych to człowiek, którego w zawodzie trzyma pasja (w ciągu tych 15 lat pracy w zawodzie na pewno trafiają się lepsze propozycje, choćby ze zwykłego rachunku prawdopodobieństwa to wynika).
Ja w każdym razie zostaję. Przez pewien czas próbowałem managerzyć i cieszę się, że już tego nie robię. Moja wątroba ma się lepiej, żona jest mniej nerwowa i jakbym siwiał trochę wolniej.
Do grzecznych dzieci w Wigilię przychodzi Mikołaj, więc i mnie nie ominął. ;)
Z jego przepastnego worka dla mnie przeznaczona była gra Filary Ziemi. Ostrzyłem sobie na nią zęby przede wszystkim ze względu na tytułowe skojarzenie z powieścią Kena Folleta, którą po prostu uwielbiam. Poczytałem kilka recenzji, obejrzałem sobie dokładnie instrukcję (można sobie ściągnąć PDF-a ze strony wydawnictwa, jak dla mnie bomba) i zdecydowałem się na wydatek 130 złotych (polecam zakup na Allegro.pl, można zaoszczędzić do 20 złotych w porównaniu do Empiku, w zwykłych sklepach internetowych cena z przesyłką jest porównywalna do Empiku).
Gra jest wydana po prostu prześlicznie i z wielką dbałością o szczegóły. Plansza wykonana tak, że mucha nie siada (podklejona na złożeniach, więc zapowiada się, że będzie również trwała), drewniane pionki, pięknie ilustrowane karty. Miałem prawdziwą przyjemność z dotykania tej gry i nawet z samego patrzenia na nią.
A potem spróbowaliśmy w to zagrać z żoną. Początek był dość trudny, bo dla osób które do tej pory grywały głównie w Monopol lub Scrabble reguły są bardzo skomplikowane, ale po dwóch rundach doszliśmy do pewnej wprawy i potoczyło się nieco szybciej. W różnychrecenzjach różnie się o tej grze wypowiadano, a ja mogę napisać tylko tyle, że wydała mi się dobrze zbalansowana (element losowy z elementem strategicznym). Jedyny mankament, jaki dostrzegłem, to trochę nadmierne faworyzowanie tzw. gracza rozpoczynającego (ma on pierwszeństwo w wykonywaniu różnych akcji, co daje mu pewną przewagę, np. przy wyborze surowców), ale może to specyfika gry w dwie osoby. Nie będę próbował zgadywać, czy się mojej żonie ogólnie podobało, ale widziałem u niej kilka momentów zadowolenia i przyjemności z gry. Gra toczyła się powoli i dopiero w ostatniej, VI rundzie przyspieszyliśmy — prawdopodobnie widok zbliżającej się mety tak na nas podziałał.
Było super. Podoba mi się ta gra. I polecam każdemu, choćby do spróbowania. Teraz czekam na rozgrywkę w większym gronie, w 3 lub w 4 osoby. A potem (zależnie od nastroju mojej głównej partnerki do grania) pewnie dokupię dodatek z nowymi możliwościami. :)
Take me to the station
And put me on a train
I've got no expectations
To pass through here again
Once I was a rich man and
Now I am so poor
But never in my sweet short life
Have I felt like this before
You heart is like a diamond
You throw your pearls at swine
And as I watch you leaving me
You pack my peace of mind
Our love was like the water
That splashes on a stone
Our love is like our music
Its here, and then its gone
So take me to the airport
And put me on a plane
I got no expectations
To pass through here again
Niedawno po prawej stronie pojawiło się kilka obrazków-linków. O ile dwóch z nich nie ma co opisywać, bo same się doskonale opisują, to link do XP-Dev.com wymaga kilku słów opisu (albo tylko tak mi się wydaje).
Jakiś czas temu chciałem się uniezależnić od mojego dostawcy hostingu w dziedzinie utrzymywania repozytorium z kodem tego serwisu (i paru innych przy okazji też). Przeszkadzało mi to, że współdzielenie dostępu do repozytorium polega na forwardowaniu portu przez SSH, jak dla mnie (i dla znajomych, którym chciałem dać dostęp do repozytorium) to mało wygodne. Zacząłem szukać miejsca, gdzie mógłbym sobie potrzymać mój nie-opensource kod, za darmo lub za niewielką opłatą (ale jak piszę niewielką, to naprawdę niewielką — €10 rocznie to była absolutnie nieprzekraczalna granica). Z serwisów za niewielką opłatą właściwie nie dało się niczego wybrać, zwłaszcza, że oferowały mniej, niż każdy z dwóch darmowych serwisów: Assembla i wspomniany wcześniej XP-Dev. Obejrzałem sobie plany w tych dwóch serwisach i o ile Assembla nie ograniczała ilości repozytoriów, to każde repozytorium miało mniejszy limit wielkości, na XP-Dev.com można było mieć 5 repozytoriów po 300MB każde (na Assembli dowolną ilość 200MB). Założyłem sobie konto na XP-Dev.com, poprosiłem o wgranie dumpów moich repozytoriów i gotowe.
Jak się parę tygodni później okazało, wybór był szczęśliwy — Assembla wprowadziła ograniczenie dla darmowych kont polegające na wymaganiu publicznego dostępu do repozytorium. Parę dni później właściciel XP-Dev.com zapowiedział, że nie zamierza wprowadzać takiego ograniczenia i wręcz zaprasza wygnańców z Assembli. Uch, upiekło mi się...
Od tamtej pory pojawiło się kilka udogodnień, z tych, które zanotowałem (bo mają dla mnie pewną wartość utylitarną):
unifikacja url-i serwisu i repozytorium;
możliwość samodzielnego wgrywania dumpów repozytorium i dumpowania istniejących repozytoriów;
zniesienie limitów rozmiaru poszczególnych repozytoriów i limitu ilości repozytoriów, teraz trzeba się tylko zmieścić w 1.5GB.
Jak dla mnie to co najmniej wystarczająco dużo. Jakby ktoś potrzebował, to są tam też jakieś dodatki typu wiki itp., ale nie ma obowiązku używania. I to mi się podoba.
Przesiadam się teraz dość regularnie z komputera z desktopem GNOME na Mac OS X 10.5 i mam kilka pomysłów, które mogłyby stać się killer-aplikacjami, gdyby tylko były. Innymi słowy, jest to lista tego, czego brakuje mi w GNOME lub w OS X (albo i w jednym i w drugim).
W GNOME najbardziej brakuje mi czegoś, co działa jak Spotlight w OS X. Celowo napisałem "co działa", bo podobne launchery i dodatki oczywiście istnieją, ale do działania Spotlighta im daleko (są wolne i żrą masę zasobów). Poproszę o coś takiego w najbliższym wydaniu.
I jest coś, czego nie ma ani GNOME, ani OS X — instalator tematów. Coś, co ma Firefox i Opera, ale sam desktop nie. Chciałbym móc otworzyć sobie okienko, przejrzeć listę tematów z gnome-look.org (albo z innego serwisu), nacisnąć guzik "install theme" i już.
Jak ze wszystkimi innymi rzeczami, tak i z memcached nie należy przesadzać. Bynajmniej nie chodzi mi o to, żeby ograniczyć jego używanie — nie ma najmniejszego powodu, żeby sobie odmawiać, to niezły kawałek softu, który dobrze wykonuje swoje zadanie (pewnie mógłby lepiej, ale daruję sobie dygresyjne wędrówki na dzisiaj). Według mnie problem jest natury psychologicznej, a u jego podłoża leżą pospołu lenistwo z ignorancją.
Dla zobrazowania sytuacji przytoczę pewną historię (tak, jak ja ją widziałem, bo nie dotyczyła ona mnie bezpośrednio). Pewien projekt już od swojego założenia miał być ściśle związany z memcache. Wiadomo było od początku, że celem przyspieszenia działania serwisu wiele danych będzie trzymanych na boku w cache, żeby zminimalizować ruch między aplikacją i bazą danych. Założenie rozsądne, ale szybko się okazało, że mocno idealistyczne. Memcache zaczął być traktowany jako panaceum na wszystkie problemy z wydajnością serwisu, obojętnie czy wynikały one ze skomplikowania struktury danych (które skutkuje wysokim obciążeniem bazy danych), czy z marnego algorytmu (nieważne, czy źle zaprojektowanego, czy źle zaimplementowanego). Jeżeli nie dało się czegoś zoptymalizować (czytaj: nikt nie umiał/nikomu się nie chciało/nikomu nie pozwolono marnować na to czasu), to komuś włączała się żaróweczka "o, wiem, wrzucę to do memkesza!", i wrzucał do memkesza. Potem trzeba było opracować metodę usuwania z cache zdezaktualizowanych wpisów. Potem okazywało się, że algorytm do kitu wrzuca do memcache dane do kitu, ale w związku z tym, że aplikacja musi mieć jakiekolwiek dane, obojętne czy prawidłowe czy nieprawidłowe, a w dodatku bez cache aplikacja działać w ogóle nie będzie, to po jakiejkolwiek zmianie algorytmu trzeba było ręcznie usuwać nieprawidłowe dane i trząść się, czy czasem nie usunie się za dużo albo za mało. A i tak do końca nie było pewności, czy po zrestartowaniu aplikacji nagle nie okaże się, że w najmniej oczekiwanym momencie aplikacja nie wysra pięćsetką, a wtedy pozostawał już tylko restart memcached, który, w dużym skrócie, skutkował ogólną apokalipsą (sesje użytkowników w piach, żadnych danych wspólnych przez jakiś czas i ogólnie przerwa w działaniu serwisu idzie w dzisiątki minut).
I tak w kółko, bo jak się okazuje, jest to praktyka powszechna. To znaczy, po tamtym razie widziałem to samo wiele, wiele razy. A jaka jest według mnie recepta? To proste:
zoptymalizuj swój kod
zoptymalizuj bazę danych (słyszałeś o indeksach, prawda?)
to, czego się nie da załatwić optymalizacją, trzymaj w cache
Często widzę pytania typu jakiego frameworka mam się nauczyć? (albo jaki język ma przyszłość?), kto chce się przekonać, niech spojrzy na Stack Overflow. Zadają je najczęściej newbies, albo jeszcze się uczący albo zaraz po szkole, chcąc się wygodnie ustawić na przewidywane 8-10 lat pracy jako software developer (potem i tak pójdą w managery i będzie im wszystko jedno). Najczęściej dostają kilka-kilkanaście odpowiedzi, sumarycznie dających obraz tego, co jest teraz hot i za czym doświadczeni developerzy sikają w majty: Rails, Merb, Django, Pylons, Werkzeug, erlang, haskell... Trudno nazwać te wszystkie odpowiedzi błędnymi, bo prawdopodobnie w krótkiej perspektywie (2 lata? 3 lata?) to wszystko będzie się sprawdzało. Ale co potem?
A potem wszystkie te odpowiedzi będzie można sobie potłuc o kant zbolałej dupy. Wszystkie te frameworki odejdą w zapomnienie, a języki staną się niszowe (albo nigdy z niszy nie wyjdą). Patrząc na aplikacje, których używają miliony aż dziw, że nikt nie podaje odpowiedzi, która powinna nasująć się sama: "synku, ucz się JavaScript-u". A co to są za aplikacje, te których używają miliony? Nie Word, nie Excel, nawet nie Firefox ani Internet Explorer (paradoks, ale przeglądarka jest taką quasi-aplikacją, jest raczej wirtualnym środowiskiem aplikacyjnym — niektórzy, jak Joel Spolsky, uważają przeglądarki za coś, co zabija tradycyjne desktopy). To GMail, Google Reader, Google Documents, Picasa i pozostałe z koszyczka Google™ (Yahoo!™ nie ma aż takich ambicji, po kupieniu Flickr-a nie rozpoczęło globalnej ekspansji w celu przejęcia władzy nad internetem). Każda z nich jest od dna aż do szczytu napakowana JavaScriptem, co czasem daje efekt taki, że użytkownicy... nie umieją już posługiwać się desktopowymi aplikacjami, które były pierwowzorami aplikacji webowych Google. Uczeń przerósł mistrza używając technologii, która miała stworzyć w internecie namiastkę interaktywności znanej z aplikacji desktopowych. Być może za kilka lat jedynymi płatnymi aplikacjami desktopowymi będą... edytory programistyczne. Bo innych aplikacji w ogóle nie będzie.
Idea webowego desktopu nie jest nowa. Sięgając pamięcią do zamierzchłych lat 90-tych XX wieku niektórzy mogą sobie przypomnieć idee komputerów sieciowych, pozbawionych twardych dysków, będących jedynie stacjami roboczymi z wypasionymi kartami graficznymi (do renderowania stron WWW w oknie przeglądarki). Jak przez mgłę majaczy mi, że nawet poważne firmy, jak np. Sun Microsystems, maczały palce w realizacji tych idei. Dzisiejsze netbooki (z małymi dyskami SSD, procesorem Intel® Atom™, napędzane specjalnie skrojonymi dystrybucjami linuksa) są pokłosiem i ewolucyjnym rozwinięciem tej idei — to nie maszynka desktopowa ma dysponować przerażającą mocą obliczeniową, tylko maszyna, na której jest uruchomiona aplikacja. Stacji roboczej wystarczy tyle mocy, żeby wyrenderowała stronę w przeglądarce.
Za 5 lat obecne ramówki aplikacyjne i języki będą zjawiskiem zanikającym, a tym, co będzie napędzało aplikacje będzie ogromne morze JavaScriptu. I o ile wiem, nie jestem odosobniony w tym poglądzie...
Is it the light I see?
Is it the water that bathes me?
Or is it your kingdom which begs me?
So abusive I can't breathe
guilt brings paralysis
my hands are left to rot
my eyes pryed open
clense this body I give
from its impurities
accumulated for years
from ignorance and blind fears
So reflective you can see
the layers of this shedding skin
conscious or self deciet
I await the vision
Is it the light I see?
Is it the water that bathes me?
I surrender to my will
regurgitate old beliefs
dedicated to my deeds
I fall to fragments
on my knees
So reflective you can see
the layers of this shedding skin
conscious or self deciet
I await the vision
So reflective you can see
the layers of this shedding skin
Do tej pory pracowałem przy poważnych aplikacjach dla poważnych ludzi. Aplikacje te sprawiały poważne problemy i walka z nimi była naznaczona ich powagą. No i kiedyś musiała nadejść ta chwila, że zająłem się aplikacją dla pokemonów — robię wyszukiwarkę dla jednego z serwisów przeznaczonych dla publiczności w wieku gimnazjalno-licealnym (tytułowe pokemony).
Byłem przygotowany na koszmarny, niczego nie przypominający język. Byłem przygotowany na wszelkie zbrodnie przeciwko ortografii, gramatyce i interpunkcji. Spodziewałem się dziwactw, które są w stanie wywalić w kosmos aplikację niezabezpieczoną przed wstrzykiwaniem SQL. Przeglądając dane z forum tego serwisu natknąłem się jednak na coś, co przesunęło moje granice percepcji.
Podczas próby indeksowania silnik indeksowy updarcie odmawiał przyjęcia pewnego zbioru danych twierdząc, że znajduje się w nich znak kontrolny Unicode o numerze 14, czyli Shift Out. WTF?! Skąd tam się wziął niedrukowalny (i niewprowadzalny z klawiatury!) znak kontrolny? Nie da się go wpisać, nie da się go wkleić w okienko do wprowadzania tekstu (tak mi się przynajmniej wydaje), bo nie można go też skopiować. Prawdę mówiąc zupełnie nie interesuje mnie, jak tamta aplikacja wpuściła ten znak do swojej bazy (to jest nazwa użytkownika, więc jest używana w wielu miejscach), za to interesuje mnie, jak ktoś go przeprowadził przez formularz HTML, żądanie HTTP POST i bibliotekę kliencką bazy danych (znak ten zapisany był w zwykłym polu znakowym typu varchar, nie powinien był tam się znaleźć bez odpowiedniego wyeskejpowania).
Wiele lat pracy z poważnymi aplikacjami przyzwyczaiło mnie do tego, że aplikacja jest linią frontu, na której muszą zostać powstrzymane śmiecie — powstrzymane lub zneutralizowane. W wyniku konsekwentnego chronienia rodowych sreber (dane) przed zalewem gówna, można mieć pełne zaufanie do danych aplikacji. No i okazało się, że są aplikacje, którym tak naprawdę jest wszystko jedno, którą częścią ciała szczekają psy...
Nie używałem zanadto, ale miałem sentyment, bo serwis był zrobiony w Django. A teraz przejęło ich Six Apart i zabawa się skończyła. To chyba normalne w interwebie, ale żal jakiś jest...