TechLife devBlog

Bootstrap - HTML-owe klocki Lego

Kodowanie Techblog 16 kwietnia 2012 o 22:18:55 | ☍ trackback

W lipcu narzekałem, że webdeveloperom brakuje klocków/struktur z których mogliby łatwo budować aplikacje, podobnie jak buduje się desktopowe interfejsy graficzne korzystając z różnych bibliotek zawierających zdefiniowane elementy i kontrolki. Dzisiaj spokojnie mogę powiedzieć, że HTML również doczekał tych wspaniałych czasów.

Bootstrap - przykład

Od kilku miesięcy obserwowałem rozwój projektu Bootstrap (od Twittera). Bootstrap to ogromny zbiór najczęściej stosowanych HTML-owych struktur, które zostały w bardzo estetyczny sposób ostylowane oraz dodano JavaScript do sterowania interaktywnymi elementami tj. okna modalne, taby, rozwijane menu, dymki z podpowiedziami, komunikaty i wiele innych.

Początkowo dostarczanych elementów było względnie mało. Do tego zastosowanie Bootstrapa było bardzo inwazyjne, ponieważ automatycznie stylował nam różne elementy, które niekoniecznie chcieliśmy mieć ostylowane w ten sposób. Jednak przez te kilka miesięcy odwalono kawał dobrej roboty. Liczba elementów urosła już do takiej ilości, że pozwala spokojnie budować bardzo zaawansowane aplikacje bez konieczności tworzenia własnych struktur. Zmieniła się również polityka stylowania i teraz większości elementów trzeba nadać klasę (np. tabeli należy nadać klasę table) aby skorzystać ze styli Bootstrapa.

Komponenty

Jak przystało na porządne pudełko z narzędziami, w Boostrapie znajdziemy też 12 kolumnowy CSS grid (stały lub płynny), oraz zestaw styli CSS3 służący do ładnego wyświetlania całości na różnej wielkości ekranach (Responsive design).

Grid

Korzystałem już z Bootstrapa w kilku aplikacjach i okazał się bardzo wygodny w użyciu. Bez problemu mogłem się skupić na mechanizmach zamiast na warstwie prezentacyjnej a mimo to wynikowa aplikacja była bardzo estetyczna i odznaczała się wysokim współczynnikiem eye candy. Do tego wszystkiego można dodać, że Bootstrap umożliwia wygenerowanie sobie spersonalizowanej paczki, zawierającej tylko potrzebne nam elementy a nawet przebudowany na nasze potrzeby CSS, ponieważ Boostrap generuje go korzystając z dobrodziejstw LESS.

Generator

Używa się tego tak dobrze, że całkiem prawdopodobne jest, że niedługo internet zostanie zalany podobnie wyglądającymi stronami i aplikacjami. Prosty przykład:

Przykładowa strona

Na stronie builtwithbootstrap.com można zobaczyć już całą gamę stron zbudowanych z pomocą Bootstrapa. Jest jednak światełko w tunelu. Powstała strona bootswatch.com oferująca różnorodne skórki dla elementów Bootstrapa.

Przykład skórki
Przykład skórki

Oczywiście Bootstrap to nie jedyny projekt tego typu. Warto przyjrzeć się również HTML KickStart.

Kick Start

Czasy gdy programiści tworzyli sraczkowate interfejsy oparte na tabelkach rodem z lat '90 oficjalnie uważam za zamknięte. Miłego kodowania!

Django i shortcodes

Django Kodowanie Techblog 05 lutego 2012 o 23:21:27 | ☍ trackback

Kilka miesięcy temu pytałem #django-wców na blipie o możliwość wstawiania do treści słów kluczowych, które później byłyby zamieniane na różne dziwne rzeczy. Nikt mi wtedy nie odpowiedział, więc pewnie sprawa nie jest jeszcze zbyt popularna. Ostatnio jednak znalazłem rozwiązanie mojego problemu. Słowo klucz - shortcodes.

Shortcodes to znane przede wszystkim z WordPress-a pseudo tagi, za pomocą których możemy wstawiać w dowolne miejsca w tekście różnego rodzaju obiekty. Np. wykorzystując taki kod:

[gallery id="123" size="medium"]

możemy osadzić galerię pomiędzy dwoma paragrafami tekstu. Odpowiednia aplikacja istnieje też dla Django - django-shortcodes. Instalacja jest bardzo prosta i sprowadza się do kilku kroków:


  1. do katalogu z naszym projektem kopiujemy folder shortcodes

  2. w settings.py dodajemy shortcodes do INSTALLED_APPS

  3. w szablonie, w którym chcemy użyć filtra dodajemy {% load shortcodes_filters %}

  4. do zmiennej, która zawiera nasze słowa kluczowe dodajemy filtr shortcodes np. {{ news.tresc|shortcodes|safe }}

Zmienna zawierająca słowa kluczowe nie musi być wyłącznie tekstem. Może być to HTML wyprodukowany przez jakiś edytor np. TinyMCE. Trzeba tylko pamiętać, żeby najpierw dokonać podmiany słów kluczowych a dopiero później wypluć HTML (kolejność filtrów).

Najważniejszą częścią aplikacji django-shortcodes są parsery znajdujące się w katalogu parsers (domyślnie tylko youtube)

parsers

To one zawierają definicje słów kluczowych, oraz ich parametry. Nazwa pliku parsera definiuje też nazwę słowa kluczowego.

Ok, czas na przykłady, np. YouTube (trochę zmodyfikowany):

YouTube - TinyMCE

Rezultat:

YouTube - podgląd

Napisałem też prosty parser do wstawiania mp3 z pomocą Googlowego odtwarzacza:

[mp3 adres=http://www.luzuj.com/pb/mp3/piwo.mp3]

Odtwarzacz mp3

czy parser osadzający galerię zdjęć:

[galeria numer=1]

Galeria zdjęć

Oczywiście łatwo można też modyfikować wstawiane treści za pomocą różnych parametrów np.

[youtube adres=http://youtu.be/d9NF2edxy-M szerokosc=600 wysokosc=400]

lub

[galeria numer=1 tytul=brak]

Naturalnie to tylko banalne przykłady. Jednak najważniejsze jest to, że każdy może je łatwo dostosować do swoich wymagań i wykorzystać do wstawiania ankiet, wykresów, plików, prezentacji, statystyk czy różnych innych treści, które w normalnych przypadkach wymagałyby użycia skomplikowanego (często generowanego) HTML-a, który byłby kłopotliwy dla różnych edytorów typu TinyMCE.

Generator filmowych miniaturek

Kodowanie Linux Software Techblog 11 stycznia 2012 o 21:59:22 | ☍ trackback

Często zamieszczając na stronie streszczenie jakiegoś filmu brakowało mi narzędzia, które było by w stanie zamiast zrzutu pojedynczej klatki wygenerować mi miniaturkę składającą się przynajmniej z 4 zrzutów pochodzących z różnych części filmu. W repozytorium znalazłem tylko mplayer-snapshot, ale nijak nie działało. Ponieważ potrzebowałem tylko 4 zrzuty szybko skleiłem prosty skrypt Basha wykorzystujący FFMpegThumbnailer (powinien być w każdym repo) do robienia zrzutów i montage (pakiet imagemagick) do ich klejenia.

#!/bin/sh

usage()
{
cat << EOF
usage: $0 [options] -i MOVIE-FILE

OPTIONS:
   -h       show this message
   -i       input movie file
   -o       output JPG file name
   -a       percentage or absolute time hh:mm:ss, default 20
   -b       percentage or absolute time hh:mm:ss, default 40
   -c       percentage or absolute time hh:mm:ss, default 60
   -d       percentage or absolute time hh:mm:ss, default 80
   -n       number of columns
EOF
}

FILE=
OUT=
COLUMNS=2
T1=20
T2=40
T3=60
T4=80

while getopts "hi:o:a:b:c:d:n:" OPTION
do
     case $OPTION in
         h)
             usage
             exit 1
             ;;
         i)
             FILE=$OPTARG
             OUT=${OPTARG}.jpg
             ;;
         o)
             OUT=$OPTARG
             ;;
         a)
             T1=$OPTARG
             ;;
         b)
             T2=$OPTARG
             ;;
         c)
             T3=$OPTARG
             ;;
         d)
             T4=$OPTARG
             ;;
         n)
             COLUMNS=$OPTARG
             ;;
         ?)
             usage
             exit
             ;;
     esac
done

if [[ -z $FILE ]]
then
    usage
    exit 1
else
    ffmpegthumbnailer -t $T1 -s 400 -o /tmp/thumb-1.jpg -i $FILE
    ffmpegthumbnailer -t $T2 -s 400 -o /tmp/thumb-2.jpg -i $FILE
    ffmpegthumbnailer -t $T3 -s 400 -o /tmp/thumb-3.jpg -i $FILE
    ffmpegthumbnailer -t $T4 -s 400 -o /tmp/thumb-4.jpg -i $FILE

    montage -mode concatenate -tile ${COLUMNS}x -adjoin /tmp/thumb*.jpg $OUT
    rm /tmp/thumb*.jpg
fi

Dla przykładu weźmy trailer Hobbita. Po pobraniu go na dysk i zapisaniu jako hobbit.flv wystarczy odpalić skrypt i wskazać plik:

movie-thumbnails.sh -i hobbit.flv

Skrypt powinien wypluć plik o nazwie hobbit.flv.jpg:

Jak to jednak przy generowaniu miniaturek bywa czasami zdarza się złapać jakaś niepożądana klatkę. Aby ją wymienić należy wskazać którą z czterech klatek wymieniamy (a,b,c czy d) oraz podać procentowo lub dokładnie (np. 00:03:28) czas filmu, z którego ma zostać pobrana.

Domyślnie:

a - 20%
b - 40%
c - 60%
d - 80%

Czyli jeżeli chcemy wymienić np. miniaturkę 2 na coś jaśniejszego wystarczy zrobić:

movie-thumbnails.sh -i hobbit.flv -b 27

wynik:

Używając parametru -n możemy sterować też ilością kolumn:

movie-thumbnails.sh -i hobbit.flv -n 1

movie-thumbnails.sh -i hobbit.flv -n 4

Na koniec parametrem -o sterujemy nazwą pliku wyjściowego

movie-thumbnails.sh -i hobbit.flv -o hobbit.jpg

Linki

[CSS] Pionowo czy poziomo?

Internet Kodowanie Techblog 25 listopada 2011 o 23:51:19 | ☍ trackback

Nie będzie to flame, chciałem przedstawić Wam tylko mój punk widzenia. Do chwili zatrudnienia się w Firmie byłem święcie przekonany, że jedynym słusznym formatowaniem jest formatowanie pionowe, gdzie elegancko mamy podane jak na tacy wszystkie atrybuty.

poziomo

W Firmie przyszedł czas bardzo intensywnego kodowania. Często pracowałem z dużymi arkuszami stylów, których ciągłe przewijanie stawało się bardzo niewygodne. Nierzadko trzeba było też wrócić do poprzednich projektów i szybko poprawić jakieś drobne niedociągnięcia. Dopiero wtedy uświadomiłem sobie, że w CSS-ie jest coś ważniejszego niż atrybuty i ich wartości. Najważniejszą rzeczą są selektory! Dopiero zrozumienie tej kwestii pozwoliło mi inaczej spojrzeć na elegancję poziomego formatowania.

poziomo

Rzeczą oczywistą jest to, że najpierw wyszukujemy obiekt, który chcemy zmodyfikować a następnie dodajemy mu kolor tła czy zmieniamy margines. Priorytetem jest więc szybkie odnajdywanie selektorów a później dopisanie czy odnalezienie potrzebnego atrybutu jest już dość proste, mimo że wszystkie atrybuty są w jednej linii. IMHO o wiele więcej czasu zajmuje znalezienie odpowiedniego selektora w rozciągniętym pliku niż odpowiedniego atrybutu w liniowym zapisie.

Aby jeszcze bardziej ułatwić sobie sprawę należy trzymać się prostej zasady: najpierw definiujemy box model: display, width, height, float, margin, padding (najlepiej zachować taką kolejność) a później całą resztę (position, background, color, font-size itp). Trzymając się tej zasady od razu wiemy czy szukamy atrybutu z końca czy początku linii.

Jeszcze raz poglądowo. Formatowanie pionowe - mało widać, dużo szukania

pionowo

Formatowanie poziome - szybkie odnajdywanie selektorów i (trzymając się zasady) w miarę szybkie odnajdywanie atrybutów.

poziomo

Łączenie przez SSH na dynamiczne IP

