QUERY_STRING i Weby

sobota, 21 sierpnia 2010

Wczoraj przerwałem moją notatkę na temat CGI zanim opisałem zmienną QUERY_STRING.

Qt 4.7 skończyło się kompilować i właściwie, dla mnie, nic interesującego z tego nie wynika. Miałem nadzieję że poprawią rendering cieni, lub wydajność efektów przejścia (WebKit). Nie poprawili. Pośród przykładów jest przeglądarka, nawet miła, ale wolniejsza niż Chrome.

Działa to naprawdę elegancko. Co najważniejsze, wybór Qt, jest już dziś wyłącznie sprawą twórcy kodu, aplikacja jest nie do odróżnienia od reszty środowiska (czy to będzie GTK, Win32, czy OSX).

Trochę bawi mnie paradoks, aby uciec od desktopowych kontrolek, muszę najpierw zawrzeć z nimi bliższą znajomość.

… ale wracając do tematu (QUERY_STRING)

Shell

Przynajmniej połowa skryptów narodziła się jako przydługie polecenie, którego dalszy rozwój wyrwał się z pod kontroli. Programowanie w shellu, to zazwyczaj używanie narzędzi, które akurat wpadną w ręce.

Shell nie jest narzędziem dla purystów. Jeśli oczekujesz eleganckiego programu, to polecam Python, gdzie napisanie programu który po prostu działa jest herezją.

Owszem da się napisać „czyste” rozwiązanie, oto przykład: bash_cgi. Tyle że nikt tak nie robi, wygodniej jest np wspomóc się wstawką w Perlu. Siła shella leży w integracji narzędzi.

Perla nie lubię, więc użyłem kilku wyrażeń regularnych i „edytora strumieniowego”:

echo "$QUERY_STRING" \
| sed 's/&/\n/g' \
| sed 's/+/%20/g' \
| sed 's/%/\\x/g' \
| sed -n 's/\(\w\+\)=\(.*\)/\1=`echo -e '\''\2'\''`/p'

Całość można owinąć w konstrukcję eval $(…) i gotowe.

Warto by dodać obsługę metody POST, ale …

Weby

Wygląda na to że w końcu sam siebie przekonałem do pomysłu napisania odpowiednika polecenia dialog w oparciu o WebKit.

Tak przy okazji, warte wspomnienia są takie rozwiązania jak Xdialog, czy gtk-server, które można z łatwością użyć z poziomu shella (przykład).

Rozwiązanie, oparte o WebKit wydaje się jednak bardziej atrakcyjne. Umożliwia bowiem płynne przejście ze skryptu działającego w linii poleceń, poprzez aplikację „biurkową”, do aplikacji webowej w przyszłości.

Odkładam na chwilę na bok wersję napisaną w Vala i wracam do C++

Najpierw konieczne było uporządkowanie kodu i utworzenie nowej kontrolki:

weby.cc

Weby::Weby(QWidget *parent) : QWidget(parent)
{
        view = new QWebView(this);
        view->load(QUrl("weby.htm"));
        view->show();
}

Następnie dodałem obsługę zmiany tytułu i url, uzyskując tą samą funkcjonalność co w Vala.

Kolejnym krokiem było dodanie obsługi formularzy. Po otrzymaniu danych, aplikacja wyświetla zmienną QUERY_STRING i kończy pracę.

void Weby::action(const QUrl &url)
{
 if (url.hasQuery()) {
  std::cout
   << "QUERY_STRING='"
   << url.encodedQuery().data()
   << "'\n";
  close();
 }
}

Ponieważ nie ma niczego eleganckiego w dekodowaniu pól formularza w skrypcie, lepiej by zrobił to Weby. To jednak okazało się nieco trudniejsze. Wychodzi na to że Qt ma błąd w obsłudze znaków spacji i „+” w url, trzeba więc trochę pokombinować.

QByteArray fixEncoding(QByteArray s)
{
 return QByteArray::fromPercentEncoding(s.replace("+","%20"));
}
/* … */
 QListIterator< QPair<QByteArray,QByteArray> >
  iter(url.encodedQueryItems());

 while (iter.hasNext()) {
  QPair<QByteArray,QByteArray> e = iter.next();
  std::cout
   << "weby_"
   << fixEncoding(e.first)
    .data()
   << "='" 
   << fixEncoding(e.second)
    .replace("'","'\\''")
    .data()
   << "'\n";
 }

Cały kod jest na code.google.com.

Formularz należy umieścić w pliku weby.htm (w tej chwili nazwa jest zakodowana na sztywno). Wywołanie odbywa się poleceniem eval `weby`.

Na koniec

Muszę przyznać że nabrałem przekonania do biblioteki Qt, w połączeniu z nią C++ przestaje być tak drętwym narzędziem jakim go pamiętam.

Przy okazji, ściągnąłem jeszcze jedno narzędzie: Qt Creator. Dawno już nie widziałem IDE, które startuje w dwie sekundy… Upadł nawet mój argument o przyzwyczajeniu do klawiszologii VIM – ktoś o to zadbał. Ktoś napisał naprawdę znakomite narzędzie. Nie, Vim'a nie porzucę, choćby dla tego że wspiera ponad 200 języków programowania, a nie tylko C++

Etykiety: , , ,

Red 23:48

Komentarze

Prześlij komentarz

Archiwum

Subskrybuj

RSS / Atom