From 6c9116b143f33117ed77972bbcc25b582fbec8b2 Mon Sep 17 00:00:00 2001 From: gryf Date: Sat, 25 Nov 2006 08:13:51 +0000 Subject: [PATCH] * Change DB engine to sqlite. * Removed login stuff. * Improvements. --- moviedb.py | 292 +++++++++++++++++++++++------------------------------ 1 file changed, 128 insertions(+), 164 deletions(-) diff --git a/moviedb.py b/moviedb.py index eb101b6..db5612c 100755 --- a/moviedb.py +++ b/moviedb.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -*- coding: iso8859-2 -*- """ -MovieDB 0.7 +MovieDB 0.8 features: - szukanie po tytule filmu/serii @@ -23,12 +23,42 @@ todo: import sys import os -WRKDIR = sys.argv[0:][0].split('moviedb.py')[0] +WRKDIR = sys.argv[0:][0].split('moviedb2.py')[0] if WRKDIR[0] != '/': """ścieżka nie jest absolutna""" WRKDIR = os.getcwd()+"/"+WRKDIR + +try: + path = os.environ['HOME'] +except: + path = "/tmp" + +try: + # przeczytaj plik, o ile istnieje + f = open("%s/.moviedb" % path,"rw") + zpliku = f.read() + f.close() + p = {} + zpliku = zpliku.split("\n") + for i in zpliku: + i = i.split("\t") + p[i[0]] = i[1] + if len(p) == 5: + DB=p['db'] + CD=p['cdrom'] + EPORTXLS=p['exportxls'] + else: + DB="moviedb.db" + CD="/mnt/cdrom" + EPORTXLS=False +except: + # w przeciwnym przypadku przjmij wartości domyślne + DB="moviedb.db" + CD="/mnt/cdrom" + EPORTXLS=False + try: import pygtk #tell pyGTK, if possible, that we want GTKv2 @@ -49,55 +79,20 @@ except: #Also, we know we are running GTK v2 try: - from pyPgSQL import PgSQL - + from pysqlite2 import dbapi2 as sqlite except: - print "You need to install pyPgSQL to run this app\nhttp://pypgsql.sourceforge.net/" + print "MovieDB uses SQLite DB.\nYou'll need to get it and the python bindings as well.\nhttp://www.sqlite.org\nhttp://initd.org/tracker/pysqlite" sys.exit(1) -try: - import pyExcelerator -except: - print "You need pyExcelerator\nhttp://sourceforge.net/projects/pyexcelerator" - sys.exit(1) - +if EPORTXLS==True: + try: + import pyExcelerator + except: + print "You'll need pyExcelerator, if you want to export DB to XLS format.\nhttp://sourceforge.net/projects/pyexcelerator" + sys.exit(1) + #}}} -try: - path = os.environ['HOME'] -except: - path = "/tmp" - -try: - # przeczytaj plik, o ile istnieje - f = open("%s/.moviedb" % path,"rw") - zpliku = f.read() - f.close() - p = {} - zpliku = zpliku.split("\n") - for i in zpliku: - i = i.split("\t") - p[i[0]] = i[1] - if len(p) == 5: - USER=p['user'] - PASS=p['pass'] - HOST=p['host'] - DB=p['db'] - CD=p['cdrom'] - else: - USER="movie" - PASS="teamsleep" - HOST="localhost" - DB="moviedb" - CD="/mnt/cdrom" -except: - # w przeciwnym przypadku przjmij wartości domyślne - USER="movie" - PASS="teamsleep" - HOST="localhost" - DB="moviedb" - CD="/mnt/cdrom" - class SaveAsMDB: """pokazuje dialog zapisu(exportu) do pliku""" #{{{ @@ -214,27 +209,6 @@ class StdMSG: return self.result #}}} -class LoginMDB: - """pokazuje dialog logowania""" #{{{ - def __init__(self): - self.gladefile = WRKDIR + "/glade/moviedb.glade" - def run(self): - self.logingld = gtk.glade.XML(self.gladefile, "loginMDB") - self.login = self.logingld.get_widget("loginMDB") - try: - pixBuf = gtk.gdk.pixbuf_new_from_file(WRKDIR + "/pixmaps/login.png") - self.logingld.get_widget("loginImg").set_from_pixbuf(pixBuf) - except: - pass - - self.login.set_title("MovieDB - Login") - self.result = self.login.run() - l = self.logingld.get_widget("flogin").get_text() - p = self.logingld.get_widget("fpass").get_text() - self.login.destroy() - return self.result,[l,p] - #}}} - class AboutMDB: """pokazuje prosty dialog "o programie" """ #{{{ def __init__(self): @@ -257,14 +231,13 @@ class AboutMDB: class DetailsMDB: """Pokazuje okno z informacjami wyciągniętymi z DB na podstawie id tytułu""" #{{{ - def __init__(self, tid=0, perms=0): + def __init__(self, tid=0): """innicjalizacja obiektu""" gladefile=WRKDIR + "/glade/moviedb.glade" self.wDetails = gtk.glade.XML(gladefile,"winDetails") self.wDetails.get_widget("image1").set_from_file(WRKDIR + "/img/notavail.gif") # pomocnicze zmienne - self.perms = perms self.typ = '0' self.imgIndeks = 1 @@ -296,13 +269,11 @@ class DetailsMDB: self.sbid = 0 # główna robota: - cx = PgSQL.connect(user=USER, password=PASS, host=HOST, database=DB, client_encoding="iso8859-2") + cx = sqlite.connect(WRKDIR+"/db/"+DB,isolation_level=None) + cx.isolation_level = "IMMEDIATE" c = cx.cursor() - if self.perms != 2: - typ = 4 - else: - typ = 0 + typ = 0 # {{{ SQL: DetailsMDB#1 wyciągnięcie podstawowych informacji o tytule c.execute("SELECT\ @@ -496,35 +467,27 @@ class DetailsMDB: class MovieDB: """pokazująca główne okno aplikacji, pozwalająca na przeszukiwanie wśród plików i tytułów i wyświetlająca wynik wyszukiwania""" #{{{ - def __init__(self, perms=0): + def __init__(self,dbfile=None): - self.perms = perms self.gladefile=WRKDIR + "/glade/moviedb.glade" self.wTree=gtk.glade.XML(self.gladefile,"mainWin") # sygnały: dic = {"on_mainWin_destroy" :(gtk.main_quit),\ "on_quit1_activate" :(gtk.main_quit),\ - "on_szukaj_clicked" :(self.searchdb,self.perms),\ - "on_szukPat_activate" :(self.searchdb,self.perms),\ - "on_lista_row_activated" :(self.szczegoly,self.perms),\ + "on_szukaj_clicked" :(self.searchdb),\ + "on_szukPat_activate" :(self.searchdb),\ + "on_lista_row_activated" :(self.szczegoly),\ "on_about1_activate" :self.oprogramie,\ "on_cut1_activate" :self.showPrefs,\ "on_save_as1_activate" :self.exportToXLS} - # inicjalizacja dodatkowych pozycji w menu, jeśli uprawnienia pozwalają - if self.perms == 2: - pass - #self.wTree.get_widget("mainMenu"). - # podłączenie sygnałów self.wTree.signal_autoconnect(dic) # inicjalizacja combo boxów self.treeview=self.wTree.get_widget("pattMatch").set_active(0) self.treeview=self.wTree.get_widget("typ").set_active(0) - if self.perms ==2: - self.treeview=self.wTree.get_widget("typ").append_text('XXX') # inicjalizacja listy z tytułami import gobject self.treeview=self.wTree.get_widget("lista") @@ -563,9 +526,9 @@ class MovieDB: return myiter #####CALLBACKS - def szczegoly(self,treeview,path,view_column,perms=0): + def szczegoly(self,treeview,path,view_column): """pokaż szczegóły w nowym oknie.""" # {{{ - win = DetailsMDB(treeview.get_model().get_value(treeview.get_model().get_iter(path),0),perms) + win = DetailsMDB(treeview.get_model().get_value(treeview.get_model().get_iter(path),0)) #}}} def oprogramie(self, widget): @@ -579,7 +542,7 @@ class MovieDB: prefs = PrefsMDB() #}}} - def searchdb(self,widget,perms=0): + def searchdb(self,widget): """ułóż zapytanie i wypluj wyniki do treeview""" #{{{ if self.wTree.get_widget("pattMatch").get_active() == 3: pattern=self.wTree.get_widget("szukPat").get_text() @@ -589,13 +552,14 @@ class MovieDB: pattern=self.wTree.get_widget("szukPat").get_text() + "%" else: pattern="%" + self.wTree.get_widget("szukPat").get_text() + "%" - - cx = PgSQL.connect(user=USER, password=PASS, host=HOST, database=DB, client_encoding="iso8859-2") + + cx = sqlite.connect(WRKDIR+"/db/"+DB,isolation_level=None) + cx.isolation_level = "IMMEDIATE" c = cx.cursor() if self.wTree.get_widget("czalt").get_active(): - klon = False + klon = 'f' else: - klon = True + klon = 't' # szukaj wg typu: # NOTE: daj tu to, co potrzeba @@ -603,11 +567,12 @@ class MovieDB: if self.wTree.get_widget("radn").get_active(): # SQL: zapytanie zbierające tytuły filmów po kluczu nazw plików # TODO: zrobić tablicę przechowującą nr płyt (najlepiej triggerze) + """ c.execute("SELECT distinct\ a.id_tytulu,\ n.tytul,\ alt,\ - to_char (data_wydania,'YYYY'),\ + data_wydania,\ case\ when\ ilosc_w_serii is null then 0\ @@ -621,26 +586,25 @@ class MovieDB: ilosc_posiadanych\ end,\ nazwa_typu,\ - plyty_asstring(a.id_tytulu::text)\ + 1\ from\ nazwa_tytulu as n\ left join tytul a using(id_tytulu)\ left join typ as t using(id_typu)\ left join plik p using(id_tytulu)\ where\ - (alt is false or alt is %s)\ + (alt = 'f' or alt = %s)\ and nazwa_pliku ilike %s\ and id_typu in (%s, %s, %s, %s)\ and id_typu != %s\ order by\ - id_tytulu, alt",(klon,pattern.encode("iso8859-2"),anime,xxx,filmy,kreskowki,typ)) - else: - # SQL: zapytanie zbierające tytuły filmów - c.execute("SELECT \ + id_tytulu, alt",(klon,pattern,anime,xxx,filmy,kreskowki,typ)) + """ + c.execute("SELECT distinct\ a.id_tytulu,\ n.tytul,\ alt,\ - to_char (data_wydania,'YYYY'),\ + data_wydania,\ case\ when\ ilosc_w_serii is null then 0\ @@ -654,19 +618,63 @@ class MovieDB: ilosc_posiadanych\ end,\ nazwa_typu,\ - plyty_asstring(a.id_tytulu::text)\ + 1\ + from\ + nazwa_tytulu as n\ + left join tytul a using(id_tytulu)\ + left join typ as t using(id_typu)\ + left join plik p using(id_tytulu)") + else: + # SQL: zapytanie zbierające tytuły filmów + """ + c.execute("SELECT \ + a.id_tytulu,\ + n.tytul,\ + alt,\ + data_wydania,\ + case\ + when\ + ilosc_w_serii is null then 0\ + else\ + ilosc_w_serii\ + end,\ + case\ + when\ + ilosc_posiadanych is null then 0\ + else\ + ilosc_posiadanych\ + end,\ + nazwa_typu,\ + 1\ from\ nazwa_tytulu as n\ left join tytul a using(id_tytulu)\ left join typ as t using(id_typu)\ where\ - (alt is false or alt is %s)\ + (alt = 'f' or alt = %s)\ and tytul ilike %s\ and id_typu in (%s, %s, %s, %s)\ and id_typu != %s\ order by\ - id_tytulu, alt",(klon,pattern.encode("iso8859-2"),anime,xxx,filmy,kreskowki,typ)) - + id_tytulu, alt",(klon,pattern,anime,xxx,filmy,kreskowki,typ)) + """ + c.execute("SELECT distinct\ + a.id_tytulu,\ + n.tytul,\ + alt,\ + data_wydania,\ + ilosc_w_serii,\ + ilosc_posiadanych,\ + nazwa_typu,\ + 1\ + from\ + nazwa_tytulu as n\ + left join tytul as a on a.id_tytulu=n.id_tytulu\ + left join typ as t using (id_typu)\ + left join plik as p on p.id_tytulu=n.id_tytulu\ + where\ + tytul like '%s'" % pattern) + res = c.fetchall() cx.close() @@ -685,13 +693,13 @@ class MovieDB: ido=0 for i in res: if i[2] == True and ido == i[0]: - self.insert_row(model,iterobj,i[0],i[1].decode("iso8859-2"),i[4],i[5],i[3],i[6],i[7]) + self.insert_row(model,iterobj,i[0],i[1],i[4],i[5],i[3],i[6],i[7]) else: - iterobj = self.insert_row(model,None,i[0],i[1].decode("iso8859-2"),i[4],i[5],i[3],i[6],i[7]) + iterobj = self.insert_row(model,None,i[0],i[1],i[4],i[5],i[3],i[6],i[7]) ido = i[0] else: for i in res: - self.insert_row(model,None,i[0],i[1].decode("iso8859-2"),i[4],i[5],i[3],i[6],i[7]) + self.insert_row(model,None,i[0],i[1],i[4],i[5],i[3],i[6],i[7]) #model.set_sort_column_id(1,gtk.SORT_ASCENDING) @@ -729,10 +737,8 @@ class MovieDB: filmy = 2 kreskowki = 3 xxx = 4 - if self.perms !=2: - typ=4 - else: - typ=0 + + typ=0 return anime,filmy,kreskowki,xxx,typ @@ -766,7 +772,7 @@ class MovieDB: anime,filmy,kreskowki,xxx,typ = self.getType() - cx = PgSQL.connect(user=USER, password=PASS, host=HOST, database=DB, client_encoding="iso8859-2") + cx = sqlite.connect(user=USER, password=PASS, host=HOST, database=DB, client_encoding="iso8859-2") c = cx.cursor() sql = "select\ p.id_pliku,\ @@ -871,57 +877,15 @@ class MovieDB: #}}} # NOTE: koniec deklaracji klas. główny program: -petla = 0 -perms = 0 -while petla == 0: - # {{{ pokazanie dialogu logowania w pętli - login = LoginMDB() - result,loginPair = login.run() + +try: + app=MovieDB(sys.argv[1]) +except: + app=MovieDB() - #sprawdzenie co też użytkownik wpisał i dokonanie odpowiedniego zachowania - if (result == gtk.RESPONSE_OK): - # w przypadku naciśnięcia OK, pobranie z DB uprawnienia, jeśli login/hasło się zgadza - cx = PgSQL.connect(user=USER, password=PASS, host=HOST, database=DB, client_encoding="iso8859-2") - c = cx.cursor() - c.execute("SELECT\ - uprawnienia\ - from\ - users\ - where\ - login = %s\ - and password = md5(%s)\ - ", loginPair[0],loginPair[1]) - perms = c.fetchone() - cx.close() - - if perms==None: - # zły login lub hasło - m = StdMSG(u"MovieDB - Błąd logowania",u"Nieprawidłowy login lub hasło.\n",1) - m.run() - else: - # zapytanie zwróciło nie None; wychodzimy z pętli while. - petla = 1 - perms = perms[0] - elif (result == gtk.RESPONSE_CANCEL): - # user nacisnął cancel, więc nie chce, lub ne może się zalogować. sprawdzamy jak jest. - # pokazanie dialogu z pytaniem - m = StdMSG("MovieDB - Pytanie",u"Jesteś pewien, że nie chcesz się logować?\n") - res = m.run() - if(res == gtk.RESPONSE_OK): - # jeśli jest pewny, wychodzimy z pętli while. jeśli nie, nic nie robimy, - # okno logowanie pojawi się przy powtórnym obrocie pętli. - petla = 1 - else: - # user ubił okno logowania, lub pociągnął z krzyża, lub do dialogu został wysłany inny sygnał. - petla = 2 - #}}} - -if petla != 2: - # w przypadku pociągnięcia z krzyża wychodzimy z aplikacji, w pozostałych przypadkach uruchomione zostaje główne okno. - app=MovieDB(perms) - try: - gtk.main() - except KeyboardInterrupt: - gtk.main_quit +try: + gtk.main() +except KeyboardInterrupt: + gtk.main_quit