Linux Techblog 04 listopada 2011 o 22:25:01 | ☍ trackback

Kiedyś korzystałem z różnych serwisów z cyklu NO-IP. Z czasem jednak niektóre się pozamykały a inne stały się płatne. Nie miałem też ochoty rejestrować się i testować nowych rozwiązań, po których do końca nie było wiadomo czy na pewno są darmowe czy może płatne. Wymyśliłem więc prosty trick.

The story

W biurze mam stale działający komp, który służy do robienia backupów z naszych serwerów. Czasem z domu chcę coś na nim pogrzebać ale problem polega na tym, że nasz Netiowy ADSL co jakiś czas zmienia IP. Żeby więc móc za każdy razem połączyć się przez SSH muszę śledzić zmiany IP.

The trick

Metoda jest bardzo prosta. Wystarczy posiadać internetowy serwer (nazwijmy go serwerem zdalnym), który spełni rolę pseudo DNS-a, czyli zapytany o namiary na biurowy serwer (nazwijmy do serwerem lokalnym) zdradzi nam jego IP.

W tym celu na serwerze zdalnym piszemy prosty skrypt, który serwer lokalny będzie odpalał co godzinę.

nazwijmy go zapisz-ip.sh

#/bin/sh
echo $SSH_CLIENT | cut -f1 -d' ' > /tmp/ip

Tak przygotowany plik zapisujemy np. w katalogu bin w katalogu domowym użytkownika (czyli /home/tomek/bin/zapisz-ip.sh) i oczywiście dajemy mu prawa do wykonywania (chmod +x bin/zapisz-ip.sh). Jak widać skrypt ze zmiennej $SSH_CLIENT wyciąga adres IP i zapisuje go do pliku /tmp/ip.

Teraz na serwerze lokalnym (tym w biurze) ustawiamy w cronie zadanie wywoływania tego skryptu co godzinę. Czyli stukamy crontab -e i piszemy:

11 * * * *      tomek@ADRES-SERWERA-ZDALNEGO.pl ~tomek/bin/zapisz-ip.sh

Tutaj należy wspomnieć, że połączenie pomiędzy serwerem lokalnym a zdalnym powinno odbywać się poprzez autoryzację kluczem SSH. W przeciwnym wypadku skrypt zatrzyma się na etapie podawania hasła.

Mamy więc na serwerze zdalnym stale uaktualniany plik /tmp/ip zawierający bieżące IP serwera lokalnego. Żeby teraz połączyć się z serwerem lokalnym z dowolnego innego miejsca wystarczy przy łączeniu przez SSH adres IP odczytać z serwera zdalnego. Wygląda to tak:

ssh tomek@`ssh tomek@ADRES-SERWERA-ZDALNEGO.pl cat /tmp/ip`

Najlepiej oczywiście wsadzić to w jakiś skrypt i wywoływać jednym poleceniem. Taki sam efekt można uzyskać wykorzystując serwer www z obsługą np. PHP + prosty skrypt zapisujący do pliku adres IP a następnie serwujący go pod jakimś URL-em.

PS. Jeżeli trick wydaje Wam się zbyt banalny to polecam niezłą listę 100 darmowych gier na Linuksa ;-).

Mikro struktury HTML

Kodowanie Techblog 02 lipca 2011 o 19:16:49 | ☍ trackback

Z doświadczenia wiem, że najlepsze rozwiązania, to takie, do których doszedłem sam ewolucyjnie. Wtedy najlepiej rozumiem do czego one są i dlaczego tak a nie inaczej działają. Jest to o wiele lepsza metoda niż przyjmowanie nawyków innych osób, których sami do końca nie rozumiemy. Dlatego najczęściej nie stosuję różnych narzędzi tylko dlatego, że inni je polecają ale czekam spokojnie aż sam dojdę do punktu, w którym uznam, że dokładnie takiego narzędzia potrzebuję. Swoją drogą w ten sposób uwalniam się od stosowania przeróżnych udziwnień, które w rzeczywistości nie są przydatne / efektywne / nie do końca wiadomo w czym pomocne.

Po kilku dobrych latach kodowania stron coraz wyraźniej zaczynam dostrzegać co jest potrzebne do szybkiego i sprawnego budowania interfejsów www -- mikro struktury. HTML ma to do siebie, że jest dość "niskopoziomowy", dzięki czemu można za jego pomocą poskładać do kupy różne cuda. Kiedy jednak chcemy szybko zbudować interfejs składający się z często powtarzających się elementów (list, przełączników, kontrolek, pasków postępu, przycisków, komunikatów, okien dialogowych itp) odkrywamy nagle, że tak na prawdę brak nam widgetów czy kontrolek znanych z różnych środowisk graficznych. Za każdym razem budujemy je na nowo z "niskopoziomowych" klocków HTML-a zamiast po prostu wziąć i wykorzystać gotowe struktury. Coś jak np. interfejsy dla telefonów:

Android GUI

Jednym słowem chodzi mi o coś w rodzaju połączenia mikroformatów z Zen Garden. Jeżeli stworzymy odpowiednio elastyczną strukturę uzyskamy możliwość stylowania jej CSS-em na wiele różnych sposobów. Weźmy na przykład prostą listę:

<ul>
    <li>Element 1</li>
    <li>Element 2</li>
    <li>Element 3</li>
    <li>Element 4</li>
</ul>

Jeżeli zamienimy ją w uniwersalną strukturę:

<div class="vertical-list">
    <div class="outer">
        <div class="inner">
            <ul>
                <li class="first">
                    <span class="line">Element 1</span>
                </li>
                <li>
                    <span class="line">Element 2</span>
                </li>
                <li>
                    <span class="line">Element 3</span>
                </li>
                <li class="last">
                    <span class="line">Element 4</span>
                </li>
            </ul>
        </div>
    </div>
</div>

Otrzymujemy obiekt, który może uzyskać praktycznie nieskończenie wiele kształtów. Na dodatek biorąc tą samą strukturę i zmieniając nazwę klasy z vertical-list na horizontal-list możemy uzyskać listę poziomą. Oczywiście każda struktura może mieć kilka wariantów wyglądu np vertical-list-v2.

Używając takich struktur w swoim kodzie, dostosowanie ich do nowego projektu mogło by się ograniczyć wyłącznie do podłączenia innego arkusza stylującego struktury. Podobnie jak jest to rozwiązane w przypadku galerii jQuery UI.

Nie bardzo chce mi się wierzyć, że nikt przede mną jeszcze na to nie wpadł, więc jeżeli znacie jakieś podobne projekty to bardzo proszę o linki bo samemu nie udało mi się nic sensownego znaleźć.

Cywilizacja Open Source

Kodowanie Techblog 22 maja 2011 o 18:01:25 | ☍ trackback

Kiedy słyszymy Open Source nasze skojarzenia biegną w kierunku systemu Linux, przeglądarki Firefox czy też śp. pakietu OpenOffice (obecnie LibreOffice) oraz niezliczonej ilość podobnych programów, z których mniej lub bardziej świadomie korzystamy na co dzień. Open Source kojarzy się nam najczęściej z informatyką i stylem wytwarzania oprogramowania. Jednak Open Source to coś więcej niż informatyka, to styl myślenia, który powoli ale nieodwracalnie wymyka się z pola informatyki i zaczyna kiełkować w przeróżnych dziedzinach.

To co chcę przekazać w tej notce może wydać się dość niepozorne jeżeli nie znamy tła jakim jest obecny status i kształt systemu, który wytwarza nam dziś wszelkie dobra. Najlepiej zapoznać się wcześniej z filmami typu: Zeitgeist: Moving Forward czy The Light Bulb Conspiracy. Pierwszy z nich pokazuje przyczyny, które zmuszają naszą cywilizację do produkcji bubli oraz marnowania zasobów, natomiast drugi pozwala nam zobaczyć ten proces w praktyce.

Czasami, żeby zrobić krok do przodu, trzeba najpierw zrobić dwa do tyłu, porzucić rozwiązania, które zaprowadziły nas w ślepy zaułek i zaprojektować od podstaw nowe, dzięki którym trafimy na autostradę rozwoju.

Arduino

Jeżeli studiowaliście elektronikę lub informatykę na pewno na laborkach uczyliście się programować jakieś proste układy w postaci (specjalnie przygotowanych do nauki) płytek drukowanych z przeróżnymi układami elektronicznymi. Problem z tymi układami (miałem z nimi styczność w technikum i na studiach) polegał na tym, że były one:

  • dość drogie
  • do ich obsługi wymagane było specjalne dostarczane przez producenta oprogramowanie (oczywiście też drogie) i dostępne wyłącznie na Windowsa
  • dostęp do układów miałem tylko na laborkach bo ani nie miałem ochoty kupować na rok tak drogiego sprzętu, ani nie miałbym go jak uruchomić bo nie mam Windowsa

Jak widać takie praktyki w żaden sposób nie zachęcają do przybliżenia młodemu człowiekowi elektroniki. Z podobnym problemami ścierano się również w innych krajach i tym sposobem narodził się projekt Arduino.

Arduino The Documentary (2010) English HD from gnd on Vimeo.

Linki:
- Wikipedia o Arduino
- www.arduino.cc - strona domowa

Oczywiście Arduino to dopiero początek, mały klocek LEGO na bazie którego mogą powstawać nowe otwarte rozwiązania.

Open Source Ecology

Wstępem do tego projektu najlepsza będzie prelekcja Marcina Jakubowskiego wygłoszona w ramach konferencji TED.

BTW. Marcin został wyróżniony odznaką TED Fellow 2011. Jeszcze intro ze strony projektu:

Marcin odwiedził już w tym roku Polskę, do której przyjechał na zaproszenie organizatorów konferencji Cohabitat Gathering 2011. Poniżej bardzo swobodna rozmowa zarejestrowana po konferencji.

Marcin Jakubowski CHG 2011 - II from dobraidea on Vimeo.

Global Village Construction Set (GVCS) ułatwia rozpoczęcie prac w sektorze rolniczym, budowlanym oraz produkcji i może być postrzegany jako naturalnej wielkości "Zestaw Lego" narzędzi modułowych, które pozwalają stworzyć całą gospodarkę, zarówno na wiejskich terenach Missouri, w którym projekt został założony, w górach Oregon, lub w sercu Afryki. Projektując bez granic, zarówno myślowych jak i praktycznych, jesteśmy pewni że GVCS może przełamać bariery wykonalności i kosztów budowy od podstaw prawdziwej trwałej i zrównoważonej wspólnoty, oraz gospodarki funkcjonującej w oparciu o lokalne zasoby.

Tak jak pisałem na początku, niektórym projekt może się to wydać dość niepozorny. W końcu stworzono tylko niezbyt estetycznie wyglądający traktor czy zgniatarkę do ziemi. Bardziej zainteresowało by to pewnie rolnika niż przeciętną osobę techniczną. Jednak cały sens projektu ukryty jest w jego filozofii, czyli filozofii Open Source. Weźcie pod uwagę np. fakt, że dopiero ostatnio producenci telefonów komórkowych zdecydowali się produkować zgodne ze sobą ładowarki (sic!). Przez Wykop przetaczają się teraz notki o tym, jak to producenci drukarek oszukują nas za pomocą tuszy. Tych problemów (pokazanych też w The Light Bulb Conspiracy ) jest całe mnóstwo. Nie wyrwiemy się z nich dopóki nie przestawimy swoich schematów myślenia na tory Open Source.

Tak więc parafrazując jest to mały traktor dla człowieka ale wielki dla ludzkości. Poza tym traktor to dopiero początek. Kilka dni temu pojawiły się pierwsze testy stołu do cięcia. Przypomnę, że jednym z jego głównych założeń jest samoreplikacja podobnie jak w przypadku słynnej drukarki 3D RepRap. Na liście projektów do stworzenia czekają jeszcze takie rzeczy jak: drukarka 3D, skaner 3D, 50kW turbina wiatrowa, automobil czy ciężarówka.

Nie sposób o tym wszystkim opowiedzieć, dlatego zachęcam do zapoznania się z różnymi zaułkami strony projektu.

Linki:
- opensourceecology.org - strona projektu

PS. Od jakiegoś czasu ilość moich notek technicznych jest zastępowana przez notki nietechniczne dodawane na moim drugim blogu poświęconym zagadnieniom alternatywnym. Jeżeli kogoś interesuje taka tematyka to zapraszam. Co do notek technicznych to chyba będę musiał zamieszczać je w bardziej skróconej formie, bo na zebranie materiałów i skompilowanie z nich jakiegoś tekstu mam coraz mniej czasu, czego skutek najczęściej jest taki, że pomysł na notkę umiera na etapie pomysłu.

