diff --git a/config.py b/config.py deleted file mode 100644 index 4b6a2ec..0000000 --- a/config.py +++ /dev/null @@ -1,141 +0,0 @@ -# This Python file uses the following encoding: utf-8 -""" -config parser object -""" - -#{{{ podstawowe importy i sprawdzenia -import sys -import os -from ConfigParser import ConfigParser - -class Ini(object): - def __init__(self): - self.ini = [] - - def add_section(self, section): - self.ini.append("[%s]" % section) - - def add_key(self, key, value): - self.ini.append("%s=%s" % (key, value)) - - def add_comment(self, comment): - self.ini.append(";%s" % comment) - - def add_verb(self, verb): - self.ini.append(verb) - - def show(self): - return "\n".join(self.ini) - - -class Config: - ini = Ini() - - confd = { - 'savewin' : True, - 'savepan' : True, - 'wx' : 800, - 'wy' : 600, - 'h' : 200, - 'v' : 300, - 'exportxls' : False, - 'cd' : '/cdrom', - 'ejectapp' : 'eject -r', - 'eject' : True, - 'pil': False, - 'gthumb':False, - 'exif':False, - 'confirmquit':True, - 'mntwarn':True, - 'confirmabandon':True, - 'showtoolbar':True, - 'showstatusbar':True, - } - - dictconf = { - "save main window size" : "savewin", - "save panes size" : "savepan", - "main window width" : "wx", - "main window height": "wy", - "horizontal panes": "h", - "vertical panes":"v", - "export xls":"exportxls", - "cd drive":"cd", - "eject command":"eject", - "image support":"pil", - 'confirm quit':'confirmquit', - 'warn mount/umount errors':'mntwarn', - 'confirm abandon current catalog':'confirmabandon', - 'show toolbar':'showtoolbar', - 'show statusbar and progress bar':'showstatusbar', - } - - dbool = ( - 'exportxls', - 'pil', - 'savewin', - 'savepan', - 'eject', - 'gthumb', - 'exif', - 'confirmquit', - 'mntwarn', - 'confirmabandon', - 'showtoolbar', - 'showstatusbar', - ) - - dstring = ('cd','eject') - - try: - path = os.environ['HOME'] - except: - path = "/tmp" - - def __init__(self): - pass - - def save(self): - try: - os.lstat("%s/.pygtktalog" % self.path) - except: - print "Saving preferences to %s/.pygtktalog" % self.path - newIni = Ini() - newIni.add_section("pyGTKtalog conf") - for opt in self.dictconf: - newIni.add_key(opt,self.confd[self.dictconf[opt]]) - try: - f = open("%s/.pygtktalog" % self.path,"w") - success = True - except: - print "Cannot open config file %s for writing." % (self.path, "/.pygtktalog") - success = False - f.write(newIni.show()) - f.close() - return success - - def load(self): - try: - # try to read config file - parser = ConfigParser() - parser.read("%s/.pygtktalog" % self.path) - for sec in parser.sections(): - if sec == 'pyGTKtalog conf': - for opt in parser.options(sec): - try: - if self.dictconf[opt] in self.dbool: - self.confd[self.dictconf[opt]] = parser.getboolean(sec,opt) - elif self.dictconf[opt] in self.dstring: - self.confd[self.dictconf[opt]] = parser.get(sec,opt) - else: - self.confd[self.dictconf[opt]] = parser.getint(sec,opt) - except: - pass - except: - pass - def __str__(self): - """show prefs in string way""" - string = "[varname]\tvalue\n" - for i in self.confd: - string+="%s\t%s\n" % (i,self.confd[i]) - return string diff --git a/db.py b/db.py deleted file mode 100644 index 9073e5a..0000000 --- a/db.py +++ /dev/null @@ -1,140 +0,0 @@ -# This Python file uses the following encoding: utf-8 -# filetype = ('r','d') - -import datetime -from pysqlite2 import dbapi2 as sqlite -import pygtk -import gtk -import gobject - -class dbfile: - def __init__(self,winobj,connection,cursor): - self.con = connection - self.cur = cursor - self.winobj = winobj - # create tree model - self.dirmodel = gtk.TreeStore(gobject.TYPE_INT, gobject.TYPE_STRING,str) - self.filemodel = gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING,str) - - def getDirectories(self,root=0): - """get directory tree from DB""" - - self.cur.execute("select count(id) from files where type=1") - self.count = self.cur.fetchone()[0] - if self.count>0: - frac = 1.0/self.count - else: - frac = 1.0 - self.count = 0 - - if self.winobj.sbid != 0: - self.winobj.status.remove(self.winobj.sbSearchCId, self.winobj.sbid) - self.winobj.sbid = self.winobj.status.push(self.winobj.sbSearchCId, "Fetching data from catalog file") - - def get_children(id, name, parent): - """fetch all children and place them in model""" - #{{{ - myiter = self.dirmodel.insert_before(parent,None) - self.dirmodel.set_value(myiter,0,id) - self.dirmodel.set_value(myiter,1,name) - - # isroot? - if parent == None: - self.dirmodel.set_value(myiter,2,gtk.STOCK_CDROM) - else: - self.dirmodel.set_value(myiter,2,gtk.STOCK_DIRECTORY) - self.cur.execute("SELECT o.child, f.filename FROM files_connect o LEFT JOIN files f ON o.child=f.id WHERE o.parent=? AND o.depth=1 AND f.type=1 ORDER BY f.filename",(id,)) - - # progress - self.winobj.progress.set_fraction(frac * self.count) - while gtk.events_pending(): gtk.main_iteration() - self.count = self.count + 1 - - for cid,name in self.cur.fetchall(): - get_children(cid, name, myiter) - #}}} - - # get initial roots from first, default root (id: 1) in the tree, - # and then add other subroots to tree model - if __debug__: - data = datetime.datetime.now() - self.cur.execute("SELECT o.child, f.filename FROM files_connect o LEFT JOIN files f ON o.child=f.id WHERE o.parent=1 AND o.depth=1 AND f.type=1 ORDER BY f.filename") - - # real volumes: - for id,name in self.cur.fetchall(): - get_children(id,name,None) - if __debug__: - print "[db.py] tree generation time: ", (datetime.datetime.now() - data) - - if self.winobj.sbid != 0: - self.winobj.status.remove(self.winobj.sbSearchCId, self.winobj.sbid) - self.winobj.sbid = self.winobj.status.push(self.winobj.sbSearchCId, "Idle") - - self.winobj.progress.set_fraction(0) - - return self.dirmodel - def getCurrentFiles(self,id): - self.filemodel.clear() - # parent for virtual '..' dir - #myiter = self.filemodel.insert_before(None,None) - #self.cur.execute("SELECT parent FROM files_connect WHERE child=? AND depth = 1",(id,)) - #self.filemodel.set_value(myiter,0,self.cur.fetchone()[0]) - #self.filemodel.set_value(myiter,1,'..') - #if __debug__: - # print datetime.datetime.fromtimestamp(ch[3]) - - # directories first - self.cur.execute("SELECT o.child, f.filename, f.size, f.date FROM files_connect o LEFT JOIN files f ON o.child=f.id WHERE o.parent=? AND o.depth=1 AND f.type=1 ORDER BY f.filename",(id,)) - for ch in self.cur.fetchall(): - myiter = self.filemodel.insert_before(None,None) - self.filemodel.set_value(myiter,0,ch[0]) - self.filemodel.set_value(myiter,1,ch[1]) - self.filemodel.set_value(myiter,2,ch[2]) - self.filemodel.set_value(myiter,3,datetime.datetime.fromtimestamp(ch[3])) - self.filemodel.set_value(myiter,4,1) - self.filemodel.set_value(myiter,5,'direktorja') - self.filemodel.set_value(myiter,6,gtk.STOCK_DIRECTORY) - #print datetime.datetime.fromtimestamp(ch[3]) - - # all the rest - self.cur.execute("SELECT o.child, f.filename, f.size, f.date, f.type FROM files_connect o LEFT JOIN files f ON o.child=f.id WHERE o.parent=? AND o.depth=1 AND f.type!=1 ORDER BY f.filename",(id,)) - for ch in self.cur.fetchall(): - myiter = self.filemodel.insert_before(None,None) - self.filemodel.set_value(myiter,0,ch[0]) - self.filemodel.set_value(myiter,1,ch[1]) - self.filemodel.set_value(myiter,2,ch[2]) - self.filemodel.set_value(myiter,3,datetime.datetime.fromtimestamp(ch[3])) - self.filemodel.set_value(myiter,4,ch[4]) - self.filemodel.set_value(myiter,5,'kategoria srategoria') - self.filemodel.set_value(myiter,6,gtk.STOCK_FILE) - #print datetime.datetime.fromtimestamp(ch[3]) - #self.filemodel.set_sort_func(1,self.sort_files_view) - return self.filemodel - - def sort_files_view(self,a,b,c): - print a,b,c - return 2 - - def getParent(self, idn): - #{{{ - self.cur.execute("SELECT parent FROM files_connect WHERE child = ? AND depth = 1",(idn,)) - - parentId = self.cur.fetchone() - if parentId: - return parentId[0] - return None - #}}} - def getInfo(self,idn): - #{{{ - self.cur.execute("SELECT filename, date, size, type FROM files WHERE id = ?",(idn,)) - set = self.cur.fetchone() - if set == None: - return '' - - string = """Filename: %s -Date: %s -Size: %s -type: %s""" % (set[0],datetime.datetime.fromtimestamp(set[1]),set[2],set[3]) - return string - - #}}} diff --git a/dialogs.py b/dialogs.py deleted file mode 100644 index 936230c..0000000 --- a/dialogs.py +++ /dev/null @@ -1,165 +0,0 @@ -# This Python file uses the following encoding: utf-8 - -import pygtk -import gtk - -class Qst: - """Show simple dialog for questions""" - #{{{ - def __init__(self, title="", message=""): - self.dialog = gtk.MessageDialog( - flags = gtk.DIALOG_DESTROY_WITH_PARENT, - type = gtk.MESSAGE_QUESTION, - buttons = gtk.BUTTONS_OK_CANCEL, - ) - self.dialog.set_title(title) - self.dialog.set_markup(message) - def run(self): - retval = self.dialog.run() - self.dialog.destroy() - if retval == gtk.RESPONSE_OK: - return True - return False - #}}} - -class Inf: - """Show simple dialog for notices""" - #{{{ - def __init__(self, title="", message=""): - self.dialog = gtk.MessageDialog( - flags = gtk.DIALOG_DESTROY_WITH_PARENT, - type = gtk.MESSAGE_INFO, - buttons = gtk.BUTTONS_OK, - ) - self.dialog.set_title(title) - self.dialog.set_markup(message) - self.dialog.connect('response', lambda dialog, response: self.ret(response)) - self.dialog.show() - def ret(self,result): - self.dialog.destroy() - return True - #}}} - -class Wrn: - """Show simple dialog for warnings""" - #{{{ - def __init__(self, title="", message=""): - self.dialog = gtk.MessageDialog( - flags = gtk.DIALOG_DESTROY_WITH_PARENT, - type = gtk.MESSAGE_WARNING, - buttons = gtk.BUTTONS_CLOSE, - ) - self.dialog.set_title(title) - self.dialog.set_markup(message) - self.dialog.connect('response', lambda dialog, response: self.ret(response)) - self.dialog.show() - def ret(self,result): - self.dialog.destroy() - return True - #}}} - -class Err: - """Show simple dialog for errors""" - #{{{ - def __init__(self, title="", message=""): - self.dialog = gtk.MessageDialog( - flags = gtk.DIALOG_DESTROY_WITH_PARENT, - type = gtk.MESSAGE_ERROR, - buttons = gtk.BUTTONS_CLOSE, - ) - self.dialog.set_title(title) - self.dialog.set_markup(message) - self.dialog.connect('response', lambda dialog, response: self.ret(response)) - self.dialog.run() - def ret(self,result): - self.dialog.destroy() - return True - #}}} - -class Abt: - """Show simple dialog for errors""" - #{{{ - def __init__(self, name=None, ver="", title="", authors=[],licence=""): - self.dialog = gtk.AboutDialog() - self.dialog.set_title(title) - self.dialog.set_version(ver) - self.dialog.set_license(licence) - self.dialog.set_name(name) - self.dialog.set_authors(authors) - self.dialog.connect('response', lambda dialog, response: self.dialog.destroy()) - self.dialog.show() - #}}} - -class InputDiskLabel: - """Sepcific dialog for quering user for a disc label""" - #{{{ - def __init__(self, label=""): - self.gladefile = "glade/dialogs.glade" - self.label = "" - if label!= None: - self.label = label - - def run(self): - gladexml = gtk.glade.XML(self.gladefile, "inputDialog") - dialog = gladexml.get_widget("inputDialog") - entry = gladexml.get_widget("volname") - entry.set_text(self.label) - result = dialog.run() - dialog.destroy() - if result == gtk.RESPONSE_OK: - return entry.get_text() - return None - #}}} - -class PointDirectoryToAdd: - """Sepcific dialog for quering user for selecting directory to add""" - #{{{ - def __init__(self,volname='',dirname=''): - self.gladefile = "glade/dialogs.glade" - self.gladexml = gtk.glade.XML(self.gladefile, "addDirDialog") - self.volname = self.gladexml.get_widget("dirvolname") - self.volname.set_text(volname) - self.directory = self.gladexml.get_widget("directory") - self.directory.set_text(dirname) - self.gladexml.signal_autoconnect({"on_browse_activate":self.show_dirchooser,"on_browse_clicked":self.show_dirchooser}) - - def show_dirchooser(self,widget): - """dialog for point the mountpoint""" - #{{{ - dialog = gtk.FileChooserDialog( - title="Choose directory to add", - action=gtk.FILE_CHOOSER_ACTION_OPEN, - buttons=( - gtk.STOCK_CANCEL, - gtk.RESPONSE_CANCEL, - gtk.STOCK_OPEN, - gtk.RESPONSE_OK - ) - ) - - dialog.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) - dialog.set_default_response(gtk.RESPONSE_OK) - - response = dialog.run() - if response == gtk.RESPONSE_OK: - self.directory.set_text(dialog.get_filename()) - dialog.destroy() - #}}} - - def run(self): - dialog = self.gladexml.get_widget("addDirDialog") - ch = True - result = dialog.run() - while ch: - if result == gtk.RESPONSE_OK and (self.volname.get_text()=='' or self.directory.get_text() == ''): - a = Err("Error - pyGTKtalog","Cannot add directory without path and disc label.") - ch = True - result = dialog.run() - else: - ch = False - dialog.destroy() - if result == gtk.RESPONSE_OK: - return self.volname.get_text(),self.directory.get_text() - else: - return None,None - #}}} diff --git a/files.py b/files.py deleted file mode 100644 index ae3ae6b..0000000 --- a/files.py +++ /dev/null @@ -1,47 +0,0 @@ -# This Python file uses the following encoding: utf-8 -# filetype = ('r','d') - -import datetime - -class fileObj: - """Main file object class""" - def __init__(self, name=None, size=0, filetype="r", mtime=0): - date = datetime.datetime(datetime.MINYEAR,1,1) - self.name = name - self.size = size - if filetype == 'r': - self.filetype = 1 - elif filetype == 'd': - self.filetype = 2 - self.members = [] - self.date = date.fromtimestamp(mtime) - - def add_member(self,member): - """add another fileObj to array""" - self.members.append(member) - if self.filetype == 'd': - self.size = self.calculate_my_size() - - def calculate_my_size(self): - """TODO: fixme!""" - size = 0 - for member in self.members: - size += member.get_size() - return size - - def get_size(self): - return self.size - - def __str__(self): - """show name of main object and his members """ - print "<%s>" % self.name - def showtree(obj,spc): - """how about members?""" - for i in obj.members: - if i.filetype == "d": - print "%s[%s]" % (spc, i.name) - else: - print "%s%s" % (spc, i.name) - showtree(i,spc+".") - showtree(self,".") - return "" diff --git a/filetypeHelper.py b/filetypeHelper.py deleted file mode 100644 index 6dce90f..0000000 --- a/filetypeHelper.py +++ /dev/null @@ -1,33 +0,0 @@ -# This Python file uses the following encoding: utf-8 -""" -functions for treat different files with different way -""" - -import string -import os -import popen2 - -def guess_video(path): - info = popen2.popen4('midentify "' + path + '"')[0].readlines() - video_format = '' - audio_codec = '' - video_codec = '' - video_x = '' - video_y = '' - for line in info: - l = line.split('=') - val = l[1].split('\n')[0] - if l[0] == 'ID_VIDEO_FORMAT': - video_format = val - elif l[0] == 'ID_AUDIO_CODEC': - audio_codec = val - elif l[0] == 'ID_VIDEO_CODEC': - video_codec = val - elif l[0] == 'ID_VIDEO_WIDTH': - video_x = val - elif l[0] == 'ID_VIDEO_HEIGHT': - video_y = val - return (video_format,video_codec,audio_codec,video_x,video_y) - -def guess_image(path): - pass diff --git a/mainwin.py b/mainwin.py deleted file mode 100644 index d913e65..0000000 --- a/mainwin.py +++ /dev/null @@ -1,759 +0,0 @@ -# This Python file uses the following encoding: utf-8 -""" -GUI, main window class and correspondig methods for pyGTKtalog app. -""" -#{{{ -licence = \ -""" -GPL v2 -http://www.gnu.org/licenses/gpl.txt -""" -#}}} - -__version__ = "0.5" -import sys -import os -import mimetypes -import popen2 -import datetime -import bz2 - -import pygtk -import gtk -import gtk.glade - -from pysqlite2 import dbapi2 as sqlite -import mx.DateTime - -from config import Config -import deviceHelper -import filetypeHelper -import dialogs -from preferences import Preferences -import db - -class PyGTKtalog: - def __init__(self): - """ init""" - # {{{ init - self.conf = Config() - self.conf.load() - - self.opened_catalog = None - self.db_tmp_filename = None - - self.gladefile = "glade/main.glade" - self.pygtkcat = gtk.glade.XML(self.gladefile,"main") - - self.window = self.pygtkcat.get_widget("main") - self.window.set_title("pyGTKtalog") - icon = gtk.gdk.pixbuf_new_from_file("pixmaps/mainicon.png") - self.window.set_icon_list(icon) - - self.progress = self.pygtkcat.get_widget("progressbar1") - - self.status = self.pygtkcat.get_widget("mainStatus") - self.sbSearchCId = self.status.get_context_id('detailed res') - self.sbid = self.status.push(self.sbSearchCId, "Idle") - - self.detailplaceholder = self.pygtkcat.get_widget("detailplace") - self.detailplaceholder.set_sensitive(False) - self.details = self.pygtkcat.get_widget("details") - self.details.hide() - - self.widgets = ("discs","files","details",'save1','save_as1', - 'cut1','copy1','paste1','delete1','add_cd','add_directory1', - 'tb_save','tb_addcd','tb_find' - ) - - for w in self.widgets: - a = self.pygtkcat.get_widget(w) - a.set_sensitive(False) - - # toolbar/status bar - self.menu_toolbar = self.pygtkcat.get_widget("toolbar1") - self.menu_toolbar.set_active(self.conf.confd['showtoolbar']) - self.menu_statusbar = self.pygtkcat.get_widget("status_bar1") - self.menu_statusbar.set_active(self.conf.confd['showstatusbar']) - self.toolbar = self.pygtkcat.get_widget("maintoolbar") - if self.conf.confd['showtoolbar']: - self.toolbar.show() - else: - self.toolbar.hide() - self.statusprogress = self.pygtkcat.get_widget("statusprogress") - if self.conf.confd['showstatusbar']: - self.statusprogress.show() - else: - self.statusprogress.hide() - - # trees - self.discs = self.pygtkcat.get_widget('discs') - c = gtk.TreeViewColumn('Filename') - cellpb = gtk.CellRendererPixbuf() - cell = gtk.CellRendererText() - c.pack_start(cellpb, False) - c.pack_start(cell, True) - c.set_attributes(cellpb, stock_id=2) - c.set_attributes(cell, text=1) - - self.discs.append_column(c) - - - self.files = self.pygtkcat.get_widget('files') - self.files.get_selection().set_mode(gtk.SELECTION_MULTIPLE) - - c = gtk.TreeViewColumn('Filename') - cellpb = gtk.CellRendererPixbuf() - cell = gtk.CellRendererText() - c.pack_start(cellpb, False) - c.pack_start(cell, True) - c.set_attributes(cellpb, stock_id=6) - c.set_attributes(cell, text=1) - - c.set_sort_column_id(1) - c.set_resizable(True) - self.files.append_column(c) - - c = gtk.TreeViewColumn('Size',gtk.CellRendererText(), text=2) - c.set_sort_column_id(2) - c.set_resizable(True) - self.files.append_column(c) - - c = gtk.TreeViewColumn('Date',gtk.CellRendererText(), text=3) - c.set_sort_column_id(3) - c.set_resizable(True) - self.files.append_column(c) - - c = gtk.TreeViewColumn('Category',gtk.CellRendererText(), text=5) - c.set_sort_column_id(5) - c.set_resizable(True) - self.files.append_column(c) - - # window size - a = self.pygtkcat.get_widget('hpaned1') - a.set_position(self.conf.confd['h']) - a = self.pygtkcat.get_widget('vpaned1') - a.set_position(self.conf.confd['v']) - self.window.resize(self.conf.confd['wx'],self.conf.confd['wy']) - - # signals: - dic = {"on_main_destroy_event" :self.doQuit, - "on_quit1_activate" :self.doQuit, - "on_tb_quit_clicked" :self.doQuit, - "on_new1_activate" :self.newDB, - "on_tb_new_clicked" :self.newDB, - "on_add_cd_activate" :self.addCD, - "on_tb_addcd_clicked" :self.addCD, - "on_add_directory1_activate" :self.addDirectory, - "on_about1_activate" :self.about, - "on_properties1_activate" :self.preferences, - "on_status_bar1_activate" :self.toggle_status_bar, - "on_toolbar1_activate" :self.toggle_toolbar, - "on_save1_activate" :self.save, - "on_tb_save_clicked" :self.save, - "on_save_as1_activate" :self.save_as, - "on_tb_open_clicked" :self.opendb, - "on_open1_activate" :self.opendb, - "on_discs_cursor_changed" :self.show_files, - "on_discs_row_activated" :self.collapse_expand_branch, - "on_files_cursor_changed" :self.show_details, - "on_files_row_activated" :self.change_view, - } - - # connect signals - self.pygtkcat.signal_autoconnect(dic) - self.window.connect("delete_event", self.deleteEvent) - #}}} - - def collapse_expand_branch(self, treeview, path, treecolumn): - """if possible, expand or collapse branch of tree""" - #{{{ - if treeview.row_expanded(path): - treeview.collapse_row(path) - else: - treeview.expand_row(path,False) - #}}} - - def show_details(self,treeview): - """show details about file""" - #{{{ - model, paths = treeview.get_selection().get_selected_rows() - try: - itera = model.get_iter(paths[0]) - if model.get_value(itera,4) == 1: - #directory, do nothin', just turn off view - if __debug__: - print "[mainwin.py] directory selected" - else: - #file, show what you got. - if __debug__: - print "[mainwin.py] some other thing selected" - except: - if __debug__: - print "[mainwin.py] insufficient iterator" - return - - if model.get_value(itera,4) == 1: - #directory, do nothin', just turn off view - self.details.hide() - buf = self.details.get_buffer() - buf.set_text('') - self.details.set_buffer(buf) - if __debug__: - print "[mainwin.py] directory selected" - elif model.get_value(itera,4) > 1: - #file, show what you got. - self.details.show() - txt = db.dbfile(self,self.con,self.cur).getInfo(model.get_value(itera,0)) - buf = self.details.get_buffer() - buf.set_text(txt) - self.details.set_buffer(buf) - if __debug__: - print "[mainwin.py] some other thing selected" - #}}} - - def change_view(self, treeview, path, treecolumn): - """show information or change directory deep down""" - #{{{ - model, paths = treeview.get_selection().get_selected_rows() - itera = model.get_iter(paths[0]) - current_id = model.get_value(itera,0) - if model.get_value(itera,4) == 1: - self.filemodel = db.dbfile(self,self.con,self.cur).getCurrentFiles(current_id) - self.files.set_model(self.filemodel) - - pat,col = self.discs.get_cursor() - if pat!=None: - if not self.discs.row_expanded(pat): - self.discs.expand_row(pat,False) - #self.discs.unselect_all() - - model, paths = self.discs.get_selection().get_selected_rows() - selected = None - new_iter = self.discs.get_model().iter_children(model.get_iter(pat)) - if new_iter: - while new_iter: - if model.get_value(new_iter,0) == current_id: - self.discs.set_cursor(model.get_path(new_iter)) - new_iter = model.iter_next(new_iter) - - - else: - #directory, do nothin', just turn off view - if __debug__: - print "[mainwin.py] directory selected" - #}}} - - def sort_files_view(self, model, iter1, iter2, data): - print 'aaaa' - - def show_files(self,treeview): - """show files after click on left side disc tree""" - #{{{ - model = treeview.get_model() - selected_item = model.get_value(model.get_iter(treeview.get_cursor()[0]),0) - self.filemodel = db.dbfile(self,self.con,self.cur).getCurrentFiles(selected_item) - self.files.set_model(self.filemodel) - - self.details.show() - txt = db.dbfile(self,self.con,self.cur).getInfo(selected_item) - buf = self.details.get_buffer() - buf.set_text(txt) - self.details.set_buffer(buf) - if __debug__: - print "[mainwin.py] some other thing selected" - - """ - iterator = treeview.get_model().get_iter_first(); - while iterator != None: - if model.get_value(iterator,0) == selected: - self.glade.get_widget(self.category_dict[model.get_value(iterator,0)]).show() - self.desc.set_markup("%s" % selected) - else: - self.glade.get_widget(self.category_dict[model.get_value(iterator,0)]).hide() - iterator = treeview.get_model().iter_next(iterator); - """ - #}}} - - def opendb(self,widget): - """open dtatabase file, decompress it to temp""" - #{{{ - try: - if self.unsaved_project: - if self.conf.confd['confirmabandon']: - obj = dialogs.Qst('Unsaved data - pyGTKtalog','There is not saved database\nDo you really want to abandon it?') - if not obj.run(): - return - except AttributeError: - pass - - - #create filechooser dialog - dialog = gtk.FileChooserDialog( - title="Open catalog", - action=gtk.FILE_CHOOSER_ACTION_OPEN, - buttons=( - gtk.STOCK_CANCEL, - gtk.RESPONSE_CANCEL, - gtk.STOCK_OPEN, - gtk.RESPONSE_OK - ) - ) - dialog.set_default_response(gtk.RESPONSE_OK) - - f = gtk.FileFilter() - f.set_name("Catalog files") - f.add_pattern("*.pgt") - dialog.add_filter(f) - f = gtk.FileFilter() - f.set_name("All files") - f.add_pattern("*.*") - dialog.add_filter(f) - - response = dialog.run() - tmp = self.opened_catalog - try: - self.opened_catalog = dialog.get_filename() - except: - self.opened_catalog = tmp - pass - dialog.destroy() - - if response == gtk.RESPONSE_OK: - # delete an existing temp file - try: - os.unlink(self.db_tmp_filename) - except: - pass - - # initial switches - self.db_tmp_filename = None - self.active_project = True - self.unsaved_project = False - self.window.set_title("untitled - pyGTKtalog") - - self.db_tmp_filename = "/tmp/pygtktalog%d.db" % datetime.datetime.now().microsecond - - source = bz2.BZ2File(self.opened_catalog, 'rb') - destination = open(self.db_tmp_filename, 'wb') - while True: - try: - data = source.read(1024000) - except: - dialogs.Err("Error opening file - pyGTKtalog","Cannot open file %s." % self.opened_catalog) - self.opened_catalog = None - self.newDB(self.window) - return - if not data: break - destination.write(data) - destination.close() - source.close() - - self.active_project = True - self.unsaved_project = False - - self.con = sqlite.connect("%s" % self.db_tmp_filename, detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES) - self.cur = self.con.cursor() - - self.window.set_title("%s - pyGTKtalog" % self.opened_catalog) - - for w in self.widgets: - try: - a = self.pygtkcat.get_widget(w) - a.set_sensitive(True) - except: - pass - # PyGTK FAQ entry 23.20 - while gtk.events_pending(): - gtk.main_iteration() - - self.__display_main_tree() - else: - self.opened_catalog = tmp - - #}}} - - def __create_database(self,filename): - """make all necessary tables in db file""" - #{{{ - self.con = sqlite.connect("%s" % filename, detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES) - self.cur = self.con.cursor() - self.cur.execute("create table files(id INTEGER PRIMARY KEY AUTOINCREMENT, filename TEXT, date datetime, size integer, type integer);") - self.cur.execute("create table files_connect(id INTEGER PRIMARY KEY AUTOINCREMENT, parent numeric, child numeric, depth numeric);") - self.cur.execute("insert into files values(1, 'root', 0, 0, 0);") - self.cur.execute("insert into files_connect values(1, 1, 1, 0);") - #}}} - - def save(self,widget): - """save database to file. compress it with gzip""" - #{{{ - if self.opened_catalog == None: - self.save_as(widget) - else: - self.__compress_and_save(self.opened_catalog) - #}}} - - def save_as(self,widget): - """save database to another file. compress it with gzip""" - #{{{ - dialog = gtk.FileChooserDialog( - title="Save catalog as...", - action=gtk.FILE_CHOOSER_ACTION_SAVE, - buttons=( - gtk.STOCK_CANCEL, - gtk.RESPONSE_CANCEL, - gtk.STOCK_SAVE, - gtk.RESPONSE_OK - ) - ) - - dialog.set_action(gtk.FILE_CHOOSER_ACTION_SAVE) - dialog.set_default_response(gtk.RESPONSE_OK) - dialog.set_do_overwrite_confirmation(True) - if widget.get_name() == 'save1': - dialog.set_title('Save catalog to file...') - - f = gtk.FileFilter() - f.set_name("Catalog files") - f.add_pattern("*.pgt") - dialog.add_filter(f) - f = gtk.FileFilter() - f.set_name("All files") - f.add_pattern("*.*") - dialog.add_filter(f) - - response = dialog.run() - if response == gtk.RESPONSE_OK: - filename = dialog.get_filename() - if filename[-4] == '.': - if filename[-3:].lower() != 'pgt': - filename = filename + '.pgt' - else: - filename = filename[:-3] + 'pgt' - else: - filename = filename + '.pgt' - self.__compress_and_save(filename) - self.opened_catalog = filename - - dialog.destroy() - #}}} - - def __compress_and_save(self,filename): - """compress and save temporary file to catalog""" - #{{{ - source = open(self.db_tmp_filename, 'rb') - destination = bz2.BZ2File(filename, 'w') - - while True: - data = source.read(1024000) - if not data: break - destination.write(data) - - destination.close() - source.close() - self.window.set_title("%s - pyGTKtalog" % filename) - self.unsaved_project = False - #}}} - - def toggle_toolbar(self,widget): - """toggle visibility of toolbar bar""" - #{{{ - self.conf.confd['showtoolbar'] = self.menu_toolbar.get_active() - if self.menu_toolbar.get_active(): - self.toolbar.show() - else: - self.toolbar.hide() - #}}} - - def toggle_status_bar(self,widget): - """toggle visibility of statusbat and progress bar""" - #{{{ - self.conf.confd['showstatusbar'] = self.menu_statusbar.get_active() - if self.menu_statusbar.get_active(): - self.statusprogress.show() - else: - self.statusprogress.hide() - #}}} - - def storeSettings(self): - """Store window size and pane position in config file (using config object)""" - #{{{ - if self.conf.confd['savewin']: - self.conf.confd['wx'], self.conf.confd['wy'] = self.window.get_size() - - if self.conf.confd['savepan']: - hpan = self.pygtkcat.get_widget('hpaned1') - vpan = self.pygtkcat.get_widget('vpaned1') - self.conf.confd['h'],self.conf.confd['v'] = hpan.get_position(), vpan.get_position() - - self.conf.save() - #}}} - - def preferences(self,widget): - """display preferences window""" - #{{{ - a = Preferences() - #}}} - - def doQuit(self, widget): - """quit and save window parameters to config file""" - #{{{ - try: - if widget.title: - pass - except: - # check if any unsaved project is on go. - try: - if self.unsaved_project: - if self.conf.confd['confirmquit']: - obj = dialogs.Qst('Quit application - pyGTKtalog','There is not saved database\nDo you really want to quit?') - if not obj.run(): - return - except AttributeError: - pass - self.storeSettings() - gtk.main_quit() - try: - self.con.commit() - self.cur.close() - self.con.close() - except: - pass - try: - os.unlink(self.db_tmp_filename) - except: - pass - return False - #}}} - - def newDB(self,widget): - """create database in temporary place""" - #{{{ - try: - if self.unsaved_project: - if self.conf.confd['confirmabandon']: - obj = dialogs.Qst('Unsaved data - pyGTKtalog','There is not saved database\nDo you really want to abandon it?') - if not obj.run(): - return - except AttributeError: - pass - self.active_project = True - self.unsaved_project = False - - self.window.set_title("untitled - pyGTKtalog") - for w in self.widgets: - try: - a = self.pygtkcat.get_widget(w) - a.set_sensitive(True) - except: - pass - # PyGTK FAQ entry 23.20 - while gtk.events_pending(): - gtk.main_iteration() - - # Create new database - if self.db_tmp_filename!=None: - self.con.commit() - self.cur.close() - self.con.close() - os.unlink(self.db_tmp_filename) - - self.db_tmp_filename = datetime.datetime.now() - self.db_tmp_filename = "/tmp/pygtktalog%d.db" % self.db_tmp_filename.microsecond - self.__create_database(self.db_tmp_filename) - - #clear treeview, if possible - try: - self.discs.get_model().clear() - except: - pass - try: - self.files.get_model().clear() - except: - pass - - #}}} - - def deleteEvent(self, widget, event, data=None): - """checkout actual database changed. If so, do the necessary ask.""" - #{{{ - try: - if self.unsaved_project: - if self.conf.confd['confirmquit']: - obj = dialogs.Qst('Quit application - pyGTKtalog','There is not saved database\nDo you really want to quit?') - if not obj.run(): - return True - except AttributeError: - pass - self.storeSettings() - try: - self.cur.close() - except: - pass - try: - self.con.close() - except: - pass - try: - os.unlink(self.db_tmp_filename) - except: - pass - return False - #}}} - - def run(self): - """show window and run app""" - #{{{ - self.window.show(); - gtk.main() - #}}} - - def addDirectory(self,widget): - """add directory structure from given location""" - #{{{ - obj = dialogs.PointDirectoryToAdd() - res = obj.run() - if res !=(None,None): - self.__scan(res[1],res[0]) - #}}} - - def addCD(self,widget): - """add directory structure from cd/dvd disc""" - #{{{ - mount = deviceHelper.volmount(self.conf.confd['cd']) - if mount == 'ok': - guessed_label = deviceHelper.volname(self.conf.confd['cd']) - obj = dialogs.InputDiskLabel(guessed_label) - label = obj.run() - if label != None: - - self.__scan(self.conf.confd['cd'],label) - - # umount/eject cd - if self.conf.confd['eject']: - msg = deviceHelper.eject_cd() - if msg != 'ok': - dialogs.Wrn("error ejecting device - pyGTKtalog","Cannot eject device pointed to %s.\nLast eject message:\n%s" % (self.conf.confd['cd'],msg)) - else: - msg = deviceHelper.volumount(self.conf.confd['cd']) - if msg != 'ok': - dialogs.Wrn("error unmounting device - pyGTKtalog","Cannot unmount device pointed to %s.\nLast umount message:\n%s" % (self.conf.confd['cd'],msg)) - else: - dialogs.Wrn("error mounting device - pyGTKtalog","Cannot mount device pointed to %s.\nLast mount message:\n%s" % (self.conf.confd['cd'],mount)) - #}}} - - def __scan(self,path,label,currentdb=None): - """scan content of the given path""" - #{{{ - mime = mimetypes.MimeTypes() - mov_ext = ('mkv','avi','ogg','mpg','wmv','mp4','mpeg') - img_ext = ('jpg','jpeg','png','gif','bmp','tga','tif','tiff','ilbm','iff','pcx') - - # count files in directory tree - count = 0 - if self.sbid != 0: - self.status.remove(self.sbSearchCId, self.sbid) - self.sbid = self.status.push(self.sbSearchCId, "Calculating number of files in directory tree...") - for root,kat,plik in os.walk(path): - for p in plik: - count+=1 - while gtk.events_pending(): gtk.main_iteration() - frac = 1.0/count - - self.count = 0 - - def __recurse(path,name,wobj,date=0,frac=0,size=0,idWhere=1): - """recursive scans the path - path = path string - name = field name - wobj = obiekt katalogu - date = data pliku - frac - kolejne krok w statusbarze. - idWhere - simple id parent, or "place" where to add node - """ - #{{{ - _size = size - walker = os.walk(path) - root,dirs,files = walker.next() - ftype = 1 - self.cur.execute("insert into files(filename, date, size, type) values(?,?,?,?)",(name, date, 0, ftype)) - self.cur.execute("select seq FROM sqlite_sequence WHERE name='files'") - currentid=self.cur.fetchone()[0] - self.cur.execute("insert into files_connect(parent,child,depth) values(?,?,?)",(currentid, currentid, 0)) - - if idWhere>0: - self.cur.execute("insert into files_connect(parent, child, depth) select r1.parent, r2.child, r1.depth + r2.depth + 1 as depth FROM files_connect r1, files_connect r2 WHERE r1.child = ? AND r2.parent = ? ",(idWhere, currentid)) - - for i in dirs: - st = os.stat(os.path.join(root,i)) - _size = _size + __recurse(os.path.join(path,i),i,wobj,st.st_mtime,frac,0,currentid) - - for i in files: - self.count = self.count + 1 - st = os.stat(os.path.join(root,i)) - - ### scan files - if i[-3:].lower() in mov_ext or \ - mime.guess_type(i)!= (None,None) and \ - mime.guess_type(i)[0].split("/")[0] == 'video': - # video only - info = filetypeHelper.guess_video(os.path.join(root,i)) - elif i[-3:].lower() in img_ext or \ - mime.guess_type(i)!= (None,None) and \ - mime.guess_type(i)[0].split("/")[0] == 'image': - pass - ### end of scan - - # progress/status - if wobj.sbid != 0: - wobj.status.remove(wobj.sbSearchCId, wobj.sbid) - wobj.sbid = wobj.status.push(wobj.sbSearchCId, "Scannig: %s" % (os.path.join(root,i))) - wobj.progress.set_fraction(frac * self.count) - # PyGTK FAQ entry 23.20 - while gtk.events_pending(): gtk.main_iteration() - - _size = _size + st.st_size - - self.cur.execute('insert into files(filename, date, size, type) values(?,?,?,?)',(i, st.st_mtime, st.st_size,2)) - self.cur.execute("select seq FROM sqlite_sequence WHERE name='files'") - currentfileid=self.cur.fetchone()[0] - self.cur.execute("insert into files_connect(parent,child,depth) values(?,?,?)",(currentfileid, currentfileid, 0)) - if currentid>0: - self.cur.execute("insert into files_connect(parent, child, depth) select r1.parent, r2.child, r1.depth + r2.depth + 1 as depth FROM files_connect r1, files_connect r2 WHERE r1.child = ? AND r2.parent = ? ",(currentid, currentfileid)) - self.con.commit() - - self.cur.execute("update files set size=? where id=?",(_size, currentid)) - return _size - #}}} - - self.con.commit() - __recurse(path,label,self,0,frac) - self.unsaved_project = True - self.__display_main_tree() - - if self.sbid != 0: - self.status.remove(self.sbSearchCId, self.sbid) - self.sbid = self.status.push(self.sbSearchCId, "Idle") - - self.progress.set_fraction(0) - #}}} - - def __display_main_tree(self): - """refresh tree with model form db""" - #{{{ - try: - self.dirmodel = db.dbfile(self,self.con,self.cur).getDirectories() - except: - dialogs.Err("Error opening file - pyGTKtalog","Cannot open file %s." % self.opened_catalog) - self.newDB(self.window) - return - #self.dirmodel.set_sort_column_id(1,gtk.SORT_ASCENDING) - self.discs.set_model(self.dirmodel) - #}}} - - def about(self,widget): - """simple about dialog""" - #{{{ - dialogs.Abt("pyGTKtalog", __version__, "About", ["Roman 'gryf' Dobosz"], licence) - #}}} - diff --git a/preferences.py b/preferences.py deleted file mode 100644 index bb3305e..0000000 --- a/preferences.py +++ /dev/null @@ -1,156 +0,0 @@ -# This Python file uses the following encoding: utf-8 -""" -Change, apply and save user defined preferences -""" -import sys -import os - -import pygtk -import gtk -import gtk.glade -import gobject - -from config import Config -import dialogs - -class Preferences: - def __init__(self): - self.category_dict = {'Disk options':'disk_group','General':'general_group','Scan options':'scan_group'} - self.category_order = ['General','Disk options','Scan options'] - self.conf = Config() - self.conf.load() - - self.gladefile = "glade/prefs.glade" - - self.glade = gtk.glade.XML(self.gladefile,"prefs") - dic = { - "on_button_ejt_clicked" :self.show_filechooser, - "on_button_mnt_clicked" :self.show_dirchooser, - "on_category_tree_cursor_changed" :self.activate_pan, - } - self.glade.signal_autoconnect(dic) - - self.pref = self.glade.get_widget("prefs") - self.pref.set_title("Preferences - pyGTKtalog") - self.desc = self.glade.get_widget("desc") - - self.cd = self.glade.get_widget("mnt_entry") - self.cd.set_text(self.conf.confd['cd']) - - self.eject = self.glade.get_widget("ejt_entry") - self.eject.set_text(self.conf.confd['ejectapp']) - - self.ch_win = self.glade.get_widget("ch_win") - self.ch_win.set_active(self.conf.confd['savewin']) - self.ch_pan = self.glade.get_widget("ch_pan") - self.ch_pan.set_active(self.conf.confd['savepan']) - self.ch_eject = self.glade.get_widget("ch_eject") - self.ch_eject.set_active(self.conf.confd['eject']) - self.ch_xls = self.glade.get_widget("ch_xls") - self.ch_xls.set_active(self.conf.confd['exportxls']) - self.ch_quit = self.glade.get_widget("ch_quit") - self.ch_quit.set_active(self.conf.confd['confirmquit']) - self.ch_wrnmount = self.glade.get_widget("ch_wrnmount") - self.ch_wrnmount.set_active(self.conf.confd['mntwarn']) - self.ch_warnnew = self.glade.get_widget("ch_warnnew") - self.ch_warnnew.set_active(self.conf.confd['confirmabandon']) - - self.ch_thumb = self.glade.get_widget("ch_thumb") - self.ch_thumb.set_active(self.conf.confd['pil']) - self.ch_exif = self.glade.get_widget("ch_exif") - self.ch_exif.set_active(self.conf.confd['exif']) - self.ch_gthumb = self.glade.get_widget("ch_gthumb") - self.ch_gthumb.set_active(self.conf.confd['gthumb']) - - self.tree = self.glade.get_widget("category_tree") - self.model = gtk.ListStore(gobject.TYPE_STRING) - self.model.clear() - self.tree.set_model(self.model) - self.tree.set_headers_visible(False) - self.tree.show() - - for i in self.category_order: - myiter = self.model.insert_before(None,None) - self.model.set_value(myiter,0,i) - - renderer=gtk.CellRendererText() - column=gtk.TreeViewColumn("Name",renderer, text=0) - column.set_resizable(True) - self.tree.append_column(column) - if self.pref.run() == gtk.RESPONSE_OK: - self.conf.confd['cd'] = self.cd.get_text() - self.conf.confd['ejectapp'] = self.eject.get_text() - self.conf.confd['savewin'] = self.ch_win.get_active() - self.conf.confd['savepan'] = self.ch_pan.get_active() - self.conf.confd['eject'] = self.ch_eject.get_active() - self.conf.confd['pil'] = self.ch_thumb.get_active() - self.conf.confd['exif'] = self.ch_exif.get_active() - self.conf.confd['gthumb'] = self.ch_gthumb.get_active() - self.conf.confd['exportxls'] = self.ch_xls.get_active() - self.conf.confd['confirmquit'] = self.ch_quit.get_active() - self.conf.confd['mntwarn'] = self.ch_wrnmount.get_active() - self.conf.confd['confirmabandon'] = self.ch_warnnew.get_active() - self.conf.save() - self.pref.destroy() - - def show_filechooser(self,widget): - """dialog for choose eject""" - dialog = gtk.FileChooserDialog( - title="Choose eject program", - action=gtk.FILE_CHOOSER_ACTION_OPEN, - buttons=( - gtk.STOCK_CANCEL, - gtk.RESPONSE_CANCEL, - gtk.STOCK_OPEN, - gtk.RESPONSE_OK - ) - ) - - dialog.set_default_response(gtk.RESPONSE_OK) - - response = dialog.run() - if response == gtk.RESPONSE_OK: - self.eject.set_text(dialog.get_filename()) - - dialog.destroy() - - def show_dirchooser(self,widget): - """dialog for point the mountpoint""" - dialog = gtk.FileChooserDialog( - title="Choose mount point", - action=gtk.FILE_CHOOSER_ACTION_OPEN, - buttons=( - gtk.STOCK_CANCEL, - gtk.RESPONSE_CANCEL, - gtk.STOCK_OPEN, - gtk.RESPONSE_OK - ) - ) - - dialog.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) - dialog.set_filename(self.conf.confd['cd']) - dialog.set_default_response(gtk.RESPONSE_OK) - - response = dialog.run() - if response == gtk.RESPONSE_OK: - self.cd.set_text(dialog.get_filename()) - dialog.destroy() - - def activate_pan(self,treeview): - model = treeview.get_model() - selected = model.get_value(model.get_iter(treeview.get_cursor()[0]),0) - iterator = treeview.get_model().get_iter_first(); - while iterator != None: - if model.get_value(iterator,0) == selected: - self.glade.get_widget(self.category_dict[model.get_value(iterator,0)]).show() - self.desc.set_markup("%s" % selected) - else: - self.glade.get_widget(self.category_dict[model.get_value(iterator,0)]).hide() - iterator = treeview.get_model().iter_next(iterator); - -if __name__ == "__main__": - try: - app=Preferences() - gtk.main() - except KeyboardInterrupt: - gtk.main_quit diff --git a/pyGTKtalog b/pyGTKtalog deleted file mode 100755 index 4eae7ad..0000000 --- a/pyGTKtalog +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# Simple wraper to launch python application from desired place. -cd ~/Devel/Python/pyGTKtalog -#export PYTHONPATH="$PYTHONPATH:/usr/lib/gajim" -#exec python -OO pyGTKtalog.py $@ -exec python pyGTKtalog.py $@ diff --git a/pyGTKtalog.py b/pyGTKtalog.py deleted file mode 100755 index c3a648d..0000000 --- a/pyGTKtalog.py +++ /dev/null @@ -1,74 +0,0 @@ -# This Python file uses the following encoding: utf-8 -""" -pytGTKtalog. - -A wannabe replacement for excellent gtktalog application. - -pyGTKtalog is an application for catalogue/index files on removable media such -a CD or DVD discs, directories on hard disks or network shares. - -""" -#{{{ try to import all necessary modules -import sys -import os - -try: - from config import Config -except: - print "Some fundamental files are missing. try runnig pyGTKtalog in his root directory" - sys.exit(1) - -conf = Config() - -try: - import pygtk - #tell pyGTK, if possible, that we want GTKv2 - pygtk.require("2.0") -except: - #Some distributions come with GTK2, but not pyGTK - pass -try: - import gtk - import gtk.glade -except: - print "You need to install pyGTK or GTKv2 ", - print "or set your PYTHONPATH correctly." - print "try: export PYTHONPATH=", - print "/usr/local/lib/python2.2/site-packages/" - sys.exit(1) - -try: - from pysqlite2 import dbapi2 as sqlite - import mx.DateTime -except: - print "pyGTKtalog 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) - -if conf.confd['exportxls']: - 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) - -if conf.confd['pil']: - try: - import Image, ImageEnhance - except: - print "You'll need Python Imaging Library (PIL), if you want to make thumbnails" - sys.exit(1) - -# project modules -from mainwin import PyGTKtalog - -if __name__ == "__main__": - app=PyGTKtalog() - try: - app.run() - except KeyboardInterrupt: - app.storeSettings() - app.cur.close() - app.con.close() - os.unlink(app.db_tmp_filename) - gtk.main_quit -