<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><title>Karbownicki.com</title><link>http://karbownicki.com/</link><description>Wpisy z dziennika internetowego Jogger, wspomaganego przez Jabbera</description><lastBuildDate>Tue, 09 Feb 2010 05:10:57 +0100</lastBuildDate><generator>JoggerPL</generator><item><title>Automatyzacja myszy i klawiatury</title><link>http://karbownicki.com/2010/01/07/automatyzacja-myszy-i-klawiatury/</link><description>&lt;p&gt;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?&lt;/p&gt;
&lt;p&gt;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 &lt;strong&gt;xautomation&lt;/strong&gt; (spaczkowany w większości dystrybucji). Dostarcza on bardzo pomocnej komendy jaką jest &lt;strong&gt;xte&lt;/strong&gt;. Podstawowymi parametrami tej komendy są:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;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
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Przykładowy skrypt powtarzający pewną czynność w nieskończoność może wglądać tak:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;#!/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
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Dla ułatwienie sobie życia możemy skorzystać z komendy &lt;strong&gt;xmousepos&lt;/strong&gt;, 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:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;tomek@Arch:~$ xmousepos
1125 136 1125 110
^^ dwie pozycje, bo każdy kij ma dwa końce
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;W każdym razie miło wiedzieć, że mamy możliwość zautomatyzowania kolejnej czynności ;-)&lt;/p&gt;
&lt;p&gt;I &amp;lt;3 Linux&lt;/p&gt;
</description><pubDate>Thu, 07 Jan 2010 22:41:56 +0100</pubDate><guid>http://karbownicki.com/2010/01/07/automatyzacja-myszy-i-klawiatury/</guid><category>Linux</category><category>Software</category><category>Techblog</category><category>linux automatyzacja</category></item><item><title>Configer.net - pokaż swoje configi</title><link>http://karbownicki.com/2009/12/29/configer-net-pokaz-swoje-configi/</link><description>&lt;p&gt;Przyszedł koniec roku, w &lt;a href=&quot;http://pdll.pl/&quot;&gt;pracy&lt;/a&gt; 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.&lt;/p&gt;
&lt;p&gt;Tak więc z potrzeby posiadania narzędzia narodził się &lt;strong&gt;&lt;a href=&quot;http://configer.net&quot;&gt;configer.net&lt;/a&gt;&lt;/strong&gt;. 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.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://farm3.static.flickr.com/2590/4225466667_1184a1e317_o.png&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2590/4225466667_ed2b938e28.jpg&quot; alt=&quot;configer.net&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ż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 ;-)&lt;/p&gt;
&lt;p&gt;Napisy końcowe: w projekcie udział wzięli - trójkąt, &lt;a href=&quot;http://techravings.com&quot;&gt;Jaro&lt;/a&gt;, Lotos (via &lt;a href=&quot;http://pdll.pl/&quot;&gt;pdll.pl&lt;/a&gt;) oraz &amp;lt;3 Django.&lt;/p&gt;
</description><pubDate>Tue, 29 Dec 2009 21:10:52 +0100</pubDate><guid>http://karbownicki.com/2009/12/29/configer-net-pokaz-swoje-configi/</guid><category>Configer</category><category>Projekty</category><category>Techblog</category><category>pliki konfiguracja django serwis społeczność</category></item><item><title>Sumowanie statystyk Google Analytics</title><link>http://karbownicki.com/2009/11/20/sumowanie-statystyk-google-analytics/</link><description>&lt;p&gt;Zawsze mnie ciekawiło jaki jest ruch na naszym &lt;a href=&quot;http://pdll.pl/&quot;&gt;firmowym serwerze&lt;/a&gt; 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 &lt;a href=&quot;http://code.google.com/intl/pl-PL/apis/analytics/docs/gdata/1.0/gdataProtocol.html&quot;&gt;swoje API&lt;/a&gt;. Wystarczyło więc zaprząc do pracy Pythona oraz bibliotekę &lt;a href=&quot;http://code.google.com/p/gdata-python-client/&quot;&gt;gdata&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Użytkownikom ArchLinuksa polecam paczkę &lt;strong&gt;python-gdata-svn&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;yaourt -S python-gdata-svn
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Skrypt jest dość prosty i działa w konsoli:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;#!/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) &amp;gt; 1:
        d = argv[1].split('-')
        data = datetime.date(int(d[0]), int(d[1]), int(d[2]))
    else:
        data = datetime.datetime.now()

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

    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 &quot;\033[1;31m%d\t%d\033[0m\t\033[33m%s\033[0m&quot; % (odw, ods, b.title.text)

    print &quot;--------------------------&quot;
    print &quot;%d\t%d\tRazem&quot; % (sum(odwiedziny),sum(odslony))


if __name__ == &quot;__main__&quot;:
    sys.exit(main(sys.argv))
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;python stats.py 2012-12-21
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Przykładowy wynik działania wygląda tak:&lt;br&gt;
&lt;img src=&quot;http://farm3.static.flickr.com/2714/4120896212_5fdc55b00f_o.png&quot; alt=&quot;Przykład działania&quot; title=&quot;Przykład działania&quot;&gt;&lt;/p&gt;
</description><pubDate>Fri, 20 Nov 2009 23:30:37 +0100</pubDate><guid>http://karbownicki.com/2009/11/20/sumowanie-statystyk-google-analytics/</guid><category>Kodowanie</category><category>Python</category><category>Techblog</category><category>python Google Analytics statystyki</category></item><item><title>Kto zabił elektryczny samochód?</title><link>http://karbownicki.com/2009/11/17/kto-zabil-elektryczny-samochod/</link><description>&lt;p&gt;Dziś z &lt;a href=&quot;http://wyborcza.pl/1,91446,7263913,Warszawa_ma_pierwszy_punkt_ladowania_samochodow_elektrycznych.html&quot; rel=&quot;nofollow&quot;&gt;pompą&lt;/a&gt; i &lt;a href=&quot;http://www.tvn24.pl/0,1629129,0,1,w-warszawie-zatankujesz-prad,wiadomosc.html&quot; rel=&quot;nofollow&quot;&gt;paradą&lt;/a&gt; otwarto pierwszy w Polsce punkt ładowania samochodów elektrycznych. Na uroczystości nie mogło zabraknąć oczywiście elektrycznych samochodów. Takie rzecz jasna się zjawiły, niestety sztuk 2 (słownie: dwie).&lt;/p&gt;
&lt;p&gt;Ktoś może spytać po co otwierać taki punkt dla dwóch samochodów? Oczywiście chodzi o promocję. Do połowy 2010 roku ma powstać 130 takich punktów (w tym 30 do końca grudnia). Jednak dlaczego do końca grudnia punktów ładowania ma być 15 razy więcej niż samochodów? Dlaczego nie mamy elektrycznych samochodów?&lt;/p&gt;
&lt;p&gt;Od razu przypomniał mi się film, który oglądałem jakiś czas temu. Jego oryginalny tytuł brzmi &lt;strong&gt;Who Killed the Electric Car?&lt;/strong&gt;. Autorzy filmu przedstawiają przerażającą historię, która doskonale wyjaśnia dlaczego nie jeździmy obecnie elektrycznymi autami, ciesząc się ich prostotą budowy/działania, ekologicznością, oszczędzając przy tym znaczne sumy pieniędzy. Kolejna teoria spiskowa? Warto obejrzeć, choćby dla Mela Gibsona ;-)&lt;/p&gt;
&lt;p&gt;&lt;embed id=&quot;VideoPlayback&quot; src=&quot;http://video.google.pl/googleplayer.swf?docid=1405611374523233913&amp;amp;hl=pl&amp;amp;fs=true&quot; style=&quot;width:400px;height:326px&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; type=&quot;application/x-shockwave-flash&quot;&gt;&lt;/p&gt;
&lt;p&gt;Jeżeli przeszkadzają komuś holenderskie napisy to możecie obejrzeć na &lt;a href=&quot;http://v.youku.com/v_show/id_XNDM3NTkyODg=.html&quot; rel=&quot;nofollow&quot;&gt;youku&lt;/a&gt;.&lt;/p&gt;
</description><pubDate>Tue, 17 Nov 2009 21:42:06 +0100</pubDate><guid>http://karbownicki.com/2009/11/17/kto-zabil-elektryczny-samochod/</guid><category>Inne</category><category>samochód elektryczny</category></item><item><title>Definiowanie własnych atrybutów w HTML-u</title><link>http://karbownicki.com/2009/11/05/definiowanie-wlasnych-atrybutow-w-html-u/</link><description>&lt;p&gt;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:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;id=&quot;required&quot;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;No ale id musi być niepowtarzalne, więc może klasa...&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;class=&quot;required&quot;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Może, ale w sumie mam już tam kilka innych klas&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;class=&quot;specjalne kontrast required&quot;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;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...&lt;/p&gt;
&lt;p&gt;Otóż uznaje. Trzeba je tylko zadeklarować w definicji dokumentu - DTD (Document Type Definition). Załóżmy że chcemy wzbogacić nasz &lt;strong&gt;input&lt;/strong&gt; w atrybut &lt;strong&gt;required&lt;/strong&gt;. Wystarczy więc taka konstrukcja DTD:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;
  &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot; 
[
  &amp;lt;!ATTLIST input required CDATA #IMPLIED&amp;gt;
]&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Ta dekladacja zezwala atrybutowi &lt;strong&gt;required&lt;/strong&gt; posiadać dowolną wartość znakową. Jeżeli chcielibyśmy ograniczyć wartość jedynie do dwóch pozycji wystarczy zastosować coś takiego:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;
  &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot; 
[
  &amp;lt;!ATTLIST input required (true|false) #IMPLIED&amp;gt;
]&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Ogólny schemat jest taki:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;ATTLIST element atrybut typ opcjnonalnyStatus
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;No i gotowe. Teraz możemy zaprząc JavaScript do podjęcia odpowiednich działań na podstawie struktury dokumentu. Czyli np. w jQuery:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$('input[required='true']').PrzypilnujInteresu();
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Prosto czysto i funkcjonalnie.&lt;/p&gt;
&lt;p&gt;Materiał źródłowy:&lt;br&gt;
&lt;a href=&quot;http://www.alistapart.com/articles/customdtd/&quot; rel=&quot;nofollow&quot;&gt;http://www.alistapart.com/articles/customdtd/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PS. Remember remember the fifth of november...&lt;/p&gt;
&lt;p&gt;&lt;object width=&quot;425&quot; height=&quot;300&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/0xO2gqi_ZjY&amp;amp;hl=pl&amp;amp;fs=1&amp;amp;&quot;&gt;
&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;
&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;
&lt;embed src=&quot;http://www.youtube.com/v/0xO2gqi_ZjY&amp;amp;hl=pl&amp;amp;fs=1&amp;amp;&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;300&quot;&gt;&lt;/object&gt;&lt;/p&gt;
</description><pubDate>Thu, 05 Nov 2009 23:31:00 +0100</pubDate><guid>http://karbownicki.com/2009/11/05/definiowanie-wlasnych-atrybutow-w-html-u/</guid><category>Kodowanie</category><category>Techblog</category><category>HTML JavaScript DTD</category></item><item><title>GooglePreview dla Google Chrome</title><link>http://karbownicki.com/2009/10/28/googlepreview-dla-google-chrome/</link><description>&lt;p&gt;&lt;a href=&quot;http://ackroyd.de/googlepreview/&quot; rel=&quot;nofollow&quot;&gt;Google preview&lt;/a&gt; to moja ulubiona &lt;del&gt;wtyczka&lt;/del&gt; &lt;u&gt;rozszerzenie&lt;/u&gt; 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 &lt;a href=&quot;http://code.google.com/chrome/extensions/getstarted.html&quot; rel=&quot;nofollow&quot;&gt;dokumentacja&lt;/a&gt;, więc postanowiłem sam zapchać lukę.&lt;/p&gt;
&lt;p&gt;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 - &lt;strong&gt;google-chrome-dev&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;yaourt -S google-chrome-dev
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Aby uruchomić ukryty jeszcze mechanizm obsługi rozszerzeń należy uruchomić przeglądarkę z parametrem &lt;strong&gt;-–enable-extensions&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;google-chrome -–enable-extensions
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Teraz wystarczy już tylko pobrać przygotowane przeze mnie rozszerzenie i potwierdzić chęć instalacji&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;https://chrome.google.com/extensions/detail/behjpjkdajdecgkkamhaplpkcbkceaie&quot; rel=&quot;nofollow&quot;&gt;ChromePreview 0.38&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Od tej chwili możemy się już cieszyć pięknymi miniaturkami&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://farm3.static.flickr.com/2727/4054114396_4da1e202d3_o.png&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2727/4054114396_b3b504c732.jpg&quot; alt=&quot;wyniki wyszukiwania&quot; title=&quot;wyniki wyszukiwania&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://dl.getdropbox.com/u/668529/chrome/ChromePreview/manifest.json&quot; rel=&quot;nofollow&quot;&gt;manifest.json&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dl.getdropbox.com/u/668529/chrome/ChromePreview/chrome-preview.js&quot; rel=&quot;nofollow&quot;&gt;chrome-preview.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dl.getdropbox.com/u/668529/chrome/ChromePreview/updates.xml&quot; rel=&quot;nofollow&quot;&gt;updates.xml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Listę zainstalowanych rozszerzeń znajdziecie wstukując do paska adresu &lt;strong&gt;chrome://extensions/&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;EDIT: rozszerzenie znajdziecie w otwartej dzisiaj bazie rozszerzeń pod adresem &lt;a href=&quot;https://chrome.google.com/extensions/detail/behjpjkdajdecgkkamhaplpkcbkceaie&quot;&gt;https://chrome.google.com/extensions/detail/behjpjkdajdecgkkamhaplpkcbkceaie&lt;/a&gt;&lt;/h3&gt;
</description><pubDate>Wed, 28 Oct 2009 22:56:02 +0100</pubDate><guid>http://karbownicki.com/2009/10/28/googlepreview-dla-google-chrome/</guid><category>Internet</category><category>Kodowanie</category><category>Techblog</category><category>Google Chrome Firefox Plugins</category></item><item><title>Październikowy update</title><link>http://karbownicki.com/2009/10/08/pazdziernikowy-update/</link><description>&lt;p&gt;Od czasu ostatniej notki trochę się u mnie pozmieniało. Studia odeszły w niepamięć a więc najwyższy czas zarobić na siebie. Wychodząc z założenia, że nigdzie nie pracuje się tak dobrze jak u siebie samego z dniem 1 sierpnia stałem się właścicielem, pracownikiem oraz jedynym inwestorem jednoosobowej działalności gospodarczej. Zarejestrowanie działalności okazało się nie takie straszne. W zasadzie wystarczyło wypełnienie pojedynczego, dwustronicowego druczku i następnego dnia miałem już regon. Resztę formalności załatwiło za mnie biuro rachunkowe.&lt;/p&gt;
&lt;p&gt;Największym problemem okazało się znalezienie w Opolu biura w rozsądnej cenie. Niestety rozsądna cena i w miarę dobra lokalizacja wiązała się z gruntownym remontem. Mając na głowie pierwsze większe zlecenie tydzień remontu nie bardzo jest na rękę, no ale nikt nie mówił, że będzie łatwo. Na szczęście remont poszedł dość sprawnie i obdrapany pokoik&lt;br&gt;
&lt;a href=&quot;http://farm4.static.flickr.com/3459/3992747985_2b17abf425_o.jpg&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3459/3992747985_b9f7c6148f.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;udało się zamienić w biuro&lt;br&gt;
&lt;a href=&quot;http://farm4.static.flickr.com/3436/3993506362_ef3a2e920f_o.jpg&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3436/3993506362_ef3a2e920f_o.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Teraz tylko podłączyć internet i już można lecieć z robotą... Niestety, podwykonawcy Netii bywają bardzo różni. Po wielu cyrkach z niewiadomym statusem realizacji zlecenia godzinami wiszenia na (dez)infolinii oraz bezkresnym burdelem na froncie Netia-podwykonawcy pierwszy pakiet dotarł do biura dopiero grubo ponad miesiąc później (sic!). Dodam że lokal znajduje w centrum Opola i były w nim od dawna działające skrzynki Netii. Oczywiście pierwszy pakiet został należycie wykorzystany (pobranie listy serwerów &lt;a href=&quot;http://www.teeworlds.com/&quot; title=&quot;Teeworlds&quot; rel=&quot;nofollow&quot;&gt;Teeworlds&lt;/a&gt;). Swoją drogą klepanie przez ponad miesiąc dużego portalu w Django bez internetu to całkiem nowe doświadczenie ;-)&lt;/p&gt;
&lt;p&gt;Na szczęście mamy już październik i wszystko wychodzi na prostą. Obecnie działam wraz z dwoma kumplami ze studiów (sam przecież nie będę grał w &lt;a href=&quot;http://www.teeworlds.com/&quot; title=&quot;Teeworlds&quot; rel=&quot;nofollow&quot;&gt;Teeworlds&lt;/a&gt;), z czego każdy dla obniżenia kosztów pracy prowadzi własną działalność. Nie przeszkadza to jednak temu, że wszyscy trzej działamy pod jedną marką - &lt;a href=&quot;http://pdll.pl/&quot; title=&quot;Tworzenie stron Opole&quot;&gt;Professional design, pdll.pl&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://pdll.pl/&quot; title=&quot;Tworzenie stron Opole&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2524/3993439502_f77d09f9bd_o.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Zajmujemy się oczywiście tworzeniem stron, bo przecież trzeba robić to co się lubi najbardziej :-) Póki co na brak roboty nie narzekamy. Cieszyć może to, że większość klientów trafia do nas z polecenia, gdzie nasi obecni klienci polecają nas kolejnym. Dzięki temu mamy pewność, że dobrze wykonujemy swoją pracę.&lt;/p&gt;
&lt;p&gt;Po dwóch miesiącach dostrzegam już zalety prowadzenia własnej działalności:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nikt mnie &lt;a href=&quot;http://room-303.com/blog/2009/10/02/przygoda-z-its-zbliza-sie-do-konca/&quot;&gt;nagle nie zwolni z pracy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;praca przekłada się bezpośrednio na wynagrodzenie&lt;/li&gt;
&lt;li&gt;łatwiej wziąć urlop ;-)&lt;/li&gt;
&lt;/ul&gt;
</description><pubDate>Thu, 08 Oct 2009 20:12:27 +0200</pubDate><guid>http://karbownicki.com/2009/10/08/pazdziernikowy-update/</guid><category>Inne</category><category>praca pdll firma</category></item><item><title>Django – personalizacja settings.py</title><link>http://karbownicki.com/2009/06/28/django-personalizacja-settings-py/</link><description>&lt;p&gt;Jak każdy djangowic dobrze wie plik &lt;b&gt;settings.py&lt;/b&gt; 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).&lt;/p&gt;
&lt;p&gt;Pierwszą możliwością rozwiązania tego problemu jest ignorowanie pliku &lt;b&gt;settings.py&lt;/b&gt; 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 &lt;b&gt;INSTALLED_APPS&lt;/b&gt;. Moje repozytorium aktualizuje stronę na serwerze po każdym commicie, więc ręczna edycja &lt;b&gt;settings.py&lt;/b&gt; jest męcząca.&lt;/p&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;python manage.py runserver --settings=settings-developer.py&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Wszystko wydaje się być ok. Jeżeli coś zmieniamy to dokonujemy zmiany w &lt;b&gt;settings.py&lt;/b&gt;, &lt;b&gt;settings-developer.py&lt;/b&gt; i po commitcie wszystko gra. Czasami jednak przy testowaniu różnych rzeczy w pliku developera można zapomnieć o &lt;b&gt;settings.py&lt;/b&gt; i po commicie znowu strona jest rozwalona. Poza tym nie każdy developer korzysta z tych samych ustawień. Jeden używa &lt;a href=&quot;http://github.com/dcramer/django-debug-toolbar/tree/master&quot;&gt;Django Debug Toolbar&lt;/a&gt; inny &lt;a href=&quot;http://www.djangosnippets.org/snippets/571/&quot;&gt;ColorSQLMiddleware&lt;/a&gt; więc trzeba by zrobić tyle settings-xxx ilu developerów. A później przy zmianie czegoś globalnego edytować wszystkie...&lt;/p&gt;
&lt;p&gt;Ostatecznym rozwiązaniem okazało się przeciążenie pliku &lt;b&gt;settings.py&lt;/b&gt; przez ponowną deklarację zmiennych lub rozszerzenie już istniejących wartości. Jak to zrobić?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Tworzymy plik, który będzie przetrzymywał nasze lokalne ustawienia, np. &lt;b&gt;settings-local.py&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Na końcu pliku &lt;b&gt;settings.py&lt;/b&gt; dodajemy kod:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;
&lt;code&gt;BASE_DIR = os.path.dirname(os.path.abspath(__file__))
execfile('%s/settings-local.py' % BASE_DIR)&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Teraz w pliku &lt;b&gt;settings-local.py&lt;/b&gt; możemy ponownie zadeklarować zmienne które mają zostać przeciążone lub rozszerzyć zadeklarowane już w &lt;b&gt;settings.py&lt;/b&gt; listy. Np. kiedy jeden z developerów chce użyć &lt;a href=&quot;http://github.com/dcramer/django-debug-toolbar/tree/master&quot;&gt;Django Debug Toolbar&lt;/a&gt; dodaje do &lt;b&gt;settings-local.py&lt;/b&gt; taki kod:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;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',
)&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Plik &lt;b&gt;settings-local.py&lt;/b&gt; wywalamy z repozytorium i w ten sposób otrzymujemy elastyczny mechanizm współdzielenia wartości globalnych przy jednoczesnej personalizacji ustawień lokalnych.&lt;/p&gt;
</description><pubDate>Sun, 28 Jun 2009 11:17:04 +0200</pubDate><guid>http://karbownicki.com/2009/06/28/django-personalizacja-settings-py/</guid><category>Django</category><category>Kodowanie</category><category>Techblog</category><category>Django Python</category></item><item><title>Narzędzia do pracy grupowej poszukiwane</title><link>http://karbownicki.com/2009/06/04/narzedzia-do-pracy-grupowej-poszukiwane/</link><description>&lt;p&gt;Obecnie pracuję jako programista aplikacji internetowych w małym zespole. Realizujemy kilka projektów w miesiącu i dość trudno jest zapanować nad wszystkimi zadaniami, które trzeba wykonać. W przypadku większych projektów korzystamy z &lt;a href=&quot;http://trac.edgewall.org/wiki&quot;&gt;Trac'a&lt;/a&gt;, jednak do mniejszych nie nadaje się on za dobrze ponieważ trzeba dla każdego projektu tworzyć nową instancję i nie ma jak zrobić zbiorczego zestawienia. Rozglądałem się więc za jakimś kompleksowym rozwiązaniem, które dawałoby możliwość ogarnięcia kilku projektów wraz ze śledzeniem repozytoriów Subversion.&lt;/p&gt;
&lt;p&gt;Powstało już wiele serwisów oferujących podobną funkcjonalność. Wśród najbardziej znanych wymienić można:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lighthouseapp.com/&quot;&gt;Lighthouse&lt;/a&gt;&lt;br&gt;
&lt;img src=&quot;http://farm4.static.flickr.com/3415/3594519193_81b19f3ebe.jpg&quot; alt=&quot;screen&quot;&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.activecollab.com/&quot;&gt;activeCollab&lt;/a&gt;&lt;br&gt;
&lt;img src=&quot;http://farm4.static.flickr.com/3377/3595326840_5d28673c68.jpg&quot; alt=&quot;screen&quot;&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://goplanapp.com/&quot;&gt;Goplan 2.0&lt;/a&gt;&lt;br&gt;
&lt;img src=&quot;http://farm4.static.flickr.com/3586/3594562805_8d985030fb.jpg&quot; alt=&quot;screen&quot;&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://collabtive.o-dyn.de/&quot;&gt;Collabtive&lt;/a&gt;&lt;br&gt;
&lt;img src=&quot;http://farm4.static.flickr.com/3589/3595370360_e24e1347b8.jpg&quot; alt=&quot;screen&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Główną wadą pierwszych trzech rozwiązań jest to, że nie można ich hostować na własnym serwerze a jedynie wykupuje się konto na serwerze producenta. Collabtive jest co prawda aplikacją na licencji GNU GPL i można postawić to u siebie, ale z kolei zupełnie nie obsługuje repozytoriów kodu.&lt;/p&gt;
&lt;p&gt;I tutaj pytanie do Was. Czego Wy używacie w pracy? Być może jest jakiś fajny projekt który przeoczyłem.&lt;/p&gt;
&lt;p&gt;PS. Swoją drogą to dziwne, że nikt jeszcze czegoś podobnego w Django nie zrobił.&lt;/p&gt;
</description><pubDate>Thu, 04 Jun 2009 15:40:21 +0200</pubDate><guid>http://karbownicki.com/2009/06/04/narzedzia-do-pracy-grupowej-poszukiwane/</guid><category>Internet</category><category>Kodowanie</category><category>projectmanagement praca grupowa kod współpraca</category></item><item><title>Python i jQuery czyli pyquery</title><link>http://karbownicki.com/2009/05/04/python-i-jquery-czyli-pyquery/</link><description>&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Jak to działa?&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;from pyquery import PyQuery as pq
import urllib

html = urllib.urlopen(&quot;http://antyweb.pl&quot;).read()
html = pq(html)&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Teraz wystarczy już zadecydować co chcemy wyciągnąć i po prostu to zrobić :-) Np. informacje o autorze&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;print  html(&quot;#f li.frt&quot;).text()&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Wynik:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Witaj, nazywam sie Grzegorz Marczak i&amp;nbsp;jestem autorem tego bloga. Piszę tutaj o&amp;nbsp;serwisach spolecznosciowych, nowych technologiach i&amp;nbsp;nowych trendach w&amp;nbsp;internecie.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wyciągnięcie wszystkich kategorii&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;for a in html(&quot;li.categories a&quot;):
        print a.text&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Wynik:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;antytydzień Biała flaga&lt;br&gt;
Ciekawe strony&lt;br&gt;
google&lt;br&gt;
Świat&lt;br&gt;
Miniblog&lt;br&gt;
Mobilnie&lt;br&gt;
Moje przemyślenia&lt;br&gt;
Off topic&lt;br&gt;
polska&lt;br&gt;
Pytamy.pl&lt;br&gt;
Startups&lt;br&gt;
To mnie drażni.&lt;br&gt;
Uncategorized&lt;br&gt;
W trakcie tworzenia&lt;br&gt;
wywiady&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wyszukanie najczęściej komentowanego wpisu ze strony głównej&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;max_comments = 0
title = ''
for a in html(&quot;ul.clnn li.l a&quot;):
        try:
                # liczba komentarzy
                comments = int(a.text.split(&quot; &quot;)[1])
                if max_comments &amp;lt; comments:
                        max_comments = comments
                        # nazwa wpisu
                        title = a.values()[1].replace(&quot;Komentarze do wpisu &quot;,'')
        except:
                pass
                
print &quot;Najwiecej komentarzy: %s&quot; % max_comments
print &quot;Wpis: %s&quot; % title&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Wynik:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Najwiecej komentarzy: 32&lt;br&gt;
Wpis: Interia mówi, tak kupujemy ruch (bo inni też tak robią)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Więcej&lt;/h3&gt;
&lt;p&gt;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ł &lt;a href=&quot;http://pythonpaste.org/webob/&quot;&gt;WebOb&lt;/a&gt; możemy też zaprzęgnąć do pracy Ajax.&lt;/p&gt;
&lt;p&gt;Po więcej informacji zapraszam na &lt;a href=&quot;http://pypi.python.org/pypi/pyquery&quot;&gt;stronę projektu pyquery&lt;/a&gt;.&lt;/p&gt;
</description><pubDate>Mon, 04 May 2009 15:51:57 +0200</pubDate><guid>http://karbownicki.com/2009/05/04/python-i-jquery-czyli-pyquery/</guid><category>Kodowanie</category><category>Python</category><category>Techblog</category><category>Python pyquery</category></item></channel></rss>