Django: usuwanie cache'u generowanego przez szablon

Django Kodowanie Techblog 25 marca 2011 o 23:58:16 | ☍ trackback

Sytuacja jest następująca: 1989 rok, Kijów. Piękna ukraińska jesień. Czterech urodzonych morderców, uzbrojonych po zęby, a ja sam, jeden, z moim wiernym kałachem... mamy jakiś kawałek szablonu, którego wygenerowanie kosztuje nas sporo zasobów np. wiele zapytań do bazy. Cache'ujemy więc w szablonie wygenerowany HTML aby ulżyć serwerowi. Np. tak:

{% load cache %}

{% cache 604800 statystyki %}
   jakiś super zasobożerny w generowaniu kod HTML
{% endcache %}

Wszystko działa ładnie. Cache wygasa co tydzień (604800 sekund) i wszystko gra. Problem pojawia się jednak, kiedy wygenerowany kod zależy bezpośrednio od jakiegoś obiektu lub obiektów. Kiedy dany obiekt jest modyfikowany chcielibyśmy usunąć cache generowany przez szablon. Rozwiązanie wydaje się być dość logiczne:

from django.core.cache import cache

cache.delete('statystyki')

Niestety powyższy kod robi nic. Template tag tworzy cache generując klucz:

args = md5_constructor(u':'.join([urlquote(resolve_variable(var, context)) for var in self.vary_on]))
cache_key = 'template.cache.%s.%s' % (self.fragment_name, args.hexdigest())

Jak widzimy schemat jest następujący:
template.cache.KLUCZ-Z-SZABLONU.ZAKODOWANE_ARGUMENTY

Jeżeli nie używaliście argumentów w szablonie przy stworzeniu klucza cache'u (czyli nie zrobiliście np. czegoś takiego: {% cache 604800 statystyki request.user %}) to Wasza lista argumentów będzie pusta. Suma MD5 z pustego stringa zawsze wynosi tyle samo, więc dla cache'u tworzonego bez argumentów klucz jest stały i wygląda tak:

cache.delete('template.cache.statystyki.d41d8cd98f00b204e9800998ecf8427e')

<oklaski />

Xfce4.8 - przewodnik

Linux Software Techblog 18 stycznia 2011 o 20:30:12 | ☍ trackback

Poniższy tekst jest tłumaczeniem oficjalnego przewodnika po nowej wersji Xfce 4.8:

Przewodnik

Ten przewodnik przedstawi Ci wszystkie ważniejsze wizualne nowości w Xfce 4.8. Jest to tylko wizualna część tego co zostało dokonane, pełną listę zmian możecie zobaczyć w dzienniku zmian. Przewodnik po Xfce 4.6 jest również nadal dostępny.

Thunar - menadżer plików

Zdalne przeglądanie współdzielonych plików

Thunar posiada teraz wsparcie dla GVFS, dzięki czemu możliwe jest przeglądanie zdalnych współdzielonych zasobów używając Thunara oraz serwerów: FTP, Windows Shares, WebDav i SSH.

zrzut ekranu

Nowe okno dialogowe postępu operacji plikowych

Kiedy kilka operacji plikowych (kopiowanie lub przenoszenie) jest wykonywanych równolegle, Thunar teraz pokaże pojedyncze okno dialogowe, które będzie zawierało wszystkie zagregowane informacje.

zrzut ekranu

Przycisk usunięcia dla urządzeń przenośnych

Jest teraz możliwe usunięcie zamontowanych urządzeń poprzez kliknięcie na przycisk usunięcia (eject) w pobliżu nazwy urządzenia przenośnego w panelu bocznym.

zrzut ekranu

Panel Xfce

Panel Xfce w wersji 4.8 został całkowicie przepisany. Poniżej najbardziej zauważalne zmiany.

Ulepszone pozycjonowanie oraz zarządzanie rozmiarami

Xfce panel posiada teraz znacznie lepsze wsparcie dla pozycjonowanie poszczególnych paneli na ekranie. Mogą one być przeciągane i przyklejane do krawędzi ekranu. Pozycja jest zapamiętywana przy przeciąganiu panelu a sam panel może posiadać szerokość określaną w procentach długości ekranu.

Przezroczyste tła

Panel umożliwia teraz ustawienie przezroczystości jego tła jednocześnie pozostawiając jego elementy nieprzezroczystymi. Twoje panele pozostaną więc czytelne a jednocześnie ładnie wyglądające.

zrzut ekranu

Nowe edytor elementów

Nowa funkcjonalność panelu - edytor elementów - pozwala na szybką modyfikację, przesuwanie, dodawanie i usuwanie elementów. Jest to funkcja szczególnie użyteczne dla pojedynczych elementów, których nie trzeba już przeklikiwać kolejno prawym klawiszem, aby wyedytować ich zawartość. Wszystkie elementy oraz ich układ mamy dostępne w jednym miejscu.

zrzut ekranu

Tworzenie aktywatorów metodą przeciągnij i upuść

Możesz teraz przeciągnąć i upuścić elementy z menu aplikacji, wyszukiwacza aplikacji lub Thunara wprost na panel, aby utworzyć aktywator. Ta funkcjonalność powinna zadowolić sporą rzeszę użytkowników, którzy domagali się jej od lat. Aktywatory mają również zintegrowany wyszukiwacz aplikacji, który przydaje się przy dodawaniu kolejnych elementów.

Wtyczka przycisków okien

Wtyczki "Ikony okien" oraz "Lista okien" zostały teraz połączone w jedną wtyczkę o nazwie "Przyciski okien". Zawiera one inne metody sortowania ulepszone działanie w pionowych panelach oraz umożliwia stworzenie podobnej ramki jak Xfwm4 podczas przełączania Alt+tab, kiedy najedzie się na przycisk.

Nowy rozmyty zegar

Nowe wydanie Xfce bez nowego trybu zegara nie było by prawdziwym wydaniem. Pozwólcie nam przedstawić nowy "rozmyty tryb" zegara!

zrzut ekranu

Nowa wtyczka - menu katalogów

Wtyczka menu katalogów dostarcza nowe menu odwzorowujące układ każdego katalogu. Pozwala to na otwarcie konsoli lub menadżera plików w danym podkatalogu w bardzo szybki i efektywny sposób.

zrzut ekranu

Edycja manu aplikacji

Możesz teraz edytować menu za pomocą każdego zgodnego z Freedesktop edytora. Do naszych testów użyliśmy Alacarte.

Dialogi ustawień Xfce

Ulepszona konfiguracja multihead setup

Xfce wspiera teraz multihead setup dla każdego zgodnego z randr 1.2 sterownika. Niestety oznacza to, że nie zadziała na własnościowych sterownikach Nvidii.

Możesz aktywować lub dezaktywować dołączane ekrany, ustawiać ich rozdzielczość, częstość odświeżania, kąt obrotu oraz odbicie, klonować oraz rozciągać ekrany.

Czasowe potwierdzenie

Wszelkie zmiany potwierdzane za pomocą okna dialogowego ustawień muszą zostać zaakceptowane w przeciągu 10 sekund. W przeciwnym wypadku zostaną cofnięte. Zapobiegnie to uszkodzeniu np. sterowników wideo podczas nieobecności przy komputerze.

zrzut ekranu

Szybkie okno ustawień

Szybkie okno ustawień pozwala skonfigurować podwójny ekran w kilka sekund. Podłącz drugi ekran, naciśnij klawisz display lub Windows+p i wybierz żądany układ. Gotowe!

Edycja ustawień za pomocą edytora ustawień Xfce

Edytor ustawień Xfce teraz w pełni zasłużył na swoją nazwę. Nie jest on już zwykła przeglądarką ustawień (Xfconfig). Możesz teraz modyfikować, dodawać i przywracać ustawienia poprzez interfejs. Potrafi on także monitorować i na bieżąco aktualizować widok.

zrzut ekranu

Usprawniona sekcja układu klawiatury

Widok sekcja układu klawiatury otrzymał sporo miłości. Nie pokazuje już zaszyfrowanych kodów język/wariant ale używa tłumaczonych nazw języków. Edycja układu klawiatury stała się również łatwiejsza poprzez wypełnianie pól przez aktualne wartości.

zrzut ekranu

Flash player i pseudo-strumień MP4

Kodowanie Linux Software Techblog 10 stycznia 2011 o 19:07:34 | ☍ trackback

Co jakiś czas przychodzi mi osadzać na stronach pliki FLV z jakimś Flashowym playerem. Oczywiście nie ma z tym żadnego problemu, jednak obecnie nadciąga moda na pliki MP4 kodowane przez h264. Flash od wersji 9 umożliwia odtwarzanie tego typu plików jednak jest ale. Żeby Flash zaśpiewał jak mu MP4 zagra, potrzebuje wyciągnąć z niego metadane (w tym cały indeks zawartości pliku) czyli tzw. obszar Moov Atom. Problem w tym, że większość enkoderów beztrosko umieszcza metadane na końcu pliku MP4.

Rezultatem tej złotej myśli technologicznej jest to, że plik MP4 musi zostać w całości pobrany, zanim jakiś Flash player go zdoła otworzyć. Z małymi plikami to nie problem, jednak kazanie użytkownikowi czekać na pobranie 200 MB pliku, zamiast oglądać go w trakcie ściągania jak w przypadku plików FLV, to powrót do epoki, w której to strony zdobione były tagami <marquee>.

Wyjścia innego nie ma jak złapać za uszy metadane i przeciągnąć je na początek pliku. Na szczęście FFMPEG dostastarcza do tego celu gotowy skrypt o nazwie qt-faststart. Jego użycie raczej nie przysporzy nikogo o ból głowy.

qt-faststart in.mp4 out.mp4

Dla !linuksiarzy pozostaje skorzystanie z aplikacji dla Adobe AIR, lub przygarnięcie klasy dla PHP5.

GIODO a serwis internetowy

Internet Techblog 22 września 2010 o 23:02:05 | ☍ trackback

Notka poświęcona osobom, które chcą stworzyć serwis internetowy zgodny z wytycznymi GIODO. Uwaga, dla osób postronnych notka może objawić się jako absurdalny bełkot.

Jak stworzyć serwis internetowy, na którym GIODO-mucha nie siada? Nie mam pojęcia! Ale mam nadzieję, że razem uda nam się coś wypracować. Aby przejść podstawowy tutorial absurdu należy zapoznać się z 8 minutowym filmem, stworzonym przez lookr.tv, na którym Generalny Inspektor Ochrony Danych Osobowych, niczym profesor Miodek odpowiada na pytania zatroskanych internautów:

[...] no ja takiego problemu proszę Państwa nie mam, dlatego że wiem, że definicja dotycząca tego co jest daną osobową jest definicją otwarta [...] dlatego każdy przypadek należy dokładnie analizować, czy informacja jest daną osobową czy też nie.

Mnie również cieszy, że wszystkie kwestie zostały już dogłębnie wyjaśnione. W końcu od tego jest ten Pan, od tego on jest, od tego jest on.

[...] tak rzeczywiście, zgadza się, informacje które wymagają dużego nakładu czasu i pracy nie uważa się za dane osobowe, aczkolwiek należy zawsze pamiętać o tym, że dla mnie jakieś informacje mogą powodować, że będę musiał użyć dużego nakładu czasu i pracy, natomiast dla kogo innego to będzie bardzo proste aby powiązać te informacje z konkretną osobą i o tym proszę zawsze pamiętać.

Wiec jeżeli konkurs ortograficzny wygra Gniewomir z Kozich piętek, a mieszkańcy Kozich piętek będą doskonale wiedzieli, że w ich miejscowości mieszka tylko jeden Gniewomir to z ich punktu widzenia będzie to oczywista publikacja danych osobowych. Zły przykład? Więc weźmy numer IP Gniewomira. Dla większości ludzi na świecie będzie to nic nie mówiący numer, ale nie dla ISP-a z Kozich piętek, który dostarcza internet całym 3 osobom. Bez większych trudności ustali kto kiedy korzystał z danego IP-ka.

[...] rzeczywiście my stwierdzamy, że co do zasady IP komputera jest daną osobową, ale są wyjątki, które powodują, że w pewnych momentach nie można uznać IP komputera za dane osobowe [...]

Tutaj mamy w działaniu zasadę łaskawego wykluczenia, czyli na wszelki wypadek wszystkie numery IP trzeba traktować jako dane osobowe, ale dzięki łasce naszego prawa będziemy mogli zignorować 5 adresów IP, co do których jesteśmy pewni, że nie są to dane osobowe. Oczywiście pozwoli to oczywiście na znaczne oszczędności w nakładach na ochronę danych osobowych.

