Programując dla mojego klienta, dosyć ciekawą, aplikację serwerową w Pythonie musiałem stworzyć małą klasę, która pobierała odpowiednie dane z pliku tekstowego. Co prawda interesowały mnie tylko dane z poszczególnych linii, ale my skupimy się na czytaniu pliku linia po linii.

Dla uproszczenia tutoriala ucieknę od tłumaczenia co to klasa, i tym samym prezentowany kod będzie od klasy stronił.

W celu załadowania pliku do pamięci(zmiennej) programu korzystamy z funkcji open. Jej pierwszy argument to ścieżka do pliku, który chcemy otworzyć, drugi natomiast to tryb, w naszym wypadku r – czyli read.

file = open('/sciezka/do/pliku/na/serwerze/plik.txt', 'r').read()

Następnie całą treść pliku musimy podzielić przez nową linię („\n”) i wiersze zapisać do tablicy.

lines = file.split('\n')

Następnie, żeby czytać każdą linię po kolei przygotowujemy pętlę for przez tablicę linii.

for line in lines:
    print line

Całość będzie wyglądać następująco:

file = open('plik.txt', 'r').read()
lines = file.split('\n')
for line in lines:
    print line
tak
czytamy
linia
po
linii
w
pythonie
pozdr.

Dzisiaj w pracy zostałem poproszony do przeanalizowania oraz usunięcia pewnego problemu na laptopie mojego współpracownika. Za każdym razem kiedy restartował komputer na ekranie po zalogowaniu pojawiało się okno notatnika, z otwartym plikiem: „desktop.ini”. Jego treść była następująca:

[.ShellClassInfo] LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21787

Dzieje się tak gdy w jakiś sposób atrybut ukrycia pliku „desktop.ini” zostaje usunięty. Problem łatwo rozwiązać, wystarczy użyć wbudowanego w system oprogramowania „attrib”, który pozwala zmieniać właściwości plików oraz folderów.