Mało Wam jeszcze? Nie ma problemu - temat rzeka.

Zajrzyjmy np. w ten zakamarek strony GIODO. Można tutaj wyłowić takie coś:

dostawcy usług internetowych oraz menedżerowie lokalnych sieci mogą, stosując rozsądne środki, zidentyfikować użytkowników internetu, którym przypisali adresy ip ponieważ systematycznie zapisują w plikach daty, czas trwania oraz dynamiczny adres IP (czyli ulegający zmianie po każdym zalogowaniu) przypisany danej osobie. To samo odnosi się do dostawców usług internetowych, którzy prowadzą rejestr (logbook) na serwerze HTTP Nie ma wątpliwości, że w takich przypadkach można mówić o danych osobowych, w rozumieniu art. 2 Dyrektywy

Macie Apache z włączonym logowaniem połączeń? Gratulacje, jesteście szczęśliwymi posiadaczami bazy danych osobowych. Na szczęście podobno logi są zwolnione z obowiązku rejestracji zgodnie z zasadą przetwarzania ich "w zakresie drobnych bieżących spraw życia codziennego". [źródło]

Po więcej można sięgnąć do dokumentu ABC zagrożeń bezpieczeństwa danych osobowych w systemach teleinformatycznych (na samym dole). Z tego dokumentu głoszącego radosną nowinę możemy szybko dowiedzieć się, że również adres e-mail może (ale nie musi (i co że nie musi?!)) być daną osobową. Mój e-mail - tomasz // karbownicki.com - z pewnością można uznać za daną osobową. Natomiast na stronie 24 dowiemy się, że również nick może być daną osobową, bo jeżeli ktoś podpisze się jako "Gniewomir z Kozich piętek" to mamy daną jak w mordę strzelił. Nawet jeżeli ktoś podpiszę się (nick) jako "Adam Kowalski z Opola, ul. Krakowska 907/34" i nie mamy pojęcia czy taka osoba w ogóle istnieje to i tak należy uważać to za daną osobową, do momentu aż będziemy wiedzieli, że taka osoba nie istnieje. Wówczas możemy z czystym sumieniem wykluczyć taką daną z naszego zbioru ściśle chronionych danych osobowych, dzięki czemu oszczędzimy oczywiście góry złota i lata pracy.

Ale wróćmy do budowy serwisu internetowego. Skoro wiemy już, że niemal wszystko co wpisze użytkownik może być daną osobową, możemy przystąpić do projektowania serwisu z uwzględnieniem mechanizmów ochrony danych osobowych. Oczywiście nawet jak użytkownik nic nie wpisze tylko wejdzie na stronę to i tak mamy jego IP w logu Apache'a, wiec za wiele do szczęścia nie trzeba (-;

Na początek musimy mieć serwer posiadający odpowiedni certyfikat, że spełnia on wszystkie wymogi wynikające z przepisów i jest gotowy do przechowywania na nim danych osobowych. Kiedy już znajdziemy taki serwer czas powitać "Wymagania dotyczące struktur baz danych osobowych oraz funkcjonalności zarządzających nimi aplikacji".

Art. 32 ust. 1 pkt. 5 w powiązaniu z §7 ust. 1 pkt. 4 rozporządzenia, stawia w odniesieniu do struktury bazy danych oraz aplikacji zarządzającej zbiorem danych osobowych wymaganie posiadania opcji umożliwiającej rejestrację daty, zakresu i sposobu udostępniania danych odbiorcom (w myśl art. 6 pkt. 7 ustawy), jeśli konieczność takiego udostępnienia wynika z przepisów prawa lub jest przewidziana przez administratora danych.

Jest to jak dla mnie najbardziej niedorzeczna część, która może sprawić, że mechanizmów tych będzie tyle samo co pozostałej części serwisu! Bo jeżeli nick może być daną osobową, to musimy zarejestrować każde udostępnienie komuś nicka. Załóżmy, że mamy widok strony głównej forum, gdzie obok tematów mamy nicki autorów ostatniego posta w wątku.

Forum ArchLinux

Wówczas każde odświeżenie strony wiąże się z koniecznością odnotowania w logu tego, że o godzinie XX:YY panu A zostały udostępnione dane: nick pana B, nick pana C, nick pana D ... Nie wspominając już o bardziej skomplikowanych stronach składających się z różnych elementów, z których każdy może zwierać dane osobowe. Dajmy na to stronę główna joggera.

Jogger - główna

Mamy tam listę najnowszych wpisów wraz z nickami autorów, najpopularniejsze wpisy razem z nickami autorów oraz najczęściej komentowane wpisy razem z nickami autorów. Teraz wyobraźmy sobie, że każdy taki element generuje jednego inserta do loga udostępniania danych osobowych i już mamy 3 inserty do bazy na każde odświeżenie strony (-: Nawet nie myślcie o bardziej skomplikowanych portalach :D Dołóżmy to, że każda zmiana w szablonie, która wprowadza wyświetlenie się np. nicka, e-maila wiąże się z odpowiednią modyfikacją mechanizmu logującego udostępnianie danych. Tym sposobem szybko odechce się każdemu tworzenia nowych widoków.

Na koniec zajrzyjmy jeszcze do "ABC zagrożeń bezpieczeńswtwa ...". Na stronie 85 znajdziemy rozdział "Zabezpieczenie elektronicznych formularzy". Na stronie 86 znajdziemy takie zdanie:

Ponadto transmisja danych między systemem administratora a komputerem rejestrującego się użytkownika powinna być zabezpieczona przy użyciu kryptograficznych środków ochrony danych (np. poprzez zastosowanie protokołu SSL).

O ile dobrze rozumiem to jeżeli przesyłamy do systemu swoje dane osobowe musimy tą transmisję zabezpieczyć np. poprzez SSL. Zestawmy to teraz z innymi danymi osobowymi, którymi jak wiemy mogą być np. adresy e-mail. Czy każdy formularz subskrypcji newslettera musi iść po SSL-u? Czy każdy formularz do napisania komentarza gdzie przesyłamy swój nick (dana osobowa) musi iść po SSL-u?

Chciałem zebrać dzisiaj wszystkie informacje niezbędne do postawienia serwisu zgodnego z GIODO. Niestety poległem :-( Z moich dotychczasowych ustaleń wynika, że nakład pracy potrzebny na ochronę danych osobowych sprawia, że zadanie stanie się niewykonalne. Dlatego będę wdzięczny za wszelkie informacje od Was dotyczące tego tematu. Może ktoś z Was postawił już coś takiego jak serwis zgodny z GIODO lub przynajmniej przeszedł kontrolę i wie co można olać...

PS. Proszę nie komentować tej notki bo formularz nie ma SSL-a a ja nie jestem pewien czy serwerownia Joggera ma odpowiednie certyfikaty ;-)

Rzecz o przyszłości internetu

Inne Internet Techblog 19 czerwca 2010 o 00:29:06 | ☍ trackback

Tekst ten spisuje w dużej mierze z własnej ciekawości, aby czytając go za kilka lat móc sprawdzić jak na ile trafnie udało mi się przewidzieć przyszłość.

Creative Commons (by-nc-nd) - JaulaDeArdilla Będąc w podstawówce czasami mogłem całe dnie przesiedzieć na klepaniu przeróżnych programów w BASIC-u na moim postkomunijnym Commodore 64 (pozdrowienia dla fanów C&A). Kiedy jednak nastała era PC a ja zacząłem szperać po internecie czy to u kumpli czy w kawiarenkach, wówczas zauważyłem, że mój nie podłączony do internetu komputer stawał się coraz mniej użyteczny. Oczywiście nadal można było zrobić na nim 1k przeróżnych rzeczy jednak był jakiś taki... pusty. Wtedy zdałem sobie sprawę, że internet to przyszłość, bez której nie będzie można niedługo żyć. Brak internetu będzie równie odczuwalny jak brak prądu.

Kiedy poszedłem do technikum, do klasy informatycznej, postanowiłem wybrać sobie jakiś język programowania, w którym zacznę się szkolić, tak aby na studiach a później w pracy zawodowej mieć już go w małym palcu. W tamtych czasach w królestwie programowania prym wiodły takie języki jak C, C++ czy Delphi, w których to można było naklepać jakiś programy użytkowe, które wówczas były w cenie. Ja jednak nie widząc innej przyszłości poza internetem postawiłem na naukę tworzenia dynamicznych stron internetowych i związanych z nimi języków skryptowych od PHP poczynając.

Na studiach zauważyłem, że moja wizja przyszłości szybko się wypełnia. Coraz więcej polskich firm zaczęło dostrzegać potencjał internetu. Każda firma chciała mieć własną stronę internetową, które stopniowo z prostych HTML-owych wizytówek zaczęły przekształcać się z coraz bardziej zaawansowane systemy zarządzania treścią, ewidencji sprzedaży czy wspomagania zarządzaniem. Te coraz bardziej funkcjonalne systemy szybko zaczęły przyjmować funkcje aplikacji desktopowych stopniowo je zastępując (stan na dzień dzisiejszy).

Creative Commons (by-nc-nd) - taberandrew Do zalet aplikacji internetowych nie muszę chyba nikogo przekonywać. Świadczy o tym chociażby fakt, że za ich pomocą ja piszę ten tekst a Wy go czytacie (i za chwilę skomentujecie). Poza tym większość z Was zapewne używa np. internetowego klienta poczty, który automagicznie się aktualizuje, naprawia, zyskuje nowe funkcje czy backupuje. Jest to ogromna przewaga nad aplikacjami desktopowymi, które mogą przestać działać na 100 sposobów (wirusy, utrata danych, awaria jednego z wymaganych komponentów systemowych), natomiast póki działa Wam przeglądarka (a do tego nie trzeba wiele) do puty będą działały aplikacje internetowe (mówię oczywiście cały czas o przeglądarkowych aplikacjach).

Ok, więc mamy stan na dzień dzisiejszy, ale co dalej? Otóż moim zdaniem następnym krokiem będzie zmniejszenie roli komputerów osobistych na rzecz internetowych chmur czyli olbrzymich farm serwerów. Dowody takiego trendu możemy znaleźć już teraz. Wystarczy sprawdzić jaki komputer szybciej przeszuka zasoby internetu - nowe 8-rdzeniowe cacko czy stary pentium 500MHz? Oczywiście zrobią to w tym samym czasie bo zamiast robić to same zapytają o to serwerownie Googla. A który z nich znajdzie szybciej mail od kumpla sprzed 3 miesięcy? Oczywiście żaden, bo zajmą się tym serwery Googla na których operuje Gmail. Przykładów jest oczywiście znacznie więcej, można przecież zapytać który poradzi sobie lepiej z konwersją wideo wrzucanego na YouTube. Oczywiście jest to kolejne niewłaściwie zadane pytanie bo żaden z nich nie zajmuje się już konwersją, robią to internetowe serwery. A kto zaczyna wykrywać nam teraz wirusy znajdujące się na dopiero co podłączonej pamięci USB? Nie, nie nasz antywirus ale zewnętrze oprogramowanie antywirusowe przebywające w chmurach, do których lekki klient, działający w naszym systemie, wysyła próbki do analizy.

Przyszłość jest w chmurach Widzimy więc, że kolejnym naturalnym krokiem na tej ścieżce jest odchudzenie komputerów osobistych do roli wyłącznie klientów internetowych chmur (patrz Chrome OS). Oczywiście nadal pozostają programy, których nie da się póki co wyprzeć z desktopów. Bo jak zastąpić programy typu Photoshop, CAD, programy do obróbki wideo czy zaawansowane graficznie gry przez aplikacje przeglądarkowe. To rzecz jasna nie stanie się w najbliższych latach, chociażby dlatego, że nie istnieje jeszcze odpowiednia technologia, w której te aplikacje mogły by powstać. IMO HTML5 dopiero będzie w stanie zapewnić dobry budulec dla aplikacji internetowych typu pakiety biurowe, a do reszty jeszcze daleko. Co prawda rzeczami typu Flash czy WebGL będzie się dało zapchać wiele dziur jednak gra napisana w WebGL choć do działania będzie wymagała wyłącznie przeglądarki to jednak całość operacji graficznych nadal pozostanie do wykonania po stronie klienta.

Creative Commons (by-nc-nd) - stadtstreicher79 Na końcu dochodzimy więc do punktu, w którym wszelkie operacje wymagające większej mocy obliczeniowej przerzuconą zostaną do chmur. Widzę to na podobnej zasadzie jak odbywają się sesje VNC. Nasz komputer będzie logował się do najbliższego nam centrum cyfrowego i stamtąd otrzyma gotowy do wyświetlenia na monitorze obraz. Zalet takiego systemu jest wiele. Po pierwsze znika problem skalowalności. Obecnie rynek gier komputerowych jest w znacznym stopniu motorem napędowym do zmiany podzespołów komputerowych na nowsze. Jednak w przypadku centrów cyfrowych problem ten nie istnieje. Jeżeli tylko będziemy chcieli pograć w najnowszą grę to po prostu w nią pogramy ponieważ system będzie miał do dyspozycji olbrzymie zasoby obliczeniowe, które będzie przydzielał użytkownikom w zależności od ich zapotrzebowania. Chociaż centra cyfrowe wydają się trochę nierealnym pomysłem to jednak nie odbiegają one za bardzo od dzisiejszych sieci energetycznych. Każdy z nas będzie podłączony do najbliższego centrum cyfrowego podobnie jak obecnie podłączony jest do najbliższej elektrowni i każdy będzie otrzymywał tyle mocy obliczeniowej ile aktualnie potrzebuje (podobnie jak z energią elektryczną). Z tej perspektywy sprawa wygląda już całkiem normalnie. Kolejna ogromna zaleta jest taka, że podobnie jak teraz wykwalifikowani pracownicy obsługują elektrownie, również specjaliści od sprzętu będą obsługiwali centra obliczeniowe. To zupełnie tak jak by każdy z nas miał w domu własnego informatyka. Skończą się zawirusowane systemy działające na ćwierć gwizdka, z którymi zwykły użytkownik nie daje sobie rady. Poza tym aktualizacja takiego centrum cyfrowego będzie wiązała się z wymianą macierzy dyskowej klasy 1 na macierz klasy 2, czy wymianą jednostki głównej posiadającej 4k procesorów klasy 1 na jednostkę z 100k procesorów klasy 2 i po bólu. Wreszcie komputerami zajmą się specjaliści a użytkownikom pozostanie... użytkowanie :-)

Co do zestawów komputerowych do szacuję, że będą one składały się wyłącznie z monitora, myszki i klawiatury (o ile ktoś nie wymyśli czegoś bardziej poręcznego) oraz urządzeń peryferyjnych typu kamera czy drukarka. Będą one spięte ze sobą siecią bezprzewodową. Wszystko inne znajdowało będzie się w chmurach. Ktoś spyta a co np. ze zgrywaniem zdjęć z aparatu skoro nie będziemy mieli obudowy komputera do której można będzie wsadzić kabel USB czy kartę pamięci. Otóż sprawa jest prosta, wszelkie urządzenia peryferyjne będą również klientami sieci internet i będą przesyłały dane prosto do chmur, a więc żadna obudowa z portami nie będzie nam potrzebna.

Na tym już zakończę moje przemyślenia co by niepotrzebnie nie wydłużać tekstu. To jak, kto się założy, że tak będzie? :-)

Google Font API

Internet Techblog 19 maja 2010 o 23:29:27 | ☍ trackback

Google pchnął dzisiejszego dnia sieć o dobre kilka kroków do przodu. Nie dość, że pojawił się projekt WebM, który prawdopodobnie raz na zawsze wydrze internetowe wideo z rąk Adobe i odda w ręce standardów, to jeszcze udostępniona dziś usługa Google Font API ma zamiar wzbogacić wreszcie strony w nowe fonty! Koniec cudowania z podmieniamiem tekstu przez obrazki, Flasha, canvasa czy inne cuda na kiju. Wreszcie wygląda to maksymalnie prosto i przejrzyście.

Wystarczy wybrać czcionkę z katalogu, wstawić odnoszący się do niej nagłówek:

‹link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz' rel='stylesheet' type='text/css'›

I już możemy korzystać z czcionki w CSS-ie:

h1 { font-family: 'Yanone Kaffeesatz', arial, serif; }

Wynik:
Wynik

No wreszcie! Czyżby Google nadrabiało za wpadkę z WIFI?

PlayFlash czyli YouTube i MPlayer

Internet Linux Techblog 19 maja 2010 o 22:14:39 | ☍ trackback

Jak wiemy VP8 jest już w drodze, jednak do czasu pełnego wdrożenia pozostanie nam jeszcze użerać się z Flashem na nie bardzo wspieranych przez Adobe platformach tj. Linux czy Mac. Ułomność obsługi Flasha widoczna jest zwłaszcza przy wideo w wyższych rozdzielczościach.

Powstało już wiele rozwiązań tego problemu jak np. podmiana playera Flashowego na MPlayera lub wywoływanie w konsoli skryptów, które jako parametr dostają adres URL do filmu na YouTube.

Rozwiązania te nie są jednak jak dla mnie zbyt wygodne, ponieważ MPlayer nie jest w stanie zastąpić playera Flashowego, z racji tego, że np. nie zbuforuje filmu od wybranego fragmentu czy też nie umożliwi nam zmiany rozdzielczości filmu. Natomiast uruchamianie skryptu z podaniem mu adresu URL jest co by nie mówić nieporęczne, bo po co klikać dziesięć razy skoro można dwa.

Wiadomo, że ładujący się film z YouTube'a tworzy plik w katalogu /tmp/ o nazwie FlashXX... Wystarczy więc wyłapać najnowszy plik z tego katalogu o takiej nazwie i uruchomić go za pomocą naszego ulubionego odtwarzacza. Całe sterowanie można wykonać za pomocą standardowego Flashowego playera YouTube np. wybór rozdzielczości i ustawienie odpowiedniego miejsca startu filmu (np. od 2 minuty) a później skryptem ukrytym w ikonce lub skrócie klawiszowym uruchomić nasz natywny player i rozsiąść się wygodnie w fotelu.

Skrypt jest banalnie prosty:

/usr/bin/mplayer /tmp/`ls /tmp/ -tr | grep Flash | tail -1`

Ja mam go podpięty pod ikonkę dzięki temu używanie wymaga dwóch kliknięć (pauza w playerze YouTube i odpalanie skryptu).

PlayFlash w akcji

Snippety dla webdevelopera

Kodowanie Linux Techblog 13 maja 2010 o 19:24:46 | ☍ trackback

Od czasu publikacji poprzedniej porcji snippetów dla mojego ulubionego edytora Geany minęło okrągłe 2 lata i 6 dni. Przez ten czas snippety uległy ewolucji (wykorzystuję je codziennie) jak również nowsze wersje Geany pozwoliły na umieszczenie w snippecie więcej niż jednej pozycji kursora.

Z racji tego, że pracuję jako webdesigner/programista/administrator oprócz zestawu HTML-a dodałem również kilka skrótów dla CSS-a oraz szczyptę udogodnień dla Django (głównie modele i szablony). Scaliłem również inne dostępne dla Geany snippety m.in. dla PHP, Pythona, LaTeX-a i Tlc oczywiście (z informacjami o ich autorach). Prawdę mówiąc, miałem nadzieję, że w ten sposób będzie można uporządkować dodatki na stronie Geany, tak aby do pobrania był jeden plik a z boku zbiorowa informacja o autorach, no ale z autorami strony trochę trudno się dogadać. Już nawet dorwałem ich bezpośrednio na IRC-u ale widocznie godzina była za późna i już mało kontaktowali.

W każdym razie dzięki Dropboksowi plik będzie teraz leżał zawsze w tym samym miejscu i w razie czego będzie na bieżąco aktualizowany, ponieważ mam go podpiętego bezpośrednio pod edytor.

snippets.conf

W szybki sposób można je pobrać tak:

$ wget http://dl.dropbox.com/u/668529/conf/snippets.conf -O ~/.config/geany/snippets.conf

Tradycyjnie dołączam mały przegląd. Oczywiście tylko pobieżnie.

Autorzy snippetów:

  • PHP - Atanas Beloborodov
  • Python - inspirowane snippetami z Gedita
  • LaTeX - Frank Lanitz
  • Tlc - Witek Mozga

Automatyzacja myszy i klawiatury

Linux Software Techblog 07 stycznia 2010 o 22:41:56 | ☍ trackback

Jak wiadomo Linux znany jest z tego, że można tutaj zautomatyzować niemalże wszystko. Zazwyczaj robimy to za pomocą skryptów Basha, Perla czy innego Pythona. Są jednak przypadki, kiedy nie bardzo mamy dojście do API czy komend aby zautomatyzować jakiś proces. Bo jak zautomatyzować np. ruch myszy w środowisku graficznym czy zasymulować wciskanie klawiszy?

Drugą rzeczą, z której znany jest Linux jest to, że zawsze znajdzie się rozwiązanie ;-) Podobnie w tym przypadku rozwiązaniem naszym problemów jest pakiet xautomation (spaczkowany w większości dystrybucji). Dostarcza on bardzo pomocnej komendy jaką jest xte. Podstawowymi parametrami tej komendy są:

key k          Wciśnięcie klawisza k
keydown k      Przytrzymanie klawisza k
keyup k        Zwolnienie klawisza k
str string     Wpisanie ciągu znaków
mouseclick i   Wciśniecie lewego klawisza myszy
mousedown i    Wciśniecie lewego klawisza myszy
mouseup i      Zwolnienie lewego klawisza myszy
mousemove x y  Przemieszczenie kursora na pozycję (x,y)
mousermove x y Względne przemieszczenie kursora na pozycję (x,y)
sleep x        Odczekanie x sekund

Dzięki zastosowaniu tych komend możemy już zautomatyzować wyklikiwanie pewnych czynności, np. głupiej ankiety internetowej lub pajacyka. Swojego czasu używałem tego do łączenia się z ukrytą siecią Wifi, której Gnomowy Network Manager za nic nie umiał mi zapamiętać. Zamiast wyklikiwać codziennie szereg opcji i po raz setny wpisywać długie wygenerowane hasło klikałem tylko w skrypt, który robił wszystko za mnie.

Przykładowy skrypt powtarzający pewną czynność w nieskończoność może wglądać tak:

#!/bin/bash
while [ 1 ]
do
    sleep 1
    xte 'mouseclick 1'

    # otwórz Chrome w trybie porno
    xte 'keydown Control_L' 'keydown Shift_L' 'key n' 'keyup Shift_L' 'keyup Control_L'
    sleep 1

    # wybierz adres
    xte 'str http://...wybierz_polskiego_polityka_roku_2009...'
    xte 'key Return'

    # czekamy na wczytanie strony
    sleep 7

    #wybierz kandydata
    xte 'mousemove 44 490'
    xte 'mouseclick 1' 

    # głosuj
    xte 'mousemove 253 710'
    xte 'mouseclick 1' 
    sleep 1

    # zamknij Chrome
    xte 'keydown Alt_L' 'key F4' 'keyup Alt_L'
done

Dla ułatwienie sobie życia możemy skorzystać z komendy xmousepos, dzięki której nie będziemy musieli zgadywać pozycji kursora. Wystarczy ustawić kursor w odpowiednie miejsce a następnie uruchomić podaną komendę aby uzyskać pozycję kursora, np:

tomek@Arch:~$ xmousepos
1125 136 1125 110
^^ dwie pozycje, bo każdy kij ma dwa końce

W każdym razie miło wiedzieć, że mamy możliwość zautomatyzowania kolejnej czynności ;-)

I <3 Linux

Configer.net - pokaż swoje configi

Configer Projekty Techblog 29 grudnia 2009 o 21:10:52 | ☍ trackback

Przyszedł koniec roku, w pracy zrobiło się troszkę luźniej, a więc to dobry czas na własne projekty :-) Nie, nie startupy. Nie lubię startupów. Startup to dla mnie czasownik mówiący o tym, jak jakiś autor (sam nie przekonany do swojego pomysłu) próbuje na siłę przekonać wszystkich, że funkcjonalność którą stworzył jest im niezbędna do życia :-/ Dlatego o wiele bardziej preferuje aplikacje o charakterze narzędziowym, w którym społeczność tylko zwiększa użyteczność samego narzędzia.

Tak więc z potrzeby posiadania narzędzia narodził się configer.net. Cała idea polega na przechowywaniu tam własnych (czasami godzinami dopieszczanych) plików konfiguracyjnych oraz podglądanie tego co wykombinowali inni. Oczywiście z możliwością dołożenia swoich 5 groszy w postaci komentarza. Dla parówkowych skrytożerców przewidziana jest opcja prywatnego configa, czyli dostęp do niego ma wyłącznie autor, więc nie koniecznie trzeba się zaraz dzielić swoimi wyczynami.