A więc:

  • uruchom linię poleceń jako administator
  • wpisz następujące polecenia:
  • attrib +s +h "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\desktop.ini"
    attrib +s +h "%programdata%\Microsoft\Windows\Start Menu\Programs\Startup\desktop.ini"
    exit
    

    voilà!

    W dniu dzisiejszym potrzebowałem zamienić wsadowo pewien ciąg znaków w pewnej kolumnie w pewnej tabeli w pewnej bazie danych 🙂

    Składnia jest niebywale prosta:

    UPDATE tabela SET kolumna = REPLACE(kolumna,'szukany','zmiana');
    

    Wstęp

    PHP oferuje nam bardzo pomocny obiekt: finfo, dzięki niemu możemy pobrać MIME Headers załadowanego przez file_get_contents pliku(z url) i w ten sposób sprawdzić czy to plik(z url) z odpowiednim rozszerzeniem.


    Kodowanie

    Cały kod będzie składał się z dwóch funkcji, których działanie opiszę pod kodem:

    
    <?php
    
    function compareFileFromUrlExtension($urlToFile, $validExtension) {
    	$fileFromUrlExtension = getFileFromUrlExtension($urlToFile);
    	
    	if($fileFromUrlExtension == $validExtension) {
    		return 'Dobre rozszerzenie pliku: '.$fileFromUrlExtension;
    	} else {
    		return 'Zle rozszerzenie pliku';
    	}	
    }
    
    function getFileFromUrlExtension($urlToFile) {
    		$fileFromUrlContents = file_get_contents($urlToFile);
    		$finfoObject = new finfo(FILEINFO_MIME_TYPE);
    		
    			return $finfoObject->buffer($fileFromUrlContents);
    }
    
    $result = compareFileFromUrlExtension('http://downloads.wordpress.org/plugin/upload-theme-via-url.zip', 'application/zip');
    
    echo $result;
    
    ?>
    
    

    Pomysł

    Sam pomysł na nowy motyw zrodził się podczas spotkania ze znajomymi(rysownikami). Wtedy naszkicowałem mniej więcej jak mają wyglądać poszczególne strony. Potem zaczęło się tzw. „przepisywanie”. Wybrałem odpowiedni framework CSS(960gs – mój ulubiony) i wyszło coś takiego:



    Dużo jQuery i dobrze zoptymalizowany kod. Już niedługo podmienię obecny motyw. Może się spodoba :-))

    Wstęp

    Ostatnio w moje ręce wpadła karta sieciowa(pod PCI) z chipsetem Atheros AR5006x. Wraz z dostarczoną paczką przyszła mi do głowy myśl zamienienia adresu MAC sprzętowo(najlepiej na same zera). Dlaczego nie? Do dzieła!


    Przede wszystkim research

    3h wklepywania w google.com różnych kombinacji słów kluczowych nie wniosło nic nowego do posiadanej wiedzy. No może, przypomniało o zasłużonym madwifi. Porażka? Nie! Poddają się tylko klepacze!


    Rusz głową!

    Madwifi to sterowniki bezprzewodowych kart sieciowych opartych na chipsetach Atherosa. Zostały one zastąpiąne przez ath5k. Madwifi po skompilowaniu dostarcza nam przydatne narzędzie: ath_info, które pozwala robić dump eeprom-a. Sam EEPROM to nic innego jak pamięć „nieulotna”, wykorzystywana do przechowywania małej ilości danych. To właśnie w tym miejscu mamy zamiar namieszać (: Wszystko jak na razie wygląda na proste i przyjemne. Niestety pozory czasem mylą i tak też jest w tym przypadku, gdyż aby zacząć mieszać potrzebujemy znaleźć adres pamięci naszego urządzenia i zczytać z niego dane. Do tego potrzebujemy Ubuntu 9.04, ponieważ w póżniejszych wersjach Ubuntu pamięć przechowywana jest w powłokach jądra i dostęp do niej jest znacznie ograniczony. Gdy już uda nam się zczytać dane to potrzebujemy nadpisać niektóre wartości w eepromie na podstawie adresów pamięci. Pewien ceniony czeski programista Jan Krupa napisał wiele narzędzi, które zczytują i nadpisują EEPROM. Niestety w moim wypadku nie działały, dlatego korzystam z ath_info, a cała operacja i tak wygląda bardzo podobnie. To by było na tyle wstępów. Do dzieła!


    Przygotuj odpowiednio system

    Zacznijmy od pobrania najnowszej wersji UNetbootin w moim wypadku dla Windowsa.



    Następnie uruchamiamy program, wybieramy dystrybucję, w naszym wypadku Ubuntu, i wybieramy wersję: 9.04_Live. Ponadto w okno przy napisie „Przestrzeń używana do zachowywania plików pomiędzy rebootami (tylko Ubuntu)” podajemy wartość 1000 mb. Wybieramy napęd USB i klikamy ok.



    Po kliknięciu ok rozpocznie się pobieranie Ubuntu i wgrywanie go na „gwizdek”. W zależności od prędkości internetu operacja może trwać ok 30min.


    Po ukończeniu całej operacji uruchamiamy komputer ponownie i wchodzimy w ustawienia BIOS-u żeby ustawić bootowanie z pendrive-a. Nie będę opisywał jak to zrobić, a jeżeli nie wiesz to odsyłam do google.pl (:


    Pierwszy start

    Włączamy komputer i po zabootowaniu naszego pendrive wybieramy opcję Default i czekamy aż system się załaduje (: Przede wszystkim klikamy alt+f2 i wpisujemy „gnome-terminal”.

    Otworzy się nam konsola, która będzie miejscem naszych działań. Dla ułatwienia i zbędnego wklepywania sudo przed każdym poleceniem zróbmy to raz, dodajmy hasło rootowi:

    sudo passwd root
    




    i zalogujmy się na jego konto:

    su root
    

    Teraz mamy pełną kontrolę. Niesety jest mały problem, ponieważ Ubuntu 9.04 nie jest dalej supportowany i nie ma możliwości zainstalowania poprzez apt-get potrzebnego nam subversion. Z problemem tym radzimy sobie w następujący sposób. Otwieramy sources.list

    gedit /etc/apt/sources.list
    




    i wklejamy treść sources.list z późniejszej wersji 9.10:

    deb http://gb.archive.ubuntu.com/ubuntu/ karmic main restricted
    deb-src http://gb.archive.ubuntu.com/ubuntu/ karmic main restricted
    
    ## Major bug fix updates produced after the final release of the
    ## distribution.
    deb http://gb.archive.ubuntu.com/ubuntu/ karmic-updates main restricted
    deb-src http://gb.archive.ubuntu.com/ubuntu/ karmic-updates main restricted
    
    ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
    ## team. Also, please note that software in universe WILL NOT receive any
    ## review or updates from the Ubuntu security team.
    deb http://gb.archive.ubuntu.com/ubuntu/ karmic universe
    deb-src http://gb.archive.ubuntu.com/ubuntu/ karmic universe
    deb http://gb.archive.ubuntu.com/ubuntu/ karmic-updates universe
    deb-src http://gb.archive.ubuntu.com/ubuntu/ karmic-updates universe
    
    ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu 
    ## team, and may not be under a free licence. Please satisfy yourself as to 
    ## your rights to use the software. Also, please note that software in 
    ## multiverse WILL NOT receive any review or updates from the Ubuntu
    ## security team.
    deb http://gb.archive.ubuntu.com/ubuntu/ karmic multiverse
    deb-src http://gb.archive.ubuntu.com/ubuntu/ karmic multiverse
    deb http://gb.archive.ubuntu.com/ubuntu/ karmic-updates multiverse
    deb-src http://gb.archive.ubuntu.com/ubuntu/ karmic-updates multiverse
    
    deb http://security.ubuntu.com/ubuntu karmic-security main restricted
    deb-src http://security.ubuntu.com/ubuntu karmic-security main restricted
    deb http://security.ubuntu.com/ubuntu karmic-security universe
    deb-src http://security.ubuntu.com/ubuntu karmic-security universe
    deb http://security.ubuntu.com/ubuntu karmic-security multiverse
    deb-src http://security.ubuntu.com/ubuntu karmic-security multiverse
    

    Po zakończeniu powyższej operacji instalujemy subversion za pomocą komendy:

    aptitude install subversion
    

    Teraz gdy słynny svn jest gotowy do użycia, korzystamy z niego wpisując:

    svn checkout http://madwifi-project.org/svn/madwifi/trunk madwifi
    

    Dzięki temu do katalogu madwifi pobierze się kod źródłowy sterowników madwifi.


    Wchodzimy do lokalizacji:

    cd madwifi
    

    i budujemy:

    make
    

    Bądź uważny i zwracaj uwagę na różnego rodzaju błędy. Jeżeli cała operacja przebiegnie pomyślnie możemy przejść do następnego kroku:

    make install
    

    Rozpocznie się kompilacja sterowników. Po jej pomyślnym przejściu musimy załadować nasze sterowniki do działającego systemu poprzez komendę:

    modprobe ath_pci
    

    Zaczynamy mieszać

    Rozpoczynamy procedurę od sprawdzenia adresu karty sieciowej w pamięci:

    lspci -v
    

    Wyświetli nam się lista różnych urządzeń, wśród nich wyszukujemy naszego Atherosa i pod szukamy takiej linijki:

    Memory at <8 znakowy adres> np. 8c100000
    

    Następnie przystępujemy do zrobienia pseudo backapu:

    ath_info -d 0x<8 znakowy adres> np. 8c100000 > backup.txt
    

    Po tym wpisujemy taką komendę:

    ath_info -d 0x<8 znakowy adres> np. 8c100000
    

    i w tym co nam się pojawi szukamy czegoś takiego

    0000:  a55a 0000 0040 0001 0000 5001 0000 7131
    0008:  144f 1c0a 0100 0000 01c2 0002 c606 0001
    0010:  0000 0000 0000 0000 0000 0000 0000 0000
    0018:  0000 0000 0000 0000 0000 5566 3344 1122
    0020:  0000 0000 0000 0000 0000 0000 0000 0000
    0028:  0000 0000 0000 0000 0000 0000 0000 0000
    0030:  0000 0000 0000 0000 0000 0000 0000 0000
    0038:  0000 0000 0000 0000 0000 0000 0000 0000
    0040:  ffff ffff ffff ffff ffff ffff ffff ffff
    0048:  ffff ffff ffff ffff ffff ffff ffff ffff
    0050:  ffff ffff ffff ffff ffff ffff ffff ffff
    0058:  ffff ffff ffff ffff ffff ffff ffff ffff
    0060:  ffff ffff ffff ffff ffff ffff ffff ffff
    0068:  ffff ffff ffff ffff ffff ffff ffff ffff
    0070:  ffff ffff ffff ffff ffff ffff ffff ffff
    0078:  ffff ffff ffff ffff ffff ffff ffff ffff
    0080:  1400 168c 001c 1402 0001 0200 140a 5001
    0088:  0000 140b 144f 7131 140f 0100 1c0a 1410
    0090:  5001 01c2 15c3 3f01 0f00 1419 0cc0 0504
    0098:  1410 5001 c1c2 1005 0000 0000 101e 0001
    00a0:  0000 ffff ffff ffff ffff 2211 4433 6655
    00a8:  ffff ffff ffff ffff ffff ffff ffff ffff
    00b0:  ffff ffff ffff ffff ffff ffff ffff ffff
    00b8:  ffff ffff ffff ffff ffff ffff ffff 0037
    00c0:  2063 5003 da6c 0401 b1c8 016e 00ff 78ff
    

    Jest to dump eepromu. Pokazuje on jakie wartości są przypisane do adresów. W naszym Atherosie dane na temat adresu MAC zapisane są w odpowiedniej kolejności w odpowiednich adresach.
    Załóżmy, że mamy nasz adres MAC to:

    11:22:33:44:55:66
    

    Aby nadpisać 4 pierwsze cyfry adresu MAC np. na zera, potrzebujemy zmienić dwie wartości przy dwóch różnych adresach. 11:22 zapisane jest przy adresie 001f i 22:11 przy adresie 00a5. Robimy to następująco:

    ath_info -g 3:0 -w 0x<8 znakowy adres> 001f 0000
    ath_info -g 3:0 -w 0x<8 znakowy adres> 00a5 0000
    

    Czasami przy -g 3:0 nie chce nadpisać wtedy należy zmieniać 3 na liczbę od 1 do 5. Przy którejś powinno przejść.
    Przy następnych cyfrach postępujemy analogicznie. 33:44 przypisane jest do adresu 001e i 44:33 do adresu 00a6

    ath_info -g 3:0 -w 0x<8 znakowy adres> 001e 0000
    ath_info -g 3:0 -w 0x<8 znakowy adres> 00a6 0000
    

    Dalej podobnie. 55:66 to adres 001d a 66:55 to 00a7

    ath_info -g 3:0 -w 0x<8 znakowy adres> 001d 0011
    ath_info -g 3:0 -w 0x<8 znakowy adres> 00a7 1100
    

    Po takiej operacji nasz adres MAC zamiast:

    11:22:33:44:55:66
    

    przyjmie postać:

    00:00:00:00:00:11
    

    Musimy zwrócić uwagę na to, że podszywanie się pod cudzy adres MAC jest nielegane
    Tekst zostal napisany wylacznie w celach edukacyjnych. Autor nie ponosi odpowiednialnosci, za jakiekolwiek poczynania zwiazane z opisanymi powyżej metodami pracy przy komputerze.

    Wstęp

    Squid jest darmowym oprogramowaniem serwera proxy, dostępnym dla (chyba) wszystkich systemów operacyjnych. Prywatne proxy przydaję się do wielu rzeczy np. dodawania postów na jakimś forum z różnych adresów IP :p.


    Instalacja

    Instalacja na Ubuntu jest bardzo prosta. Wystarczy, że włączymy gnome-terminal i wpiszemy taką komendę ( i oczywiście klikniemy enter ) :

    
    apt-get install squid 
    
    albo
    
    aptitude install squid
    
    

    Mi znacznie bliższy jest aptitude, ale to bez różnicy.


    Przystępujemy do konfiguracji

    Na samym początku naszej konfiguracji zajmiemy się ncsa_auth, czyli mniej więcej tworzeniem usernamea z hasłem ( tego z którym będziemy się łączyć, żeby korzystać z proxy ). Cała operacja ogranicza się do wklepania takiej komendy:

    htpasswd /etc/squid/passwd username
    

    Następnie zmieniamy prawa naszego pliku tak aby squid był w stanie go odczytać i pobrać z niego dane:

    chmod o+r /etc/squid/passwd
    

    Zaraz potem musimy znaleźć nsca_auth authentication helper:

    dpkg -L squid | grep nsca_auth
    

    Natomiast teraz przechodzimy do konfiguracji najważniejszego pliku squida czyli squid.conf. Otwórzmy go za pomocą mcedit:

    mcedit /etc/squid/squid.conf
    

    Szukamy:

    #auth_param basic program <uncomment and complete this line>
    #auth_param basic children 5 startup=5 idle=1
    #auth_param basic realm Squid proxy-caching web server
    #auth_param basic credentialsttl 2 hours
    

    i zamieniamy na:

    auth_param basic program /usr/lib/squid/ncsa_auth /etc/squid/passwd 
    auth_param basic children 2
    auth_param basic realm Komunikat przy logowaniu
    auth_param basic credentialsttl 2 hours
    auth_param basic casesensitive off
    

    Następnie szukamy:

    acl ncsa_users
    

    i zamieniamy na:

    acl ncsa_users proxy_auth REQUIRED
    

    Potem szukamy:

    http_access
    

    i zamieniamy na:

    http_access allow ncsa_users
    

    Aby nasze proxy było high anymous musimy znaleźć:

    forwarded_for on 
    

    i zamienić na:

    forwarded_for off
    

    Następnie na samym końcu squid.conf dodajemy:

    	request_header_access Allow allow all 
    	request_header_access Authorization allow all 
    	request_header_access WWW-Authenticate allow all 
    	request_header_access Proxy-Authorization allow all 
    	request_header_access Proxy-Authenticate allow all 
    	request_header_access Cache-Control allow all 
    	request_header_access Content-Encoding allow all 
    	request_header_access Content-Length allow all 
    	request_header_access Content-Type allow all 
    	request_header_access Date allow all 
    	request_header_access Expires allow all 
    	request_header_access Host allow all 
    	request_header_access If-Modified-Since allow all 
    	request_header_access Last-Modified allow all 
    	request_header_access Location allow all 
    	request_header_access Pragma allow all 
    	request_header_access Accept allow all 
    	request_header_access Accept-Charset allow all 
    	request_header_access Accept-Encoding allow all 
    	request_header_access Accept-Language allow all 
    	request_header_access Content-Language allow all 
    	request_header_access Mime-Version allow all 
    	request_header_access Retry-After allow all 
    	request_header_access Title allow all 
    	request_header_access Connection allow all 
    	request_header_access Proxy-Connection allow all 
    	request_header_access User-Agent allow all 
    	request_header_access Cookie allow all 
    	request_header_access All deny all 
    

    a na sam koniec uruchamiamy w konsoli te trzy komendy:

    service squid start
    chkconfig squid on
    ufw allow squid
    

    W razie problemów z visible_hostname przy starcie squida wystarczy edytować squid.conf i dodać:

    visible_hostname server1
    

    Teraz nasze proxy powinno działać i powinniśmy mieć możliwość połączenia się z nim i to by było na tyle (:

    Python nie posiada określonej funkcji, aby sprawdzić, czy zmienna jest zdefiniowana, ponieważ jest założenie, że wszystkie zmienne zostały zdefiniowane przed użyciem. Próba uzyskania dostępu do zmiennej, która nie została wcześniej zdefiniowana będzie pluła wyjątkami.

    W pythonie to rzadkość, żeby nie wiedzieć czy dana zmienna jest zdefiniowana. Jeżeli nastąpi już taka sytuacja, że tego nie wiesz możesz to sprawdzić poprzez próbę „try”, która w przypadku niezdefiniowanej zmiennej powinna wznieść wyjątek „NameError”:

    try:
        test
    except NameError:
        test = None
    

    To nie wszystko, ponieważ musimy sprawdzić czy wyjątek został wzniesiony prostym warunkiem:

    try:
        test
    except NameError:
        test = None
    
    if test is None:
        print "zmienna jest niezdefiniowana";
    else:
        print "zmienna jest definiowana";
    

    W wielu sytuacjach np. w formularzach wskazane jest korzystanie ze słowników i testów na obecność kluczy przy pomocy metody:

    has_key()
    

    Wstęp

    SQLAlchemy jest zestawem pythonowych narzędzi SQL i ORM znacznie pomagającym programiście przy pracy z bazami danych.
    Obsługuje następujące bazy danych: MySQL, SQLite, PostgreSQL, Oracle, MS-SQL i Firebird.


    Instalacja

    Jest kilka sposób instalacji, ze względu na prostotę polecam:

    easy_install sqlalchemy
    

    Jeżeli nie korzystasz z konta roota, prawdopodobnie będziesz musiał skorzystać z sudo.
    Zastrzegam, że to nie jedyny sposób instalacji (;


    ORM

    ORM – ang. Object-Relational Mapping co w dosłownym tłumaczeniu znaczy Mapowanie Obiektowo-Relacyjne. Polega to mniej więcej na odwzorowaniu struktury obiektowej na relacyjnej bazie danych.


    Pierwszy raz

    Mniej więcej wyjaśniliśmy sobie kilka pojęć związanych z SQLAlchemy. Poznaliśmy prostą metodę instalacji i definicję ORM. Posiadając taką wiedzę czas na pokazanie i wytłumaczenie prostego przykładu „w kodzie”. Stwórz plik „przyklad.py„, zamieść w nim zawartość poniższego listingu i zapisz.

    # -*- coding: utf-8 -*-
    from sqlalchemy import *
    
    db = create_engine('sqlite:///przyklad.db')
    
    db.echo = False # Spróbuj zmienić na true (:. To taki odpowednik "verbose"
    
    metadata = MetaData(db)
    
    users = Table('users', metadata,
        Column('user_id', Integer, primary_key=True),
        Column('name', String(255)),
        Column('job', Integer),
        Column('pass', String(255)),
    )
    users.create() # Tworzymy tabelę
    
    insert = users.insert()
    
    insert.execute(name='Michal', job: 'Bezrobotny', pass='sekretne')
    
    insert.execute({'name': 'Jan', 'job': 'Handlowiec', 'pass': 'tajne'},
              {'name': 'Kuba', 'job': 'Wozny'},
              {'name': 'Ola', 'job': 'Handlowiec'}) # Wkładamy dane
    
    select = users.select()
    result = select.execute()
    
    wszystko = result.fetchall()
    row = result.fetchone()
    print 'Id:', row['user_id']
    print 'Imie:', row['name']
    print 'Praca:', row.job
    print 'Haslo:', row['pass']
    
    for row in wszystko: 
        print row.name, 'pracuje jako', row.job
    
    

    Aby uruchomić nasz mały program wpisz w konsolę:

    pyhton przyklad.py
    

    Abyśmy mogli operwać na tabelach musieliśmy przypisać je do obiektu MetaData(). Teraz dopiero możemy stworzyć tabelę users. W przykładzie pokazałem dwa sposoby dodawania danych do bazy. Pierwszy pozwala na dodanie pojedyńczego obiektu, natomiast za pomocą drugiego sposobu podajemy listę słowników, żeby dodać wiele obiektów na raz. Jeżeli SQLAlchemy w naszych danych znajdzie się jakiś znak specjalny(np. apostrofę lub średnik) to SQLEngine automatycznie je zasleszuje. Dzięki takiej ochronie, atak SQL Injection staje się praktycznie niemożliwy. W SQLAlchemy pobieranie danych nie stanowi żadnego problemu, żeby pobrać jeden wiersz skorzystałem z funkcji fetchone(), natomiast żeby pobrać wszystkie rekordy na raz skorzystałem z fetchall() i wylistowałem je za pomocą pętli for, której obsługa w pythonie jest wyjątkowo prosta. Pewnie zwróciłeś uwagę to to, że korzystamy z sqlite. Jak już pewnie wiesz to nie jedyna baza obsługiwana przez SQLAlchemy. Poniżej przedstawiam sposoby łączenia się z innymi bazami danych:

    
    db = create_engine('postgres://login:haslo@localhost:port/nazwabazydanych') # PostgreSQL
    db = create_engine('mysql://login:haslo@localhost:port/nazwabazydanych') #MySQL
    db = create_engine('oracle://login:haslo@localhost:port/nazwabazydanych') #Oracle
    
    # Łączenie z bazami danych odbywa się za pomocą pewnego schematu:
    # driver://login:haslo@host:port/nazwabazydanych
    
    db = create_engine('sqlite:////bezwzgledna/sciezka/do/bazydanych.db') 
    db = create_engine('sqlite:///relatywna/sciezka/do/bazydanych.db')
    db = create_engine('sqlite://')  # baza w pamięci RAM
    
    
    

    Pobieranie danych – szczegółowo

    Poświęćmy trochę czasu, aby zbadać różne sposoby pobierania danych z bazy przy pomocy SQLAlchemy, które skracają czas pracy i pomagają programiście tworzyć zaawansowane zapytania z klauzulami WHERE, AND, OR itd. Na początek stwórzmy plik „pobieranie.py„.

    # -*- coding: utf-8 -*-
    from sqlalchemy import *
    
    # Użyjmy tej samej bazy danych
    db = create_engine('sqlite:///przyklad.db')
    
    db.echo = True  # Robimy true, żeby widzieć co się dzieje
    
    metadata = MetaData(db)
    
    # Tabela users istnieje, ładujemy ją z bazy danych za pomocą "autoload"
    users = Table('users', metadata, autoload=True)
    
    def run(stmt):
        rs = stmt.execute()
        for row in rs:
            print row
    
    
    # Zapytanie z  warunkiem jednego pola
    q = users.select(users.c.name == 'Ola')
    run(q)
    q = users.select(users.c.id > 1 )
    run(q)
    q = users.select(users.c.job == 'Handlowiec'
    
    # AND, OR i NOT
    q = users.select(and_(users.c.id < 3, users.c.name != 'Jan'))
    run(q)
    q = users.select(or_(users.c.id > 1 , users.c.name != 'Jan'))
    run(q)
    q = users.select(not_(users.c.name == 'Jan'))
    run(q)
    
    # równie dobrze możemy korzystać z &, | i ~
    q = users.select((users.c.job == 'Handlowiec') & (users.c.name != 'Ola'))
    run(q)
    q = users.select((users.c.job == 'Handlowiec' | (users.c.name != 'Kuba'))
    run(q)
    q = users.select(~(users.c.name == 'Michal'))
    run(q)
    
    # dostępne są również funkcje "like", "startswith", "endswith"
    q = users.select(users.c.name.startswith('K'))
    run(q)
    q = users.select(users.c.name.like('%a%'))
    run(q)
    q = users.select(users.c.name.endswith('a'))
    run(q)
    
    # ponadto dostępne są "in" i "between"
    q = users.select(users.c.id.between(1,3))
    run(q)
    
    # aby zapobiec konfliktowi z pythonem dajemy in_
    q = users.select(users.c.name.in_('Jan', 'Ola'))
    run(q)
    
    # do wywoływanie funkcji SQL służy "func"
    q = users.select(func.substr(users.c.name, 3, 1) == 'b')
    run(q)
    
    # pobieranie określonych 
    q = select([users], users.c.job != 'Handlowiec')
    run(q)
    q = select([users.c.name, users.c.job], users.c.name != 'Michal')
    run(q)
    
    # korzystanie z funkcji SQL  "count"
    q = select([func.count(users.c.user_id)])
    run(q)
    
    # korzystanie z funkcji SQL  "count", żeby zliczyć wszystko
    q = select([func.count("*")], from_obj=[users])
    run(q)
    

    Order By, Limit i inne takie

    Pobierając dane z bazy, zazwyczaj chcemy żeby były one odpowiednio posortowane. W takich przypadkach z pomocą przychodzą do nas Order by, Limit itp.

    # -*- coding: utf-8 -*-
    from sqlalchemy import *
    
    # Użyjmy tej samej bazy danych
    db = create_engine('sqlite:///przyklad.db')
    
    db.echo = True  # Robimy true, żeby widzieć co się dzieje
    
    metadata = MetaData(db)
    
    # Tabela users istnieje, ładujemy ją z bazy danych za pomocą "autoload"
    users = Table('users', metadata, autoload=True)
    
    def run(stmt):
        rs = stmt.execute()
        for row in rs:
            print row
    
    # proste wykorzystanie order_by
    q = users.select(order_by=[users.c.name])
    run(q)
    
    # malejące sortowanie na podstawie id
    q = users.select(order_by=[desc(users.c.user_id)])
    run(q)
    
    # rosnące sortowanie na podstawie id
    q = users.select(order_by=[desc(users.c.user_id)])
    run(q)
    
    # sortowanie na wielu kolumnach
    q = users.select(users.c.job>'A', order_by=[desc(users.c.user_id), asc(users.c.job)])
    
    # pobieranie unikalnych danych
    q = select([users.c.name], distinct=True)
    run(q)
    
    # wykorzystanie limit i offset
    q = users.select(offset=2, limit=2)
    run(q)
    

    Delete

    Czasami nie tylko chcemy pobierać dane, ale chcemy je usuwać. Tu z pomocą wkracza obiekt delete().

    # -*- coding: utf-8 -*-
    from sqlalchemy import *
    
    # Użyjmy tej samej bazy danych
    db = create_engine('sqlite:///przyklad.db')
    
    db.echo = True  # Robimy true, żeby widzieć co się dzieje
    
    metadata = MetaData(db)
    
    # Tabela users istnieje, ładujemy ją z bazy danych za pomocą "autoload"
    users = Table('users', metadata, autoload=True)
    
    def run(stmt):
        stmt.execute()
    
    # Usuwamy rekord o id równym 1
    q = users.delete(users.c.user_id == 1)
    run(q)
    
    # Usuwamy rekordy gdzie zawodem jest "Handlowiec"
    q = users.delete(users.c.job == 'Handlowiec')
    run(q)
    
    # Usuwanie rekordów dla wielu argumentów
    users.delete().execute(
    		{'name': '%Jan%'},
    		{'name': '%Ola%'},
    		{'job': '%wozny%'}
    	)
    
    	
    

    Update

    Oprócz usuwania często chcemy coś poprawić lub zamienić w naszych rekordach. Pomoże nam w tym obiekt update().

    # -*- coding: utf-8 -*-
    from sqlalchemy import *
    
    # Użyjmy tej samej bazy danych
    db = create_engine('sqlite:///przyklad.db')
    
    db.echo = True  # Robimy true, żeby widzieć co się dzieje
    
    metadata = MetaData(db)
    
    # Tabela users istnieje, ładujemy ją z bazy danych za pomocą "autoload"
    users = Table('users', metadata, autoload=True)
    
    # Podmieniamy "Kuba" na "Marcin"
    users.update(users.c.user_name=='Kuba').execute(user_name='Marcin')
    
    # Update dla wielu argumentów
    users.update().execute(
            {'user_id':1, 'user_name':'Helena', 'job':'wozna'},
            {'user_id':2, 'user_name':'Zdzislaw', 'job':'ksiegowy'},
            {'user_id':3, 'user_name':'Maciek', 'job':'sportowiec'},
        )
    

    JOIN czyli łączenie tabel

    Wielokrotnie spotykamy się z problemem struktury bazy danych. Np. Trzymania w innej tabeli adresów zamieszkania naszych „userów”. Na początek stwórzmy sobie nowy plik „jointest.py” i wypełnij go poniższą zawartością:

    # -*- coding: utf-8 -*-
    from sqlalchemy import *
    
    # Tworzymy nową bazę danych
    db = create_engine('sqlite:///przykladjoin.db')
    
    db.echo = True  # Robimy true, żeby widzieć co się dzieje
    
    metadata = MetaData(db)
    
    users = Table('users', metadata,
        Column('user_id', Integer, primary_key=True),
        Column('name', String(255)),
        Column('job', Integer),
        Column('pass', String(255)),
    )
    
    users.create() # Tworzymy tabelę users
    
    address = Table('addresses', metadata,
    	Column('address_id', Integer, primary_key=True),
    	Column('town', String),
    	Column('user_id', Integer, ForeignKey('users.user_id')),
    	)
    
    address.create() # Tworzymy tabelę address
    
    insert = users.insert()
    insert.execute(
    			{'name': 'Jan', 'job': 'Handlowiec', 'pass': 'tajne'},
    			{'name': 'Kuba', 'job': 'Wozny', 'pass': 'tajne'},
    			{'name': 'Ola', 'job': 'Handlowiec', 'pass': 'tajne'},
    			{'name': 'Karolina', 'job': 'Sportowiec', 'pass': 'tajne'},
    			{'name': 'Marcin', 'job': 'Wozny', 'pass': 'tajne'}
    		) # Wkładamy dane
    
    insert = address.insert()
    insert.execute(	
    			{'town': 'Warsaw', 'user_id': 1},
    			{'town': 'New York', 'user_id': 2},
    			{'town': 'London', 'user_id': 3},
    			{'town': 'Oslo', 'user_id': 4}
    		) # Wkładamy dane
    
    
    def run(stmt):
        rs = stmt.execute()
        for row in rs:
            print row	
    	
    # Spróbujmy trochę nabroić i zróbmy pełny join (:
    # ze względu na brak klauzuli WHERE
    # program zwróci nam wszystkie możliwe kombinacje rekordów.
    q = select([users, address])	
    run(q)
    
    # Teraz spróbujemy z klauzulą WHERE 
    # SQL: bla bla WHERE addresses.user_id = users.user_id
    q = select([users, address], address.c.user_id == users.c.user_id)
    run(q)
    
    # Pobieramy tylko kilka kolumn
    q = select([users.c.name, address.c.town], address.c.user_id == users.c.user_id)
    run(q)
    
    # sqlalchemy oferuje "mądry" obiekt "join"
    # który określa odpowiednie parametry łączenia
    # na podstawie "foreign keys" tabel
    q = join(users, address).select()
    run(q)
    
    # jeżeli chcemy pobrać wszystkich userów
    # nawet jeżeli nie mają wpisanego miasta
    # to korzystamy z outerjoin w takiej kolejności 
    q = outerjoin(users, address).select()
    run(q)
    
    # kolejność ma znaczenie
    # domyślnie outerjoin jest "left outer join" 
    # to znaczy tabela po lewej i odpowiadające jej wartości z tabeli po prawej
    # w ten sposób nie pobierzemy rekordu z "Marcinem"
    # ponieważ nie ma jego id w tabeli addresses
    q = outerjoin(address, users).select()
    run(q)
    

    i wykonaj takie polecenie:

    python jointest.py
    

    Obiekt bindparam()

    W SQLAlchemy możesz sam „zbindować„(określić) inną nazwę dla istniejącej nazwy jakiejś kolumny i korzystać z takiego „binda” wielokrotnie w swoich zapytaniach do bazy. Brzmi to strasznie, ale wytłumaczenie tego słowami ( przynajmniej dla mnie ) jest stosunkowo trudne, dlatego zapraszam do zajrzenia do kodu:

    q = users.select(users.c.name==bindparam('username'))
    conn.execute(q, username = 'Jan').fetchall() 
    
    q = users.select(users.c.user_id==bindparam('id'))
    conn.execute(q, id = 1 ).fetchall() 
    

    Mam nadzieję, że jakoś to pojęliście (: Dokumentacja


    Union

    Union służy do łączenia wyników selectów ( nie pokaże powtarzających się wierszy ):

    # -*- coding: utf-8 -*-
    from sqlalchemy import *
    
    # Użyjmy tej samej bazy danych
    db = create_engine('sqlite:///przykladjoin.db')
    
    db.echo = True  # Robimy true, żeby widzieć co się dzieje
    
    metadata = MetaData(db)
    
    # Tabela users istnieje, ładujemy ją z bazy danych za pomocą "autoload"
    users = Table('users', metadata, autoload=True)
    address = Table('addresses', metadata, autoload=True)
    
    union(
        address.select(address.c.street=='New York'),
        address.select(address.c.street=='Oslo'),
        address.select(address.c.street=='Warsaw'),
        order_by=[addresses.c.street]
    ).execute()
    
    users.select(
        users.c.user_id==1
      ).union_all(
          users.select(
              users.c.user_id==3
          ), 
          order_by=[users.c.user_id]
      ).execute()
    

    Podsumowanie

    SQLAlchemy to narzędzie proste, szybkie i wygodne, przyspieszające pracę programisty, który nie musi się już zamartwiać długimi zapytaniami z JOIN itp. Zdecydowanie POLECAM!( zwłaszcza do pracy z Pylonsem )


    Źródła wiedzy

    Po upgrajdzie do Ubuntu 10.10, aircrack przestał mi działać.

    Jak zwykle próbowałem ustawić w airodump-ng channel:

    
    airodump-ng --channel n
    
    

    Wyświetliło mi status:

    
    fixed channel mon0: -1
    
    

    Na jednym angielskim forum dyskusyjnym znalazłem rozwiązanie dla mojej karty sieciowej (atheros) i wygląda ono następująco:

    
    wget http://wireless.kernel.org/download/compat-wireless-2.6/compat-wireless-2010-10-16.tar.bz2
    tar -jxf compat-wireless-2010-10-16.tar.bz2
    cd compat-wireless-2010-10-16
    wget http://patches.aircrack-ng.org/mac80211.compat08082009.wl_frag+ack_v1.patch
    patch -p1 < mac80211.compat08082009.wl_frag+ack_v1.patch
    wget http://patches.aircrack-ng.org/channel-negative-one-maxim.patch
    patch ./net/wireless/chan.c channel-negative-one-maxim.patch
    gedit scripts/update-initramfs
    #* Znajdź LINIĘ : KLIB=/lib/modules/2.6.31-wl/build
    #* i Zamień NA: KLIB=/lib/modules/$(uname -r)/build
    make
    make install
    make unload
    reboot
    
    

    Jeżeli nie wykonujesz tych komend z konta roota to musisz korzystać z sudo.

    Mam nadzieję, że pomoże to wielu użytkownikom aricracka i Ubuntu 10.10 .