configer.net

Żeby maksymalnie ułatwić korzystanie z serwisu nie trzeba się nawet rejestrować. Wystarczy że zalogujemy się za pomocą OpenID, Googla, Facebooka lub Yahoo! (przecz z rejestracjami!). Mam nadzieję, że serwis kilku gikom się przyda. Jeżeli nie - trudno - to nie startup, nie musi podbijać serc ;-)

Napisy końcowe: w projekcie udział wzięli - trójkąt, Jaro, Lotos (via pdll.pl) oraz <3 Django.

Sumowanie statystyk Google Analytics

Kodowanie Python Techblog 20 listopada 2009 o 23:30:37 | ☍ trackback

Zawsze mnie ciekawiło jaki jest ruch na naszym firmowym serwerze ale nie chciałem obciążać maszyny dodatkowym oprogramowaniem, które by to zliczało. Zwłaszcza że każda hostowana przez nas strona jest podpięta pod Google Analytics. Nie znalazłem jednak sposobu aby w panelu statystyk wyświetlić sumę odwiedzin z kilku kont. Na szczęście Analytics podobnie jak większość usług Googla ma swoje API. Wystarczyło więc zaprząc do pracy Pythona oraz bibliotekę gdata.

Użytkownikom ArchLinuksa polecam paczkę python-gdata-svn

yaourt -S python-gdata-svn

Skrypt jest dość prosty i działa w konsoli:

#!/usr/bin/python

import datetime
import sys

import gdata.analytics
import gdata.analytics.service


def main(argv):

    GOOGLE_ANALYTICS_LOGIN = 'TWOJE@KONTO'
    GOOGLE_ANALYTICS_PASSWORD = 'TAJNE_HASLO'

    if len(argv) > 1:
        d = argv[1].split('-')
        data = datetime.date(int(d[0]), int(d[1]), int(d[2]))
    else:
        data = datetime.datetime.now()

    print "\ndata: %d-%d-%d" % (data.year, data.month, data.day)
    print "\nodw\tods\tdomena"
    print "--------------------------"

    dc = gdata.analytics.service.AnalyticsDataService()
    dc.ClientLogin(GOOGLE_ANALYTICS_LOGIN, GOOGLE_ANALYTICS_PASSWORD, account_type='GOOGLE')
    a = dc.GetAccountList()

    odwiedziny, odslony = [], []

    for b in a.entry:
        tid = b.id.text.replace('http://www.google.com/analytics/feeds/accounts/','')
        query = dc.GetData(
            ids=tid, 
            start_date='%.4d-%.2d-%.2d' % (data.year, data.month, data.day), 
            end_date='%.4d-%.2d-%.2d' % (data.year, data.month, data.day), 
            metrics='ga:visitors,ga:pageviews',
            dimensions='ga:day'
        )
        odw = int(query.entry[0].visitors.value)
        ods = int(query.entry[0].pageviews.value)
        odwiedziny.append(odw)
        odslony.append(ods)
        print "\033[1;31m%d\t%d\033[0m\t\033[33m%s\033[0m" % (odw, ods, b.title.text)

    print "--------------------------"
    print "%d\t%d\tRazem" % (sum(odwiedziny),sum(odslony))


if __name__ == "__main__":
    sys.exit(main(sys.argv))

Jeżeli wywoła się go bez parametrów wówczas pokaże statystyki dla dnia dzisiejszego. Można też podać mu jako parametr datę, np:

python stats.py 2012-12-21

Przykładowy wynik działania wygląda tak:
Przykład działania

Definiowanie własnych atrybutów w HTML-u

Kodowanie Techblog 05 listopada 2009 o 23:31:00 | ☍ trackback

Obecnie w czasach interfejsów napędzanych JavaScriptem coraz widoczniejszy staje się problem składowania danych w HTML-u. Prosty przykład: mamy generowany formularz, który chcemy zweryfikować za pomocą JavaScriptu. Przy generowaniu formularza posiadamy dla każdego pola zmienną mówiącą nam o tym czy to pole jest wymagane czy nie. I tu pojawia się problem, jak oznaczyć np. inputa jako pole wymagane? Struktura formularza nie daje nam miejsca na składowanie takich danych. Można kombinować z wrzuceniem jakiegoś słowa kluczowego do id. np:

id="required"

No ale id musi być niepowtarzalne, więc może klasa...

class="required"

Może, ale w sumie mam już tam kilka innych klas

class="specjalne kontrast required"

A więc czy klasa to na pewno dobre miejsce? Jasne że nie, klasa jest dla styli. No więc jak? Trzeba stworzyć własny atrybut! Niby jasne, ale przecież validator nie uznaje własnych atrybutów...

Otóż uznaje. Trzeba je tylko zadeklarować w definicji dokumentu - DTD (Document Type Definition). Załóżmy że chcemy wzbogacić nasz input w atrybut required. Wystarczy więc taka konstrukcja DTD:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" 
[
  <!ATTLIST input required CDATA #IMPLIED>
]>

Ta dekladacja zezwala atrybutowi required posiadać dowolną wartość znakową. Jeżeli chcielibyśmy ograniczyć wartość jedynie do dwóch pozycji wystarczy zastosować coś takiego:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" 
[
  <!ATTLIST input required (true|false) #IMPLIED>
]>

Ogólny schemat jest taki:

ATTLIST element atrybut typ opcjnonalnyStatus

No i gotowe. Teraz możemy zaprząc JavaScript do podjęcia odpowiednich działań na podstawie struktury dokumentu. Czyli np. w jQuery:

$('input[required='true']').PrzypilnujInteresu();

Prosto czysto i funkcjonalnie.

Materiał źródłowy:
http://www.alistapart.com/articles/customdtd/

PS. Remember remember the fifth of november...

GooglePreview dla Google Chrome

Internet Kodowanie Techblog 28 października 2009 o 22:56:02 | ☍ trackback

Google preview to moja ulubiona wtyczka rozszerzenie dla Firefoksa, bez której wyniki wyszukiwania w Googlu po prostu nie wyglądają. Wstawia ona obok każdej pozycji miniaturkę strony, a ponieważ człowiek myśli obrazami więc o wiele szybciej można namierzyć szukaną witrynę. Niestety w przeglądarce Google Chrome (która ostatnio stała się moją podstawową przeglądarką) nic takiego nie istnieje. Istnieje już jednak system rozszerzeń (chociaż ukryty) oraz podstawowa dokumentacja, więc postanowiłem sam zapchać lukę.

Na początek przyda się nam developerska wersja Chroma (nie wiem czy wersja stabilna posiada tą funkcjonalność, jeżeli tak to niech mnie ktoś poprawi). Dla użytkowników ArchLinuksa polecam paczkę z AUR - google-chrome-dev.

yaourt -S google-chrome-dev

Aby uruchomić ukryty jeszcze mechanizm obsługi rozszerzeń należy uruchomić przeglądarkę z parametrem -–enable-extensions.

google-chrome -–enable-extensions

Teraz wystarczy już tylko pobrać przygotowane przeze mnie rozszerzenie i potwierdzić chęć instalacji

ChromePreview 0.38

Od tej chwili możemy się już cieszyć pięknymi miniaturkami

wyniki wyszukiwania

O ile wszystko dobrze poskładałem to rozszerzenie powinno się samo aktualizować (w razie W). Jeżeli ktoś jest zainteresowany bebechami to dołączam pliki:

Listę zainstalowanych rozszerzeń znajdziecie wstukując do paska adresu chrome://extensions/

EDIT: rozszerzenie znajdziecie w otwartej dzisiaj bazie rozszerzeń pod adresem https://chrome.google.com/extensions/detail/behjpjkdajdecgkkamhaplpkcbkceaie

Django – personalizacja settings.py

Django Kodowanie Techblog 28 czerwca 2009 o 11:17:04 | ☍ trackback

Jak każdy djangowic dobrze wie plik settings.py przechowuje wszelkie ustawienia aplikacji począwszy od nazwy strony a na listach middleware'u czy liście zainstalowanych aplikacji skończywszy. Ponieważ zawiera on wszelkie ustawienia, musi być inny dla developera a inny dla serwera produkcyjnego (np. z powodu tego, że developer ma DEBUG=True).

Pierwszą możliwością rozwiązania tego problemu jest ignorowanie pliku settings.py przez repozytorium kodu, tak aby różne zawartości tego pliku nie powodowały konfliktów. Wadą takiego rozwiązania jest potrzeba ręcznego edytowania tego pliku na serwerze kiedy np. dodajemy nową aplikację do INSTALLED_APPS. Moje repozytorium aktualizuje stronę na serwerze po każdym commicie, więc ręczna edycja settings.py jest męcząca.

Drugą możliwością jest stworzenie osobnych ustawień dla serwera i osobnych dla developera. Django umożliwia uruchomienie serwera z podaniem pliku ustawień jako parametr:

python manage.py runserver --settings=settings-developer.py

Wszystko wydaje się być ok. Jeżeli coś zmieniamy to dokonujemy zmiany w settings.py, settings-developer.py i po commitcie wszystko gra. Czasami jednak przy testowaniu różnych rzeczy w pliku developera można zapomnieć o settings.py i po commicie znowu strona jest rozwalona. Poza tym nie każdy developer korzysta z tych samych ustawień. Jeden używa Django Debug Toolbar inny ColorSQLMiddleware więc trzeba by zrobić tyle settings-xxx ilu developerów. A później przy zmianie czegoś globalnego edytować wszystkie...

Ostatecznym rozwiązaniem okazało się przeciążenie pliku settings.py przez ponowną deklarację zmiennych lub rozszerzenie już istniejących wartości. Jak to zrobić?

  1. Tworzymy plik, który będzie przetrzymywał nasze lokalne ustawienia, np. settings-local.py
  2. Na końcu pliku settings.py dodajemy kod:
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
execfile('%s/settings-local.py' % BASE_DIR)

Teraz w pliku settings-local.py możemy ponownie zadeklarować zmienne które mają zostać przeciążone lub rozszerzyć zadeklarowane już w settings.py listy. Np. kiedy jeden z developerów chce użyć Django Debug Toolbar dodaje do settings-local.py taki kod:

MIDDLEWARE_CLASSES += (
	'debug_toolbar.middleware.DebugToolbarMiddleware',
)

INSTALLED_APPS += (
	'debug_toolbar',
)

DEBUG_TOOLBAR_PANELS = (
	'debug_toolbar.panels.sql.SQLDebugPanel',
	'debug_toolbar.panels.headers.HeaderDebugPanel',
	'debug_toolbar.panels.cache.CacheDebugPanel',
	'debug_toolbar.panels.profiler.ProfilerDebugPanel',
	'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
	'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
	'debug_toolbar.panels.templates.TemplatesDebugPanel',
	# If you are using the profiler panel you don't need the timer
	# 'debug_toolbar.panels.timer.TimerDebugPanel',
)

Plik settings-local.py wywalamy z repozytorium i w ten sposób otrzymujemy elastyczny mechanizm współdzielenia wartości globalnych przy jednoczesnej personalizacji ustawień lokalnych.

Python i jQuery czyli pyquery

Kodowanie Python Techblog 04 maja 2009 o 15:51:57 | ☍ trackback

Ostatnio wpadł mi w ręce bardzo ciekawy moduł Pythona, który śmiało można określić jako jQuery po stronie serwera. Jeżeli potrzebowaliście kiedyś wyciągnąć jakieś dane z kodu HTML-a i denerwowała was zabawa z parsowaniem kodu za pomocą sgmllib czy innego tego typu wynalazku, to wasze cierpienia właśnie się skończyły.

Jak to działa?

Na początek pobierzemy zawartość jakieś strony, z której chcemy wyciągnąć dane. Ja posłużę się stroną antyweb.pl, ponieważ jest całkiem przystępnie zakodowana.

from pyquery import PyQuery as pq
import urllib

html = urllib.urlopen("http://antyweb.pl").read()
html = pq(html)

Teraz wystarczy już zadecydować co chcemy wyciągnąć i po prostu to zrobić :-) Np. informacje o autorze

print  html("#f li.frt").text()

Wynik:

Witaj, nazywam sie Grzegorz Marczak i jestem autorem tego bloga. Piszę tutaj o serwisach spolecznosciowych, nowych technologiach i nowych trendach w internecie.

Wyciągnięcie wszystkich kategorii

for a in html("li.categories a"):
	print a.text

Wynik:

antytydzień Biała flaga
Ciekawe strony
google
Świat
Miniblog
Mobilnie
Moje przemyślenia
Off topic
polska
Pytamy.pl
Startups
To mnie drażni.
Uncategorized
W trakcie tworzenia
wywiady

Wyszukanie najczęściej komentowanego wpisu ze strony głównej

max_comments = 0
title = ''
for a in html("ul.clnn li.l a"):
	try:
		# liczba komentarzy
		comments = int(a.text.split(" ")[1])
		if max_comments < comments:
			max_comments = comments
			# nazwa wpisu
			title = a.values()[1].replace("Komentarze do wpisu ",'')
	except:
		pass
		
print "Najwiecej komentarzy: %s" % max_comments
print "Wpis: %s" % title

Wynik:

Najwiecej komentarzy: 32
Wpis: Interia mówi, tak kupujemy ruch (bo inni też tak robią)

Więcej

To oczywiście tylko mała próbka możliwości. pyquery pozwala również na manipulację stylami (addClass, toggleClass, removeClass, attr, css) czy samą strukturą danych (append, prepend, prependTo, insertAfter, remove, replaceWith itd.). Jeżeli posiadamy moduł WebOb możemy też zaprzęgnąć do pracy Ajax.

Po więcej informacji zapraszam na stronę projektu pyquery.

Xfce 4.6 oficjalnie wydane

Linux Software Techblog 27 lutego 2009 o 05:39:37 | ☍ trackback

Poniższy tekst jest tłumaczeniem oficjalnego przewodnika po nowej wersji Xfce 4.6:

Wizualny przewodnik po Xfce 4.6.0

Długo wyczekiwana wersja 4.6.0 środowiska graficznego Xfce wreszcie została wydana. Postaramy się wyszczególnić niektóre z nowych funkcji, które zostały dodane od czasu ostatniego stabilnego wydania.

Ulepszone użytkowanie pulpitu z Xfdesktop

Od czasu kiedy w wersji Xfce 4.4 pojawiły się ikony na pulpicie, ludzie chcieli mieć możliwość jednoczesnego zaznaczania wielu ikon. W Xfce 4.6 Xfdesktop wreszcie posiada tą funkcję: można zaznaczać wiele ikon, przesuwać je, usuwać itp.

Xfce 4.6 wprowadza całkiem nowe menu pulpitu, które pozwala zarówno na manipulowanie plikami tak samo jak menu kontekstowe Thunara, jak również na otwieranie aplikacji, zakończenie sesji czy dostęp do dokumentacji.

Panel

Wiele znanych od dawna błędów zostało naprawionych w panelu Xfce4, zwłaszcza wsparcie dla wielu monitorów. Nowe wydanie przynosi też wiele ulepszeń panelowych wtyczek.

Wtyczka zegara została całkowicie przepisana, aby zużywać jak najmniej zasobów systemowych oraz pozbycia się kilku błędów wyświetlania. Wprowadzony został również nowy tryb zegara dla geeków: zegar binarny! Nowa wtyczka obszaru powiadomień pozwala na ukrywanie wybranych ikon, aby zachować porządek i przejrzystość.

Nowy mikser dźwięku

Mikser Xfce4 został przepisany od zera aby używał Gstreamer-a. Umożliwia to łatwiejsze wsparcie dla wielu systemów dźwięku, interfejs użytkownika jest bardziej dopracowany oraz można zarządzać kilkoma różnymi kartami dźwiękowymi. Dodatkowo wtyczka panelu pozwana na szybką zmianę poziomu dźwięku przy użyciu rolki myszy.

Udoskonalony menadżer sesji

Xfce 4.6 posiada udoskonalony menadżer sesji: sesje powinny startować szybciej a okno dialogowe ustawień sesji zostało przerobione aby umożliwić łatwiejsze zarządzanie uruchamianymi aplikacjami. Dodatkowo menadżer sesji automatycznie zrestartuje sesyjne aplikacje, które się „wysypały”, tak aby w przypadku wystąpienia błędu nie pozostawić użytkownika bez pulpitu, paneli czy menadżera okien.

Nowy menadżer sesji zawiera również długo wyczekiwane funkcje: wsparcie dla uśpienia i hibernacji „out of the box”. Dialog zamykania sesji posiada teraz dwa dodatkowe przyciski umożliwiające uśpienie i hibernację komputera.

Menadżer okien

Jak zwykle Xfwm4 dojrzał nieco podczas tego cyklu dystrybucyjnego: wiele błędów zostało poprawionych, dodano wsparcie dla wielu monitorów oraz ogólne osiągi zostały poprawione.

W nawiązaniu do kilku innych nowych funkcji, Xfwm4 potrafi teraz wykryć okna, które nie odpowiadają i zaoferować zabicie ich.

Pojawiło się również nowe menu, które pozawala na szybkie przesuwanie i zmianę rozmiaru okien, przemieszczenia ich na wierzch czy pod spód względem innych okien oraz przełączenie ich w tryb pełnoekranowy.

Zaimplementowana została nowa funkcja wypełniania: powiększa ona wybrane okno tak, aby zajmowało jak największą przestrzeń lecz bez przysłaniania sąsiednich okien.

Kompozytor został zoptymalizowany tak, aby zredukować miganie okien podczas zmiany ich rozmiaru.

Rozszerzono również niektóre opcje: np. można wyłączyć miganie okien gdy te otrzymują jakieś zdarzenie.

Menadżer plików

Naprawiono wiele błędów oraz poprawiono osiągi Thunar-a. Można teraz używać przycisków „naprzód” i „wstecz” na myszce (o ile są włączone) aby nawigować. Dołączono też nową wtyczkę, która pozwala na ustawienie tapety pulpitu z menu kontekstowego obrazka.

Thunar korzysta teraz ze słownika specyfikacji użytkowników – XDG. Pozwala to na wskazanie i oznaczenie folderów użytkownika tj. muzyka, dokumenty, wideo, szablony itd.

Thunar potrafi teraz wyświetlać półprzezroczyste ikony dla dysków i woluminów, które nie są zamontowane, więc można je teraz łatwo odróżnić od pozostałych.

Thunar obsługuje teraz szyfrowane urządzenia!

Nowe okno konfiguracji

Xfce 4.6 wprowadza nowe okno konfiguracji interfejsu – Xfce Settings Manager – które umożliwia konfigurację środowiska graficznego dużo łatwiej niż poprzednio. Nowe okno konfiguracji dostępne jest poprzez pojedyncze kliknięcie na ikonkę ustawień i zaprojektowane zostało jako bardziej jednolite, pozwalające szybciej oraz bardziej intuicyjnie konfigurować środowisko.

Ustawienia dostępności

Okno ustawień dostępności pozwala na konfigurację opcji związanych z klawiaturą i myszą tj. modyfikacja zachowania klawiszy funkcyjnych, czas powtarzania klawiszy, minimalny czas przytrzymania klawiszy, odstęp pomiędzy kolejnymi powtórzeniami czy emulacja myszy.

Ustawienia wyglądu

Okno ustawień wyglądu pozwala na dobór styli elementów sterujących, wyglądu ikon i czcionek, pasków narzędzi oraz wyglądu menu.

Okno ustawień wyświetlania pozwala na dobór rozdzielczości ekranu, częstotliwości odświeżania oraz rotacji każdego podłączonego ekranu.

Ustawienia klawiatury

Ustawienia klawiatury pozwalają na dorób opcji związanych z powtarzalnością klawiszy, skrótami klawiaturowymi oraz układem klawiatury.

Konfiguracja skrótów klawiszowych odbywa się teraz o wiele łatwiej a wszelkie konflikty skrótów są natychmiast wykrywane.

Ustawienia myszy

Okno ustawień myszy pozwala na konfigurację myszy podłączonej do komputera: kolejność klawiszy, akcelerację, prędkość podwójnego kliknięcia, wygląd kursora itp.

Ustawienia pulpitu

Okno ustawień pulpitu jest obecnie znacznie bardziej ujednolicone. Pozwala ono na konfigurację dla każdego ekranu: tapety, jasności, menu pulpitu, wyświetlanych ikon itp.

Nowy wyszukiwacz aplikacji

Xfce 4.6 posiada również całkiem nowy wyszukiwacz aplikacji odznaczający się przejrzystym interfejsem. Posiada również ulepszenie wyszukiwania aplikacji przy użyciu klawiatury oraz na bieżąco monitoruje zainstalowane aplikacje, dzięki czemu potrafi „w locie” uaktualnić listę aplikacji. Pozwala również na łatwiejsze tworzenie aktywatorów w panelu poprzez przeciągnięcie ikony aplikacji do okna kreatora aktywatorów.

Linki

Zasługi

  • tekst: Jérôme Guelfucci (luty 2009),
  • zrzuty ekranu: Jannis Pohlmann,
  • tłumaczenie metodą chałupniczą: – trójkąt.

Geany 0.16

Linux Software Techblog 26 lutego 2009 o 14:20:58 | ☍ trackback

Kronikarskim obowiązkiem melduję pojawienie się nowej wersji mojego ulubionego edytora Geany.

Ważniejsze zmiany:

  • cała konfiguracja została przeniesiona do ~/.config/geany. Pliki zostaną przeniesione automatycznie przy pierwszym uruchomieniu nowej wersji,
  • boczna lista symboli jest teraz drzewem,
  • minimalne wymagania zostały podwyższone do GTK w wersji 2.8
  • nowy pasek narzędzi jest teraz bardziej elastyczny i spersonalizowany. (Narzędzia > Configuration Files > ui_toolbar.xml),
  • dodano opcję automatycznego zamykania nawiasów i cydzysłowów (Guillaume de Rorthais),
  • wsparcie dla kilkukrotnego występowania znaku %cursor% w snippetach, dzięki czemu przy wstawianiu snippeta możemy tabulatorem przechodzić w kolejne miejsca przeznaczone do wypełnienia tekstem (Thomas Martitz),
  • wsparcie dla nowych typów plików Ada, CMake, Matlab, NSIS, Vala and YAML,
  • możliwość dzielenia okna również w poziomie (thanks to Moritz Barsnick),
  • udoskonalony instalator dla Windowsów
  • aktualizacje tłumaczeń: bg, ca, cs, de, en_GB, fr, hu, it, ja, pt_BR, sv, ru, tr, vi, zh_CN

Pełną listę zmian znajdziecie w Release Notes (nie mam pomysłu jak to przetłumaczyć :-P)

Zachęcam również do zaglądnięcia w sekcję Extras na stronie projektu, gdzie znajdziecie między innymi snippety PHP, HTML oraz Pythona. Jest tam również mój ulubiony schemat ciemnych kolorów…

...czy inne ciekawe wynalazki typu edytor schematów kolorowania składni on-line.

Rippowanie muzyki z Last.fm

ArchLinux Linux Software Techblog 29 listopada 2008 o 11:57:19 | ☍ trackback

Aktualnie w polskim prawie nie ma przepisu zabraniającego nagrywania audycji radiowych. Oznacza to, że całkowicie legalnie możemy wejść w posiadanie sporych zbiorów muzyki. Nie każde radio jednak gra to czego chcielibyśmy słuchać. I tu pojawia się Last.fm – radio, które zna nasz gust i gra to co lubimy. Tylko jak teraz dobrać się do tej muzyki?

Odpowiedzią jest program TheLastRipper. Małe ale skuteczne narzędzie, pożerające adresy typu lastfm://. Wystarczy wskazać mu katalog, do jakiego ma rippować muzykę oraz stację.

Rezultatem działania TheLastRippera będą utwory znajdujące się w ładnie nazwanych katalogach (wg. schematu wykonawca > album > utwór) oraz pobrane okładki albumów w trzech rozmiarach.

Trzy rozmiary okładek mogą przeszkadzać. Np. mój QuodLibet przy odtwarzaniu utworu wybiera akurat najmniejszą okładkę co nie wygląda najlepiej. Ale łatwo można temu zaradzić. Wystarczy w katalogu z muzyką utworzyć skrypt zawierający:

find ./ -type f \( -name "SmallCover.jpg" -o -name "MediumCover.jpg" \) -delete

który usunie małe i średnie okładki z wszystkich podkatalogów.

Użytkownicy Archa aby pobrać pogram mogą skorzystać z aktualnego PKGBUILDa, który zamieszczam poniżej, ponieważ ten obecnie znajdujący się w AUR jest przestarzały.

PKGBUILD for version 1.1.1
pkgname=thelastripper
pkgver=1.1.1
pkgrel=1
pkgdesc="A Last.FM Ripper"
arch=('i686')
url="http://thelastripper.com/"
license=('GPL')
depends=('gnome-desktop-sharp' 'gnome-icon-theme')
makedepends=('pkgconfig')
source=("http://thelastripper.googlecode.com/files/$pkgname-$pkgver.tar.gz")
md5sums=('9a8653cc0cf450077b599cb8988ba8a3')
build() {
export RSVG_SHARP_20_CFLAGS="/usr/share/rsvg2-sharp/2.0/rsvg2-api.xml"
export RSVG_SHARP_20_LIBS="/usr/lib/mono/rsvg2-sharp-2.0/rsvg2-sharp.dll"
cd $startdir/src/$pkgname-$pkgver
# Bypass GMCS and fakeroot bug
mkdir -p $startdir/src/$pkgname/.wabi
export MONO_SHARED_DIR="$startdir/src/$pkgname/"
./configure --prefix=/usr
make || return 1
make DESTDIR=$startdir/pkg install
}

Załącznik 1 - lista adresów last.fm

  • lastfm://user/$username/personal
  • lastfm://user/$username/playlist
  • lastfm://artist/$artistname or lastfm://artist/$artistname/similarartists
  • lastfm://globaltags/$tag
  • lastfm://group/$groupname
  • lastfm://user/$username/neighbours
  • lastfm://user/$username/recommended/100
  • lastfm://play/tracks/$trackid,$trackid,$trackid

RPSy w OVH.pl

Inne Internet Techblog 19 października 2008 o 14:53:18 | ☍ trackback

W ostatni czwartek zdarzyło mi się wynająć w ovh.pl prywatny serwer RPS I. Miał on służyć testom nowego startupa. Docelowa grupa testerów (około 80 osób), Celeron 1,2 GHz, 512 RAM, Łącze 100 Mbps bez limitu transferu, dysk 10 GB i 50 zł miesięcznie. Dobry serwer do testów można by rzec. Można by… ale:

Prywatne RPSy to rozwiązanie „ekologiczne” i tanie. Aby takim było żadna z maszyn nie posiada fizycznego dysku. Dane przechowywane są na wielkiej, wspólnej macierzy dyskowej dostępnej przez sieć za pomocą NFSa lub iSCSI.

Z grubsza powinno to działać tak:

Ale działa niestety tak:

Mały dowód:

$ time ls /sbin/
real   0m41.424s
user   0m0.008s
sys   0m0.004s

dla porównania mój laptop

$ time ls /sbin/
real   0m0.071s
user   0m0.000s
sys0   m0.003s

Dysk praktycznie nie istnieje a serwer staje się przez to zupełnie nieużyteczny. Nie żeby był to odosobniony przypadek. Wystarczy poczytać ten wątek na forum aby się o tym przekonać.

Na RPSa zdecydowałem się, bo słyszałem, że problemy z dyskami już ustały. Otóż nic podobnego! Od następnego miesiąca przesiadam się na serwer dedykowany z własnym dyskiem. Pewnie skończy się na Kimsufi w opcji L. Chyba, że polecacie coś lepszego w podobnej cenie.

Podsumowując:

RPS w OVH.pl – nie polecam!

Joggerowy gadżet na pulpit

ArchLinux Kodowanie Linux Python Techblog 05 września 2008 o 00:38:40 | ☍ trackback

Ostatnio rozglądałem się za tutorialem do budowy prostego gadżetu w Pythonie, który siedział by sobie na przezroczystym tle na moim pulpicie. Gadżety Screenlets czy gDesklets działają różnie, zazwyczaj niestabilnie albo, któryś (akurat przydatny) całkowicie się nie odpala. Poza tym potrzebowałem coś maksymalnie prostego a nie całej platformy dla gadżetów.

Wpadłem więc dziś na pomysł wykorzystania Tildy jako ładnego kontenera. W zasadzie to do pełni szczęścia potrzebne były dwie paczki: tilda i python-feedparser. Znajdziecie je w każdej dystrybucji. Dla archowców:

# pacman -S tilda python-feedparser

Tildę najlepiej skonfigurować następująco:

W sekcji Command w polu Custom Command umieszczamy adres skryptu, ale o tym za chwilę.

Teraz czas na Pythona. Wystarczy sworzyć malutki skrypt o takiej treści:

#! /usr/bin/env python

import feedparser
import time
import os, sys

# nieskonczona petla
while 1:
	# pobierz RSS
	feed = feedparser.parse("http://jogger.pl/rss/")
	# wyczysc ekran
	sys.stdout.write(os.popen('clear').read())
	# dla kazdego wpisu
	for note in feed['entries']:
		# wypisz tytul
		print "- %s" % note['title']
	print "\nhttp://jogger.pl/"
	# odczekaj 60 sekund
	time.sleep(60)

Skrypt wystarczy zapisać np. jako jogger.py i wpisać ścieżkę do niego w polu Custom Command. W moim przypadku jest to:

python /home/tomek/go/python/jogger.py

I to by było na tyle. Po ponownym uruchomieniu Tildy powinniśmy mieć ładny przegląd wydarzeń na joggerze odświeżany co 60 sekund. Gdy coś nas zainteresuje wystarczy przytrzymać ctrl i kliknąć link do joggera.

Oczywiście może to być dowolny kanał RSS/Atom czy coś zupełnie innego np. statystyki obciążenia naszego serwera. Żadnych tam Googlowych gadżetów z tysiącem funkcji. Prosto łatwo i przyjemnie.

Język dot

ArchLinux Linux Software Techblog 18 czerwca 2008 o 15:51:07 | ☍ trackback

Już dawno miałem o nim napisać notkę jednak zawsze gdzieś mi to uciekało. Ale nie tym razem.

Język dot służy do opisywania schematów za pomocą tekstu. Pewnie brzmi to niewyraźnie, dlatego od razu przejdźmy do konkretów. Aby skorzystać z dobrodziejstw języka dot instalujemy pakiet graphviz.

# pacman -S graphviz

Następnie otwieramy nasz ulubiony edytor tekstu i zaczynamy pisać:

digraph linux {
    Linux -> Debian;
    Linux -> "Red Hat";

    Debian -> Ubuntu;
    Debian -> Knoppix;

    Ubuntu -> Kubuntu;
    Ubuntu -> Edubuntu;
    Ubuntu -> Xubuntu;

    "Red Hat" -> Mandrake;
    "Red Hat" -> Fedora;

    Mandrake -> Mandriva;
}

Tak przygotowany plik zapisujemy jako test.dot A teraz najlepsza część, czyli budujemy schemat

$ dot -Tpng test.dot -o test.png

TIP: Pliki możemy eksportować również do innych formatów

W efekcie powinniśmy otrzymać plik test.png, który wygląda tak:

Narysowanie czegoś takiego w Inkscape pewnie zajęło by Wam kilka minut więcej. Najlepszą według mnie zaletą języka dot jest to, składa on się ze zwykłego tekstu, dzięki czemu w łatwy sposób możemy generować te pliki przez różne mechanizmy. Np. jeżeli mamy bazę danych firmy gdzie jakaś tabela obrazuje zależności pomiędzy przełożonymi a podwładnymi wówczas możemy szybko napisać skrypt w PHP czy Pythonie, który z pomocą tej tabeli wygeneruje nam plik dot a następnie utworzy z niego ładny schemat.

Na tym jednak nie koniec. Język dot to prawdziwe bogactwo kształtów grotów i kolorów. Za pomocą kombinacji różnych tych elementów możemy dokładnie zamodelować to co chcemy.

Więcej przykładów znajdziecie w galerii.

Rozpoznawanie gestów za pomocą kamery

Kodowanie Projekty Python Techblog 07 czerwca 2008 o 13:06:30 | ☍ trackback

Od dawna chciałem już zrobić coś związanego z kamerą. W tym semestrze nadarzyła się okazja i zaproponowaliśmy prowadzącemu własny temat projektu z przedmiotu o nazwie „struktury systemów informatycznych”. Naszym zamierzeniem było stworzenie programu, który działałby podobnie jak gesty wykonywane myszą w Firefoksie tyle, że rolę myszki odegrać miała kamera. Założenia wstępne: platforma – Linux, język – Python.

Najwięcej problemów sprawiła nam sama kamera, a dokładniej to zbieranie i przetwarzanie jej obrazu.

Na początku zabraliśmy się za testowanie reacTIVision, które w zasadzie jest oprogramowaniem dla ekranów wielodotykowych. ReacTIVision ma swoją bibliotekę 89 symboli, które potrafi rozpoznać określając ich numer id, pozycję x-y, kąt nachylenia a nawet przyśpieszenie.

Symbole wyglądają tak:

Kamera widziała to tak:

A reacTIVision tak:

Działo to całkiem sprawnie. Jeżeli wykonaliśmy szybszy ruch markerem, a dokładniej przyśpieszenie markera przekroczyło pewną granicę, wówczas rozpoczynał się rysować gest. Wadą jednak tego rozwiązania były markery. Jeżeli nie miało się markera to program był bezużyteczny. Trzeba było więc go zastąpić czymś co ma każdy, np. ręką :-)

Do łapania obrazu z kamery tym razem wykorzystaliśmy moduł Pythona pyvideograb. Znaleźliśmy nawet bardzo przydatny skrypt, który wykrywał punkty ruchu w obrazie poprzez porównywanie dwóch sąsiednich klatek. Co prawda autorzy zaznaczyli, że działa tylko pod Windowsem z uwagi na moduł do przychwytywania obrazu z kamery, ale ten łatwo można było podmienić.

Teraz wystarczyło wrzucić wszystko do Pygame’a i już pierwsze efekty były widoczne.

Program wykrywał ruch i potrafił określić współrzędne punktu ruchu, co w przypadku poruszającej się większej powierzchni oznaczało jej środek.

Po naciśnięciu spacji możemy już wykonywać gest.

Następny etap to sieć neuronowa a dokładniej sieć Hopfielda. Dzięki niej jesteśmy w stanie rozpoznać, czy wykonany gest zgadza się z jednym z 4 wzorców. Jeżeli tak, wykonywane jest przypisane do niego polecenie.

W konsoli wygląda to tak:

W tej chwili program ma wprowadzone 4 wzorce (plik: patterns.txt)

Przypisane do nich działania można łatwo edytować (interfejs.py)

Jeżeli ktoś miał by ochotę się tym pobawić lub zrobić z tym coś więcej to proszę bardzo.

Gesty v0.001 na licencji GNU GPL

Projekt – 4.5, radość ze zrealizowanego pomysłu – bezcenna ;-)

Współautorzy:
– Marek Knaga
Jarosław Miazga

UPDATE: ponieważ strona projektu pyvideograb od jakiegoś czasu jest martwa zamieszczam spakowany moduł pyvideograb.tar.gz

Snippety w Geany

Linux Software Techblog 07 maja 2008 o 14:58:52 | ☍ trackback

AKTUALIZACJA: karbownicki.com/2010/05/13/snippety-dla-webdevelopera/

Odkąd zagościł u mnie dżin używam tylko jego. Jest szybki i ma wszystko czego mi trzeba. No może prawie wszystko. Brakowało mi tylko snippetów czyli po polsku wstawek. To ostatnia rzecz jakiej brakowało mi do szybkiej i efektywnej pracy. Bo co klepać linie kodu, kiedy można klepnąć tabulator :-)

Co jakiś czas sprawdzałem czy pojawiła się już odpowiednia wtyczka zapewniająca taką funkcjonalność, ale póki co nadal jest to tylko pozycja na liście życzeń. Dopiero wczoraj znalazłem w dokumentacji, że większość jest już zrobiona !

W katalogu w którym zainstalował się Geany znajdziecie plik snippets.conf. U mnie pełna ścieżka to:

/usr/share/geany/snippets.conf

Teraz wystarczy skopiować go do naszego katalogu domowego:

$ cp /usr/share/geany/snippets.conf ~/.geany/

I już możemy dodawać do niego dowolne wstawki. W bloku [Special] możemy zadeklarować słowa kluczowe, których będziemy używać przy tworzeniu naszych wstawek. Np. żeby nie powtarzać często ładnego otwarcia bloku kodu {} deklarujemy to raz:

klamry=\n{\n\t\n}\n

a następnie możemy używać tego słowa kluczowego przy deklaracji naszych wstawek:

[PHP]
for=for ($i = 0; $i < %cursor%; $i++)%klamry%

Na początek zadeklarowałem sobie kilka wstawek z HTML-a. Jeżeli ktoś chce to niech się częstuje:

wget http://dl.dropbox.com/u/668529/conf/snippets.conf -O ~/.geany/snippets.conf

Efekt działania