1
0
mirror of https://github.com/gryf/pygtktalog.git synced 2025-12-17 11:30:19 +01:00

* Added drag and drop support from files TreeView to tags cloud.

* Added tags add.
 * Code clean up.
 * Removed unnecessary imports.
 * Adapted to PEP8.
This commit is contained in:
2008-04-16 14:07:18 +00:00
parent f98c905591
commit a98ba36a23
4 changed files with 764 additions and 612 deletions

4
README
View File

@@ -60,8 +60,8 @@ TODO
For version 1.0 following aims have to be done:
- searching database
- tagging files
- user definied group of tags (represented by color in cloud tag)
- tagging files (40%)
- user definied group of tags (represented by color in cloud tag) (10%)
x file details:
x files properties
x thumbnail

View File

@@ -23,7 +23,7 @@
# -------------------------------------------------------------------------
__version__ = "0.8"
licence = \
LICENCE = \
"""
GPL v2
http://www.gnu.org/licenses/gpl.txt
@@ -34,9 +34,12 @@ from os import popen
from utils import deviceHelper
from gtkmvc import Controller
from time import time, ctime
from c_config import ConfigController
from views.v_config import ConfigView
from models.m_config import ConfigModel
from c_tags import TagsController
from views.v_tags import TagsView
import views.v_dialogs as Dialogs
@@ -45,27 +48,22 @@ from views.v_image import ImageView
import gtk
import pango
import datetime
class MainController(Controller):
"""Controller for main application window"""
scan_cd = False
widgets = (
"discs","files",
'save1','save_as1','cut1','copy1','paste1','delete1','add_cd','add_directory1',
'tb_save','tb_addcd','tb_find','nb_dirs','description','stat1',
)
widgets_all = (
"discs","files",
'file1','edit1','add_cd','add_directory1','help1',
'tb_save','tb_addcd','tb_find','tb_new','tb_open','tb_quit',
'nb_dirs','description','stat1',
)
widgets = ("discs", "files", 'save1', 'save_as1', 'cut1', 'copy1',
'paste1', 'delete1', 'add_cd', 'add_directory1', 'tb_save',
'tb_addcd', 'tb_find', 'nb_dirs', 'description', 'stat1')
widgets_all = ("discs", "files", 'file1', 'edit1', 'add_cd',
'add_directory1', 'help1', 'tb_save', 'tb_addcd', 'tb_find',
'tb_new', 'tb_open', 'tb_quit', 'nb_dirs', 'description',
'stat1')
widgets_cancel = ('cancel','cancel1')
def __init__(self, model):
"""Initialize controller"""
self.DND_TARGETS = [('files_tags', 0, 69)]
Controller.__init__(self, model)
return
@@ -88,8 +86,9 @@ class MainController(Controller):
self.view['debugbtn'].hide()
# load configuration/defaults and set it to properties
self.view['toolbar1'].set_active(self.model.config.confd['showtoolbar'])
if self.model.config.confd['showtoolbar']:
bo = self.model.config.confd['showtoolbar']
self.view['toolbar1'].set_active(bo)
if bo:
self.view['maintoolbar'].show()
else:
self.view['maintoolbar'].hide()
@@ -105,15 +104,24 @@ class MainController(Controller):
self.model.config.confd['wy'])
# initialize statusbar
self.context_id = self.view['mainStatus'].get_context_id('detailed res')
context = self.view['mainStatus'].get_context_id('detailed res')
self.context_id = context
self.statusbar_id = self.view['mainStatus'].push(self.context_id,
"Idle")
# make tag_cloud_textview recive dnd signals
self.view['tag_cloud_textview'].drag_dest_set(gtk.DEST_DEFAULT_ALL,
self.DND_TARGETS,
gtk.gdk.ACTION_COPY)
#ttv.connect('drag_motion', self.on_tag_cloud_textview_drag_motion)
#ttv.connect('drag_drop', self.on_tag_cloud_textview_drag_drop)
# initialize treeviews
self.__setup_disc_treeview()
self.__setup_files_treeview()
self.__setup_exif_treeview()
# in case passing catalog filename in command line, unlock gui
if self.model.filename != None:
self.__activate_ui(self.model.filename)
@@ -121,26 +129,60 @@ class MainController(Controller):
# generate recent menu
self.__generate_recent_menu()
# initialoze tag cloud
self.__tag_cloud()
# Show main window
self.view['main'].show();
self.view['main'].drag_dest_set(0, [], 0)
return
#########################################################################
# Connect signals from GUI, like menu objects, toolbar buttons and so on.
def on_tag_cloud_textview_drag_drop(self, wid, context, x, y, time):
#print '\n'.join([str(t) for t in context.targets])
#print context.drag_get_selection()
#print context.get_source_widget()
#print x, y
#print wid
context.finish(True, False, time)
return True
def on_tag_cloud_textview_drag_motion(self, wid, context, x, y, time):
context.drag_status(gtk.gdk.ACTION_COPY, time)
return True
def on_files_drag_data_get(self, widget, context, selection,
targetType, eventTime):
# get selection, and send it to the client
if targetType == self.DND_TARGETS[0][2]:
str = "1,2,3,4,57,9,0,"
selection.set(selection.target, 8, str)
def on_tag_cloud_textview_drag_data_received(self, widget, context, x, y,
selection, targetType, time):
if targetType == self.DND_TARGETS[0][2]:
print selection.data
print "kupa"
def on_edit2_activate(self, menu_item):
try:
selection = self.view['files'].get_selection()
model, list_of_paths = selection.get_selected_rows()
id = model.get_value(model.get_iter(list_of_paths[0]), 0)
except TypeError:
if __debug__: print "c_main.py: on_edit2_activate(): 0 zaznaczonych wierszy"
if __debug__:
print "c_main.py: on_edit2_activate(): 0",
print "zaznaczonych wierszy"
return
val = self.model.get_file_info(id)
ret = Dialogs.EditDialog(val).run()
if ret:
self.model.rename(id, ret['filename'])
self.model.update_desc_and_note(id, ret['description'], ret['note'])
self.model.update_desc_and_note(id,
ret['description'], ret['note'])
self.__get_item_info(id)
self.model.unsaved_project = True
self.__set_title(filepath=self.model.filename, modified=True)
@@ -158,7 +200,9 @@ class MainController(Controller):
self.model.unsaved_project = True
self.__set_title(filepath=self.model.filename, modified=True)
except:
if __debug__: print "c_main.py: on_add_thumb1_activate(): error on getting selected items or creating thumbnails"
if __debug__:
print "c_main.py: on_add_thumb1_activate(): error on getting",
print "selected items or creating thumbnails"
return
self.__get_item_info(id)
return
@@ -166,7 +210,8 @@ class MainController(Controller):
def on_remove_thumb1_activate(self, menu_item):
if self.model.config.confd['delwarn']:
obj = Dialogs.Qst('Delete thumbnails', 'Delete thumbnails?',
'Thumbnails for selected items will be permanently removed from catalog.')
"Thumbnails for selected items will be \
permanently removed from catalog.")
if not obj.run():
return
try:
@@ -176,7 +221,9 @@ class MainController(Controller):
id = model.get_value(model.get_iter(path),0)
self.model.del_thumbnail(id)
except:
if __debug__: print "c_main.py: on_remove_thumb1_activate(): error on getting selected items or removing thumbnails"
if __debug__:
print "c_main.py: on_remove_thumb1_activate(): error on",
print "getting selected items or removing thumbnails"
return
self.model.unsaved_project = True
@@ -187,7 +234,8 @@ class MainController(Controller):
def on_remove_image1_activate(self, menu_item):
if self.model.config.confd['delwarn']:
obj = Dialogs.Qst('Delete images', 'Delete all images?',
'All images for selected items will be permanently removed from catalog.')
'All images for selected items will be \
permanently removed from catalog.')
if not obj.run():
return
try:
@@ -197,7 +245,9 @@ class MainController(Controller):
id = model.get_value(model.get_iter(path),0)
self.model.del_images(id)
except:
if __debug__: print "c_main.py: on_remove_thumb1_activate(): error on getting selected items or removing thumbnails"
if __debug__:
print "c_main.py: on_remove_thumb1_activate(): error on",
print "getting selected items or removing thumbnails"
return
self.model.unsaved_project = True
@@ -211,12 +261,14 @@ class MainController(Controller):
id = model.get_value(iter, 0)
img = self.model.get_image_path(id)
if img:
if self.model.config.confd['imgview'] and len(self.model.config.confd['imgprog'])>0:
if self.model.config.confd['imgview'] and \
len(self.model.config.confd['imgprog'])>0:
popen("%s %s" % (self.model.config.confd['imgprog'], img))
else:
ImageView(img)
else:
Dialogs.Inf("Image view", "No Image", "This item have no real image, only thumbnail.")
Dialogs.Inf("Image view", "No Image",
"This item have no real image, only thumbnail.")
def on_rename1_activate(self, widget):
model, iter = self.view['discs'].get_selection().get_selected()
@@ -224,7 +276,8 @@ class MainController(Controller):
id = model.get_value(iter, 0)
new_name = Dialogs.InputNewName(name).run()
if __debug__: print "c_main.py: on_rename1_activate(): label:", new_name
if __debug__:
print "c_main.py: on_rename1_activate(): label:", new_name
if new_name != None and new_name != name:
self.model.rename(id, new_name)
@@ -246,7 +299,8 @@ class MainController(Controller):
name = model.get_value(model.get_iter(list_of_paths[0]),1)
new_name = Dialogs.InputNewName(name).run()
if __debug__: print "c_main.py: on_rename1_activate(): label:", new_name
if __debug__:
print "c_main.py: on_rename1_activate(): label:", new_name
if new_name != None and new_name != name:
self.model.rename(fid, new_name)
@@ -265,20 +319,34 @@ class MainController(Controller):
return
def on_tag_cloud_textview_motion_notify_event(self, widget):
if __debug__: print "c_main.py: on_tag_cloud_textview_motion_notify_event():"
if __debug__:
print "c_main.py: on_tag_cloud_textview_motion_notify_event():"
w = self.view['tag_cloud_textview'].get_window(gtk.TEXT_WINDOW_TEXT)
if w:
w.set_cursor(None)
def on_main_destroy_event(self, window, event):
self.__do_quit()
self.on_quit1_activate(widget)
return True
def on_tb_quit_clicked(self, widget):
self.__do_quit()
self.on_quit1_activate(widget)
def on_quit1_activate(self, widget):
self.__do_quit()
"""Quit and save window parameters to config file"""
# check if any unsaved project is on go.
if self.model.unsaved_project and \
self.model.config.confd['confirmquit']:
if not Dialogs.Qst('Quit application - pyGTKtalog',
'Do you really want to quit?',
"Current database is not saved, any changes \
will be lost.").run():
return
self.__store_settings()
self.model.cleanup()
gtk.main_quit()
return False
def on_new1_activate(self, widget):
self.__new_db()
@@ -286,11 +354,34 @@ class MainController(Controller):
def on_tb_new_clicked(self, widget):
self.__new_db()
def on_add_cd_activate(self, widget):
self.__add_cd()
def on_add_cd_activate(self, widget, label=None, current_id=None):
"""Add directory structure from cd/dvd disc"""
mount = deviceHelper.volmount(self.model.config.confd['cd'])
if mount == 'ok':
guessed_label = deviceHelper.volname(self.model.config.confd['cd'])
if not label:
label = Dialogs.InputDiskLabel(guessed_label).run()
if label != None:
self.scan_cd = True
for widget in self.widgets_all:
self.view[widget].set_sensitive(False)
self.model.source = self.model.CD
self.model.scan(self.model.config.confd['cd'], label,
current_id)
self.model.unsaved_project = True
self.__set_title(filepath=self.model.filename, modified=True)
else:
deviceHelper.volumount(self.model.config.confd['cd'])
return True
else:
Dialogs.Wrn("Error mounting device - pyGTKtalog",
"Cannot mount device pointed to %s" %
self.model.config.confd['cd'],
"Last mount message:\n%s" % mount)
return False
def on_tb_addcd_clicked(self, widget):
self.__add_cd()
self.on_add_cd_activate(widget)
def on_add_directory1_activate(self, widget):
"""Show dialog for choose drectory to add from filesystem."""
@@ -300,7 +391,7 @@ class MainController(Controller):
def on_about1_activate(self, widget):
"""Show about dialog"""
Dialogs.Abt("pyGTKtalog", __version__, "About",
["Roman 'gryf' Dobosz"], licence)
["Roman 'gryf' Dobosz"], LICENCE)
return
def on_preferences_activate(self, widget):
@@ -327,13 +418,27 @@ class MainController(Controller):
self.view['maintoolbar'].hide()
def on_save1_activate(self, widget):
self.__save()
"""Save catalog to file"""
if self.model.filename:
self.model.save()
self.__set_title(filepath=self.model.filename)
else:
self.on_save_as1_activate(widget)
def on_tb_save_clicked(self, widget):
self.__save()
self.on_save1_activate(widget)
def on_save_as1_activate(self, widget):
self.__save_as()
"""Save database to file under different filename."""
path = Dialogs.ChooseDBFilename().run()
if path:
ret, err = self.model.save(path)
if ret:
self.model.config.add_recent(path)
self.__set_title(filepath=path)
else:
Dialogs.Err("Error writing file - pyGTKtalog",
"Cannot write file %s." % path, "%s" % err)
def on_stat1_activate(self, menu_item):
self.__show_stats()
@@ -350,10 +455,30 @@ class MainController(Controller):
self.__show_stats(selected_id)
def on_tb_open_clicked(self, widget):
self.__open()
self.on_open1_activate(widget)
return
def on_open1_activate(self, widget):
self.__open()
def on_open1_activate(self, widget, path=None):
"""Open catalog file"""
confirm = self.model.config.confd['confirmabandon']
if self.model.unsaved_project and confirm:
obj = Dialogs.Qst('Unsaved data - pyGTKtalog',
'There is not saved database',
'Pressing "Ok" will abandon catalog.')
if not obj.run():
return
if not path:
path = Dialogs.LoadDBFile().run()
if path:
if not self.model.open(path):
Dialogs.Err("Error opening file - pyGTKtalog",
"Cannot open file %s." % path)
else:
self.__generate_recent_menu()
self.__activate_ui(path)
return
def on_discs_cursor_changed(self, widget):
"""Show files on right treeview, after clicking the left disc
@@ -377,7 +502,8 @@ class MainController(Controller):
def on_images_button_press_event(self, iconview, event):
try:
path_and_cell = iconview.get_item_at_pos(int(event.x), int(event.y))
path_and_cell = iconview.get_item_at_pos(int(event.x),
int(event.y))
except TypeError:
return False
@@ -394,7 +520,7 @@ class MainController(Controller):
def on_img_delete_activate(self, menu_item):
if self.model.config.confd['delwarn']:
obj = Dialogs.Qst('Delete image', 'Delete image?',
'Selected image will be permanently removed from catalog.')
'Selected image will be permanently removed from catalog.')
if not obj.run():
return
list_of_paths = self.view['images'].get_selected_items()
@@ -487,6 +613,8 @@ class MainController(Controller):
self.view['edit2'].set_sensitive(True)
self.__popup_menu(event, 'files_popup')
return True
if event.button == 1:
return False
def on_files_cursor_changed(self, treeview):
"""Show details of selected file/directory"""
@@ -497,7 +625,9 @@ class MainController(Controller):
selected_item = self.model.files_list.get_value(iter, 0)
self.__get_item_info(selected_item)
except:
if __debug__: print "c_main.py: on_files_cursor_changed() insufficient iterator"
if __debug__:
print "c_main.py: on_files_cursor_changed() insufficient",
print "iterator"
return
def on_files_key_release_event(self, a, event):
@@ -516,8 +646,8 @@ class MainController(Controller):
first_iter = f_model.get_iter_first()
first_child_value = f_model.get_value(first_iter, 0)
# get two steps up
value = self.model.get_parent_discs_value(first_child_value)
parent_value = self.model.get_parent_discs_value(value)
val = self.model.get_parent_discs_value(first_child_value)
parent_value = self.model.get_parent_discs_value(val)
iter = self.model.discs_tree.get_iter_first()
while iter:
current_value = self.model.discs_tree.get_value(iter,0)
@@ -565,15 +695,36 @@ class MainController(Controller):
return
def recent_item_response(self, path):
self.__open(path)
self.on_open1_activate(widget)
return
def on_add_tag1_activate(self, menu_item):
print self.view['files'].get_cursor()
#try:
selection = self.view['files'].get_selection()
model, list_of_paths = selection.get_selected_rows()
tags = Dialogs.TagsDialog().run()
if not tags:
return
for path in list_of_paths:
id = model.get_value(model.get_iter(path),0)
self.model.add_tags(id, tags)
#except:
# if __debug__:
# print "c_main.py: on_remove_thumb1_activate(): error on",
# print "getting selected items or removing thumbnails"
# return
self.__tag_cloud()
self.model.unsaved_project = True
self.__set_title(filepath=self.model.filename, modified=True)
self.__get_item_info(id)
return
def on_add_image1_activate(self, menu_item):
dialog = Dialogs.LoadImageFile(True)
toggle = gtk.CheckButton("Don't copy images. Generate only thumbnails.")
toggle = gtk.CheckButton("Don't copy images. \
Generate only thumbnails.")
toggle.show()
dialog.dialog.set_extra_widget(toggle)
@@ -613,8 +764,7 @@ class MainController(Controller):
fid = model.get_value(model.get_iter(path), 0)
if self.model.get_source(path) == self.model.CD:
self.__add_cd(label, fid)
self.on_add_cd_activate(widget, label, fid)
elif self.model.get_source(path) == self.model.DR:
self.__add_directory(filepath, label, fid)
@@ -672,8 +822,9 @@ class MainController(Controller):
return
if self.model.config.confd['delwarn']:
obj = Dialogs.Qst('Delete elements', 'Delete items?',
'Items will be permanently removed from catalog.')
obj = Dialogs.Qst("Delete elements", "Delete items?",
"Items will be permanently \
removed from catalog.")
if not obj.run():
return
@@ -699,7 +850,8 @@ class MainController(Controller):
model, list_of_paths = selection.get_selected_rows()
if not list_of_paths:
list_of_paths = [1]
self.model.get_root_entries(model.get_value(model.get_iter(list_of_paths[0]),0))
iter = model.get_iter(list_of_paths[0])
self.model.get_root_entries(model.get_value(iter,0))
except TypeError:
return
@@ -716,7 +868,8 @@ class MainController(Controller):
def on_th_delete_activate(self, menu_item):
if self.model.config.confd['delwarn']:
obj = Dialogs.Qst('Delete thumbnail', 'Delete thumbnail?',
'Current thumbnail will be permanently removed from catalog.')
"Current thumbnail will be permanently removed\
from catalog.")
if not obj.run():
return
path, column = self.view['files'].get_cursor()
@@ -785,73 +938,6 @@ class MainController(Controller):
#########################
# private class functions
def __open(self, path=None):
"""Open catalog file"""
confirm = self.model.config.confd['confirmabandon']
if self.model.unsaved_project and confirm:
obj = Dialogs.Qst('Unsaved data - pyGTKtalog','There is not saved database','Pressing "Ok" will abandon catalog.')
if not obj.run():
return
if not path:
path = Dialogs.LoadDBFile().run()
if path:
if not self.model.open(path):
Dialogs.Err("Error opening file - pyGTKtalog","Cannot open \
file %s." % path)
else:
self.__generate_recent_menu()
self.__activate_ui(path)
return
def __save(self):
"""Save catalog to file"""
if self.model.filename:
self.model.save()
self.__set_title(filepath=self.model.filename)
else:
self.__save_as()
pass
def __save_as(self):
"""Save database to file under different filename."""
path = Dialogs.ChooseDBFilename().run()
if path:
ret, err = self.model.save(path)
if ret:
self.model.config.add_recent(path)
self.__set_title(filepath=path)
else:
Dialogs.Err("Error writing file - pyGTKtalog","Cannot write \
file %s." % path, "%s" % err)
def __add_cd(self, label=None, current_id=None):
"""Add directory structure from cd/dvd disc"""
mount = deviceHelper.volmount(self.model.config.confd['cd'])
if mount == 'ok':
guessed_label = deviceHelper.volname(self.model.config.confd['cd'])
if not label:
label = Dialogs.InputDiskLabel(guessed_label).run()
if label != None:
self.scan_cd = True
for widget in self.widgets_all:
self.view[widget].set_sensitive(False)
self.model.source = self.model.CD
self.model.scan(self.model.config.confd['cd'], label,
current_id)
self.model.unsaved_project = True
self.__set_title(filepath=self.model.filename, modified=True)
else:
deviceHelper.volumount(self.model.config.confd['cd'])
return True
else:
Dialogs.Wrn("Error mounting device - pyGTKtalog",
"Cannot mount device pointed to %s" %
self.model.config.confd['cd'],
"Last mount message:\n%s" % mount)
return False
def __add_directory(self, path=None, label=None, current_id=None):
if not label or not path:
res = Dialogs.PointDirectoryToAdd().run()
@@ -868,30 +954,13 @@ class MainController(Controller):
self.__set_title(filepath=self.model.filename, modified=True)
return True
def __do_quit(self):
"""Quit and save window parameters to config file"""
# check if any unsaved project is on go.
if self.model.unsaved_project and \
self.model.config.confd['confirmquit']:
if not Dialogs.Qst('Quit application - pyGTKtalog',
'Do you really want to quit?',
"Current database is not saved, any changes will be lost.").run():
return
self.__store_settings()
self.model.cleanup()
gtk.main_quit()
return False
def __new_db(self):
self.__tag_cloud()
"""Create new database file"""
if self.model.unsaved_project:
if not Dialogs.Qst('Unsaved data - pyGTKtalog',
"Current database isn't saved",
'All changes will be lost. Do you really want to abandon it?').run():
"All changes will be lost. Do you really \
want to abandon it?").run():
return
self.model.new()
@@ -931,9 +1000,10 @@ class MainController(Controller):
def __setup_files_treeview(self):
"""Setup TreeView files widget, as columned list."""
self.view['files'].set_model(self.model.files_list)
v = self.view['files']
v.set_model(self.model.files_list)
self.view['files'].get_selection().set_mode(gtk.SELECTION_MULTIPLE)
v.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
c = gtk.TreeViewColumn('Filename')
cellpb = gtk.CellRendererPixbuf()
@@ -956,6 +1026,12 @@ class MainController(Controller):
c.set_sort_column_id(3)
c.set_resizable(True)
self.view['files'].append_column(c)
#v.enable_model_drag_source(gtk.gdk.BUTTON1_MASK,
# self.DND_TARGETS,
# gtk.gdk.ACTION_DEFAULT)
v.drag_source_set(gtk.gdk.BUTTON1_MASK, self.DND_TARGETS,
gtk.gdk.ACTION_COPY)
return
def __setup_exif_treeview(self):
@@ -1040,7 +1116,7 @@ class MainController(Controller):
set = self.model.get_file_info(item)
buf = gtk.TextBuffer()
if __debug__ and set.has_key('debug'):
if __debug__ and 'debug' in set:
tag = buf.create_tag()
tag.set_property('weight', pango.WEIGHT_BOLD)
buf.insert_with_tags(buf.get_end_iter(), "ID: ", tag)
@@ -1054,7 +1130,7 @@ class MainController(Controller):
buf.insert_with_tags(buf.get_end_iter(), "Type: ", tag)
buf.insert(buf.get_end_iter(), str(set['debug']['type']) + "\n\n")
if set.has_key('gthumb'):
if 'gthumb' in set:
tag = buf.create_tag()
tag.set_property('weight', pango.WEIGHT_BOLD)
buf.insert_with_tags(buf.get_end_iter(), "gThumb comment:\n", tag)
@@ -1066,14 +1142,14 @@ class MainController(Controller):
buf.insert(buf.get_end_iter(), set['gthumb']['date'] + "\n")
buf.insert(buf.get_end_iter(), "\n")
if set.has_key('description'):
if 'description' in set:
tag = buf.create_tag()
tag.set_property('weight', pango.WEIGHT_BOLD)
buf.insert_with_tags(buf.get_end_iter(), "Details:\n", tag)
buf.insert(buf.get_end_iter(), set['description'])
buf.insert(buf.get_end_iter(), "\n")
if set.has_key('note'):
if 'note' in set:
tag = buf.create_tag()
tag.set_property('weight', pango.WEIGHT_BOLD)
buf.insert_with_tags(buf.get_end_iter(), "Note:\n", tag)
@@ -1081,42 +1157,43 @@ class MainController(Controller):
self.view['description'].set_buffer(buf)
if set.has_key('images'):
if 'images' in set:
self.__setup_iconview()
self.view['img_container'].show()
else:
self.view['img_container'].hide()
if set.has_key('exif'):
if 'exif' in set:
self.view['exif_tree'].set_model(self.model.exif_list)
self.view['exifinfo'].show()
else:
self.view['exifinfo'].hide()
if set.has_key('thumbnail'):
if 'thumbnail' in set:
self.view['thumb'].set_from_file(set['thumbnail'])
self.view['thumb_box'].show()
#self.view['thumb'].show()
else:
#self.view['thumb'].hide()
self.view['thumb_box'].hide()
return
'''
def on_tag_cloud_textview_drag_motion(self, widget, context, x, y, time):
context.drag_status(gtk.gdk.ACTION_COPY, time)
print "motion", x, y
'''
def __tag_cloud(self):
"""generate tag cloud"""
# TODO: checkit!
v = self.view['tag_cloud_textview']
def tag_cloud_click(tag, textview, event, iter, e):
"""react on click on connected tag items"""
if event.type == gtk.gdk.BUTTON_RELEASE:
print tag.get_property('name')
elif event.type == gtk.gdk.MOTION_NOTIFY:
w = \
self.view['tag_cloud_textview'].get_window(gtk.TEXT_WINDOW_TEXT)
w = v.get_window(gtk.TEXT_WINDOW_TEXT)
if w:
w.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
else:
w = \
self.view['tag_cloud_textview'].get_window(gtk.TEXT_WINDOW_TEXT)
w = v.get_window(gtk.TEXT_WINDOW_TEXT)
if w:
w.set_cursor(None)
@@ -1129,18 +1206,22 @@ class MainController(Controller):
return iter
if len(self.model.tag_cloud) > 0:
buff = gtk.TextBuffer()
buff = v.get_buffer()
buff.set_text('')
for cloud in self.model.tag_cloud:
iter = insert_blank(buff, buff.get_end_iter())
tag = buff.create_tag(cloud['id'])
tag = buff.create_tag(str(cloud['id']))
tag.set_property('size-points', cloud['size'])
tag.set_property('foreground', cloud['color'])
tag.connect('event', tag_cloud_click, tag)
buff.insert_with_tags(iter, cloud['name'], tag)
self.view['tag_cloud_textview'].set_buffer(buff)
v.set_buffer(buff)
def __show_stats(self, selected_id=None):
data = self.model.get_stats(selected_id)
label = Dialogs.StatsDialog(data).run()
def __find_tag_in_textview(self, widget, x, y):
pass
pass # end of class

View File

@@ -24,11 +24,10 @@
import os
import sys
import base64
import shutil
import tarfile
import tempfile
import string
import math
import gtk
import gobject
@@ -38,10 +37,7 @@ from gtkmvc.model_mt import ModelMT
from pysqlite2 import dbapi2 as sqlite
from datetime import datetime
try:
import threading as _threading
except ImportError:
import dummy_threading as _threading
import threading as _threading
from m_config import ConfigModel
try:
@@ -120,33 +116,91 @@ class MainModel(ModelMT):
# - #rgb
# - #rrggbb
self.tag_cloud = []
'''{'id': str(1), 'name': "bezpieczeństwo", 'size': 10, 'color': '#666'},
{'id': str(2), 'name': "bsd", 'size': 14, 'color': '#333'},
{'id': str(3), 'name': "debian", 'size': 18, 'color': '#333'},
{'id': str(4), 'name': "fedora", 'size': 12, 'color': '#666'},
{'id': str(5), 'name': "firefox", 'size': 40, 'color': '#666'},
{'id': str(6), 'name': "gnome", 'size': 26, 'color': '#333'},
{'id': str(7), 'name': "gentoo", 'size': 30, 'color': '#000'},
{'id': str(8), 'name': "kde", 'size': 20, 'color': '#333'},
{'id': str(9), 'name': "kernel", 'size': 10, 'color': '#666'},
{'id': str(10), 'name': "windows", 'size': 18, 'color': '#333'},
]'''
return
def add_tags(self, id, tags):
for tag in tags.split(','):
tag = tag.strip()
# first, checkerap if we already have tag in tags table
sql = """SELECT id FROM tags WHERE tag = ?"""
self.db_cursor.execute(sql, (tag, ))
res = self.db_cursor.fetchone()
if not res:
# insert new tag
sql = """INSERT INTO tags(tag, group_id)
VALUES(?, ?)"""
self.db_cursor.execute(sql, (tag, 1))
self.db_connection.commit()
sql = """SELECT id FROM tags WHERE tag = ?"""
self.db_cursor.execute(sql, (tag, ))
res = self.db_cursor.fetchone()
tag_id = res[0]
# then checkout if file have already tag assigned
sql = """SELECT file_id FROM tags_files
WHERE file_id = ? AND tag_id = ?"""
self.db_cursor.execute(sql, (id, tag_id))
res = self.db_cursor.fetchone()
if not res:
sql = """INSERT INTO tags_files(file_id, tag_id)
VALUES(?, ?)"""
self.db_cursor.execute(sql, (id, tag_id))
self.db_connection.commit()
self.get_tags()
return
def get_tags(self):
sql = """SELECT COUNT(f.file_id), t.id, t.tag FROM tags_files f
LEFT JOIN tags t ON f.tag_id = t.id
GROUP BY f.tag_id
ORDER BY t.tag"""
self.db_cursor.execute(sql)
res = self.db_cursor.fetchall()
if len(res) > 0:
self.tag_cloud = []
for row in res:
self.tag_cloud.append({'id': row[1],
'name': row[2],
'size': row[0],
'color':'black'})
def tag_weight(x):
"""Calculate 'weight' of tag.
Tags can have sizes between 9 to ~40. Upper size is calculated with
logarythm and can take in extereme situation around value 55 like
for 1 milion tags."""
if x==None or x==0:
x = 1
return 4 * math.log(x, math.e)
# correct font sizes with tag_weight function.
count = 0
for ta in self.tag_cloud:
tmp = int(tag_weight(ta['size']))
if tmp == 0:
tmp = 1
self.tag_cloud[count]['size'] = tmp + 8
count+=1
def add_image(self, image, id, only_thumbs=False):
"""add single image to file/directory"""
sql = """insert into images(file_id, thumbnail, filename)
values(?, null, null)"""
sql = """INSERT INTO images(file_id, thumbnail, filename)
VALUES(?, null, null)"""
self.db_cursor.execute(sql, (id,))
self.db_connection.commit()
sql = """select id from images where thumbnail is null and filename is null and file_id=?"""
sql = """SELECT id FROM images WHERE thumbnail is null
AND filename IS null AND file_id=?"""
self.db_cursor.execute(sql, (id,))
res = self.db_cursor.fetchone()
if res:
tp, ip, rc = Img(image, self.internal_dirname).save(res[0])
if rc != -1:
sql = """update images set filename=?, thumbnail=? where id=?"""
sql = """UPDATE images SET filename=?,
thumbnail=? WHERE id=?"""
if only_thumbs:
img = None
else:
@@ -160,7 +214,7 @@ class MainModel(ModelMT):
def del_images(self, id):
"""removes images and their thumbnails from selected file/dir"""
# remove images
sql = """select filename, thumbnail from images where file_id =?"""
sql = """SELECT filename, thumbnail FROM images WHERE file_id =?"""
self.db_cursor.execute(sql, (id,))
res = self.db_cursor.fetchall()
if len(res) > 0:
@@ -170,13 +224,13 @@ class MainModel(ModelMT):
os.unlink(os.path.join(self.internal_dirname, fn[1]))
# remove images records
sql = """delete from images where file_id = ?"""
sql = """DELETE FROM images WHERE file_id = ?"""
self.db_cursor.execute(sql, (id,))
self.db_connection.commit()
def delete_image(self, id):
"""removes image on specified image id"""
sql = """select filename, thumbnail from images where id=?"""
sql = """SELECT filename, thumbnail FROM images WHERE id=?"""
self.db_cursor.execute(sql, (id,))
res = self.db_cursor.fetchone()
if res:
@@ -189,7 +243,7 @@ class MainModel(ModelMT):
print res[0]
print res[1]
# remove images records
sql = """delete from images where id = ?"""
sql = """DELETE FROM images WHERE id = ?"""
self.db_cursor.execute(sql, (id,))
self.db_connection.commit()
@@ -200,7 +254,8 @@ class MainModel(ModelMT):
p, e, ret_code = Thumbnail(img_fn,
base=self.internal_dirname).save(id)
if ret_code != -1:
sql = """insert into thumbnails(file_id, filename) values (?, ?)"""
sql = """insert into thumbnails(file_id, filename)
values (?, ?)"""
self.db_cursor.execute(sql,
(id,
p.split(self.internal_dirname)[1][1:]))
@@ -212,14 +267,14 @@ class MainModel(ModelMT):
"""removes thumbnail from selected file/dir"""
# remove thumbnail files
sql = """select filename from thumbnails where file_id=?"""
sql = """SELECT filename FROM thumbnails WHERE file_id=?"""
self.db_cursor.execute(sql, (id,))
res = self.db_cursor.fetchone()
if res:
os.unlink(os.path.join(self.internal_dirname, res[0]))
# remove thumbs records
sql = """delete from thumbnails where file_id=?"""
sql = """DELETE FROM thumbnails WHERE file_id=?"""
self.db_cursor.execute(sql, (id,))
self.db_connection.commit()
@@ -276,7 +331,8 @@ class MainModel(ModelMT):
try:
tar.extractall()
if __debug__:
print "m_main.py: extracted tarfile into", self.internal_dirname
print "m_main.py: extracted tarfile into",
print self.internal_dirname
except AttributeError:
# python's 2.4 tarfile module lacks of method extractall()
directories = []
@@ -305,14 +361,15 @@ class MainModel(ModelMT):
os.chmod(tarinfo, '.')
except:
if __debug__:
print "m_main.py: open(): setting corrext owner, mtime etc"
print "m_main.py: open(): setting corrext owner,",
print "mtime etc"
pass
tar.close()
self.__connect_to_db()
self.__fetch_db_into_treestore()
self.config.add_recent(filename)
self.get_tags()
return True
def scan(self, path, label, currentid):
@@ -334,7 +391,7 @@ class MainModel(ModelMT):
def rename(self, id, new_name=None):
if new_name:
self.db_cursor.execute("update files set filename=? \
where id=?", (new_name, id))
WHERE id=?", (new_name, id))
self.db_connection.commit()
self.__fetch_db_into_treestore()
self.unsaved_project = True
@@ -354,9 +411,10 @@ class MainModel(ModelMT):
pass
# directories first
self.db_cursor.execute("SELECT id, filename, size, date FROM files \
WHERE parent_id=? AND type=1 \
ORDER BY filename", (id,))
sql = """SELECT id, filename, size, date FROM files
WHERE parent_id=? AND type=1
ORDER BY filename"""
self.db_cursor.execute(sql, (id,))
data = self.db_cursor.fetchall()
for ch in data:
myiter = self.files_list.insert_before(None, None)
@@ -370,10 +428,11 @@ class MainModel(ModelMT):
self.files_list.set_value(myiter, 6, gtk.STOCK_DIRECTORY)
# all the rest
self.db_cursor.execute("SELECT f.id, f.filename, f.size, f.date, \
f.type FROM files f \
WHERE f.parent_id=? AND f.type!=1 \
ORDER BY f.filename", (id,))
sql = """SELECT f.id, f.filename, f.size, f.date, f.type
FROM files f
WHERE f.parent_id=? AND f.type!=1
ORDER BY f.filename"""
self.db_cursor.execute(sql, (id,))
data = self.db_cursor.fetchall()
for ch in data:
myiter = self.files_list.insert_before(None, None)
@@ -391,7 +450,8 @@ class MainModel(ModelMT):
def get_parent_discs_value(self, child_id):
if child_id:
self.db_cursor.execute("SELECT parent_id FROM files where id=?", (child_id,))
sql = """SELECT parent_id FROM files WHERE id=?"""
self.db_cursor.execute(sql, (child_id,))
set = self.db_cursor.fetchone()
if set:
return set[0]
@@ -421,9 +481,11 @@ class MainModel(ModelMT):
retval['note'] = set[6]
if set[4]:
retval['thumbnail'] = os.path.join(self.internal_dirname, set[4])
pa = os.path.join(self.internal_dirname, set[4])
retval['thumbnail'] = pa
sql = """SELECT id, filename, thumbnail from images WHERE file_id = ?"""
sql = """SELECT id, filename, thumbnail FROM images
WHERE file_id = ?"""
self.db_cursor.execute(sql, (id,))
set = self.db_cursor.fetchall()
if set:
@@ -437,7 +499,7 @@ class MainModel(ModelMT):
sql = """SELECT camera, date, aperture, exposure_program,
exposure_bias, iso, focal_length, subject_distance, metering_mode,
flash, light_source, resolution, orientation
from exif
FROM exif
WHERE file_id = ?"""
self.db_cursor.execute(sql, (id,))
set = self.db_cursor.fetchone()
@@ -452,20 +514,22 @@ class MainModel(ModelMT):
retval['exif'] = True
# gthumb
sql = """SELECT note, place, date from gthumb WHERE file_id = ?"""
sql = """SELECT note, place, date FROM gthumb WHERE file_id = ?"""
self.db_cursor.execute(sql, (id,))
set = self.db_cursor.fetchone()
if set:
retval['gthumb'] = {'note': set[0], 'place': set[1], 'date': set[2]}
retval['gthumb'] = {'note': set[0],
'place': set[1],
'date': set[2]}
return retval
def get_source(self, path):
"""get source of top level directory"""
bid = self.discs_tree.get_value(self.discs_tree.get_iter(path[0]),
0)
self.db_cursor.execute("select source from files where id = ?",
bid = self.discs_tree.get_value(self.discs_tree.get_iter(path[0]), 0)
sql = """SELECT source FROM files WHERE id = ?"""
self.db_cursor.execute(sql,
(bid,))
res = self.db_cursor.fetchone()
if res == None:
@@ -474,10 +538,10 @@ class MainModel(ModelMT):
def get_label_and_filepath(self, path):
"""get source of top level directory"""
bid = self.discs_tree.get_value(self.discs_tree.get_iter(path),
0)
self.db_cursor.execute("select filepath, filename from files \
where id = ? and parent_id = 1", (bid,))
bid = self.discs_tree.get_value(self.discs_tree.get_iter(path), 0)
sql = """SELECT filepath, filename FROM files
WHERE id = ? AND parent_id = 1"""
self.db_cursor.execute(sql, (bid,))
res = self.db_cursor.fetchone()
if res == None:
return None, None
@@ -496,14 +560,14 @@ class MainModel(ModelMT):
if not db_connection:
db_connection = self.db_connection
sql = """select parent_id from files where id = ?"""
sql = """SELECT parent_id FROM files WHERE id = ?"""
db_cursor.execute(sql, (root_id,))
res = db_cursor.fetchone()
parent_id = res[0]
def get_children(fid):
fids.append(fid)
sql = """select id from files where parent_id = ?"""
sql = """SELECT id FROM files where parent_id = ?"""
db_cursor.execute(sql, (fid,))
res = db_cursor.fetchall()
if len(res)>0:
@@ -517,17 +581,17 @@ class MainModel(ModelMT):
yield (c,)
# remove files records
sql = """delete from files where id = ?"""
sql = """DELETE FROM files WHERE id = ?"""
db_cursor.executemany(sql, generator())
# remove tags records
sql = """delete from tags_files where file_id = ?"""
sql = """DELETE FROM tags_files WHERE file_id = ?"""
db_cursor.executemany(sql, generator())
arg = self.__list_to_string(fids)
arg = str(tuple(fids))
# remove thumbnails
sql = """select filename from thumbnails where file_id in (%s)""" % arg
sql = """SELECT filename FROM thumbnails WHERE file_id IN %s""" % arg
db_cursor.execute(sql)
res = db_cursor.fetchall()
if len(res) > 0:
@@ -535,7 +599,8 @@ class MainModel(ModelMT):
os.unlink(os.path.join(self.internal_dirname, fn[0]))
# remove images
sql = """select filename, thumbnail from images where file_id in (%s)""" % arg
sql = """SELECT filename, thumbnail FROM images
WHERE file_id IN %s""" % arg
db_cursor.execute(sql)
res = db_cursor.fetchall()
if len(res) > 0:
@@ -545,32 +610,34 @@ class MainModel(ModelMT):
os.unlink(os.path.join(self.internal_dirname, fn[1]))
# remove thumbs records
sql = """delete from thumbnails where file_id = ?"""
sql = """DELETE FROM thumbnails WHERE file_id = ?"""
db_cursor.executemany(sql, generator())
# remove images records
sql = """delete from images where file_id = ?"""
sql = """DELETE FROM images WHERE file_id = ?"""
db_cursor.executemany(sql, generator())
# remove gthumb info
sql = """delete from gthumb where file_id = ?"""
sql = """DELETE FROM gthumb WHERE file_id = ?"""
db_cursor.executemany(sql, generator())
# correct parent direcotry sizes
# get size and parent of deleting object
while parent_id:
sql = """update files set size =
(select case when
sum(size) is null
then
sql = """UPDATE files SET size =
(SELECT CASE WHEN
SUM(size) IS null
THEN
0
else
sum(size)
end
from files where parent_id=?) where id=?"""
ELSE
SUM(size)
END
FROM files WHERE parent_id=?)
WHERE id=?"""
db_cursor.execute(sql, (parent_id, parent_id))
sql = """select parent_id from files where id = ? and parent_id!=id"""
sql = """SELECT parent_id FROM files
WHERE id = ? AND parent_id!=id"""
db_cursor.execute(sql, (parent_id,))
res = db_cursor.fetchone()
if res:
@@ -585,7 +652,7 @@ class MainModel(ModelMT):
"""get statistic information"""
retval = {}
if selected_id:
sql = """select id, type, parent_id from files where id=?"""
sql = """SELECT id, type, parent_id FROM files WHERE id=?"""
self.db_cursor.execute(sql, (selected_id,))
res = self.db_cursor.fetchone()
if not res:
@@ -595,9 +662,11 @@ class MainModel(ModelMT):
# collect all parent_id's
parents = []
def _recurse(fid):
parents.append(fid)
sql = """select id from files where type=? and parent_id=? and parent_id!=1"""
sql = """SELECT id FROM files
WHERE type=? AND parent_id=? AND parent_id!=1"""
self.db_cursor.execute(sql, (self.DIR, fid))
res = self.db_cursor.fetchall()
if res:
@@ -615,37 +684,42 @@ class MainModel(ModelMT):
files_count = 0
for p in parents:
sql = """select count(id) from files where type!=0 and type!=1 and parent_id=?"""
sql = """SELECT count(id) FROM files
WHERE type!=0 AND type!=1 AND parent_id=?"""
self.db_cursor.execute(sql, (p,))
res = self.db_cursor.fetchone()
if res:
files_count+=res[0]
retval['files'] = files_count
sql = """select size from files where id=?"""
sql = """SELECT size FROM files WHERE id=?"""
self.db_cursor.execute(sql, (selected_id,))
res = self.db_cursor.fetchone()
if res:
retval['size'] = self.__bytes_to_human(res[0])
else:
sql = """select count(id) from files where parent_id=1 and type=1"""
sql = """SELECT count(id) FROM files
WHERE parent_id=1 AND type=1"""
self.db_cursor.execute(sql)
res = self.db_cursor.fetchone()
if res:
retval['discs'] = res[0]
sql = """select count(id) from files where parent_id!=1 and type=1"""
sql = """SELECT count(id) FROM files
WHERE parent_id!=1 AND type=1"""
self.db_cursor.execute(sql)
res = self.db_cursor.fetchone()
if res:
retval['dirs'] = res[0]
sql = """select count(id) from files where parent_id!=1 and type!=1"""
sql = """SELECT count(id) FROM files
WHERE parent_id!=1 AND type!=1"""
self.db_cursor.execute(sql)
res = self.db_cursor.fetchone()
if res:
retval['files'] = res[0]
sql = """select sum(size) from files where parent_id=1 and type=1"""
sql = """SELECT sum(size) FROM files
WHERE parent_id=1 AND type=1"""
self.db_cursor.execute(sql)
res = self.db_cursor.fetchone()
if res:
@@ -654,7 +728,7 @@ class MainModel(ModelMT):
def get_image_path(self, img_id):
"""return image location"""
sql = """select filename from images where id=?"""
sql = """SELECT filename FROM images WHERE id=?"""
self.db_cursor.execute(sql, (img_id,))
res = self.db_cursor.fetchone()
if res:
@@ -721,7 +795,8 @@ class MainModel(ModelMT):
def __create_internal_dirname(self):
self.cleanup()
self.internal_dirname = "/tmp/pygtktalog%d" % datetime.now().microsecond
self.internal_dirname = "/tmp/pygtktalog%d" % \
datetime.now().microsecond
try:
os.mkdir(self.internal_dirname)
except IOError, (errno, strerror):
@@ -802,8 +877,11 @@ class MainModel(ModelMT):
note TEXT,
place TEXT,
date datetime);""")
self.db_cursor.execute("insert into files values(1, 1, 'root', null, 0, 0, 0, 0, null, null);")
self.db_cursor.execute("insert into groups values(1, 'default', 'black');")
sql = """INSERT INTO files
VALUES(1, 1, 'root', null, 0, 0, 0, 0, null, null)"""
self.db_cursor.execute(sql)
sql = """INSERT INSERT groups VALUES(1, 'default', 'black')"""
self.db_cursor.execute(sql)
self.db_connection.commit()
def __scan(self):
@@ -857,22 +935,21 @@ class MainModel(ModelMT):
if parent_id == 1:
self.fresh_disk_iter = myit
self.discs_tree.set_value(myit,2,gtk.STOCK_CDROM)
sql = """insert into
files(parent_id, filename, filepath, date, size, type, source)
values(?,?,?,?,?,?,?)"""
sql = """INSERT INTO
files(parent_id, filename, filepath, date,
size, type, source)
VALUES(?,?,?,?,?,?,?)"""
db_cursor.execute(sql, (parent_id, name, path, date, size,
filetype, self.source))
else:
self.discs_tree.set_value(myit,2,gtk.STOCK_DIRECTORY)
sql = """
insert into
sql = """INSERT INTO
files(parent_id, filename, filepath, date, size, type)
values(?,?,?,?,?,?)
"""
db_cursor.execute(sql,
(parent_id, name, path, date, size, filetype))
VALUES(?,?,?,?,?,?)"""
db_cursor.execute(sql, (parent_id, name, path,
date, size, filetype))
sql = """select seq FROM sqlite_sequence WHERE name='files'"""
sql = """SELECT seq FROM sqlite_sequence WHERE name='files'"""
db_cursor.execute(sql)
currentid=db_cursor.fetchone()[0]
@@ -904,12 +981,11 @@ class MainModel(ModelMT):
if os.path.islink(current_dir):
l = self.__decode_filename(os.readlink(current_dir))
sql = """
insert into files(parent_id, filename, filepath, date, size, type)
values(?,?,?,?,?,?)
"""
sql = """INSERT INTO
files(parent_id, filename, filepath, date, size, type)
VALUES(?,?,?,?,?,?)"""
db_cursor.execute(sql, (currentid, j + " -> " + l,
ocurrent_dir, st_mtime, 0,
current_dir, st_mtime, 0,
self.LIN))
dirsize = 0
else:
@@ -944,17 +1020,16 @@ class MainModel(ModelMT):
# do NOT follow symbolic links
if os.path.islink(current_file):
l = self.__decode_filename(os.readlink(current_file))
sql = """insert into files(parent_id, filename, filepath,
date, size, type)
values(?,?,?,?,?,?)"""
sql = """INSERT INTO
files(parent_id, filename, filepath, date, size, type)
VALUES(?,?,?,?,?,?)"""
db_cursor.execute(sql, (currentid, j + " -> " + l,
current_file, st_mtime, 0,
self.LIN))
else:
sql = """
insert into files(parent_id, filename, filepath, date, size, type)
values(?,?,?,?,?,?)
"""
sql = """INSERT INTO
files(parent_id, filename, filepath, date, size, type)
VALUES(?,?,?,?,?,?)"""
db_cursor.execute(sql, (currentid, j, current_file,
st_mtime, st_size, self.FIL))
@@ -969,7 +1044,8 @@ class MainModel(ModelMT):
update = True
exif = None
sql = """select seq FROM sqlite_sequence WHERE name='files'"""
sql = """SELECT seq FROM sqlite_sequence
WHERE name='files'"""
db_cursor.execute(sql)
fileid = db_cursor.fetchone()[0]
@@ -977,14 +1053,19 @@ class MainModel(ModelMT):
# Images - thumbnails and exif data
if self.config.confd['thumbs'] and ext in self.IMG:
tpath, exif, ret_code = Thumbnail(current_file, base=self.internal_dirname).save(fileid)
t = Thumbnail(current_file,
base=self.internal_dirname)
tpath, exif, ret_code = t.save(fileid)
if ret_code != -1:
sql = """insert into thumbnails(file_id, filename) values (?, ?)"""
db_cursor.execute(sql, (fileid,
tpath.split(self.internal_dirname)[1][1:]))
sql = """INSERT INTO
thumbnails(file_id, filename)
VALUES(?, ?)"""
t = tpath.split(self.internal_dirname)[1][1:]
db_cursor.execute(sql, (fileid, t))
# exif - stroe data in exif table
if self.config.confd['exif'] and ext in ['jpg', 'jpeg']:
# exif - store data in exif table
jpg = ['jpg', 'jpeg']
if self.config.confd['exif'] and ext in jpg:
p = None
if self.config.confd['thumbs'] and exif:
p = ParseExif(exif_dict=exif)
@@ -1026,13 +1107,11 @@ class MainModel(ModelMT):
db_cursor.execute(sql, (fileid,
cmnts['note'],
cmnts['place'],
cmnts['date']
))
if cmnts.has_key('keywords'):
# TODO: add gthumb keywords to tags and group 'gthumb'
cmnts['date']))
if 'keywords' in cmnts:
# TODO: add gthumb keywords to tags
pass
# Extensions - user defined actions
if ext in self.config.confd['extensions'].keys():
cmd = self.config.confd['extensions'][ext]
@@ -1041,19 +1120,17 @@ class MainModel(ModelMT):
desc = ''
for line in output:
desc += line
#desc = string.replace(desc, "\n", "\\n")
sql = """update files set description=? where id=?"""
sql = """UPDATE files SET description=?
WHERE id=?"""
db_cursor.execute(sql, (desc, fileid))
#if i.split('.').[-1].lower() in mov_ext:
# # video only
# info = filetypeHelper.guess_video(os.path.join(root,i))
### end of scan
if update:
self.statusmsg = "Scannig: %s" % current_file
self.progress = step * self.count
sql = """update files set size=? where id=?"""
sql = """UPDATE files SET size=? WHERE id=?"""
db_cursor.execute(sql,(_size, currentid))
if self.abort:
return -1
@@ -1098,23 +1175,20 @@ class MainModel(ModelMT):
self.__clear_discs_tree()
#connect
detect_types = sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES
db_connection = sqlite.connect("%s" % \
(self.internal_dirname + '/db.sqlite'),
detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)
detect_types = detect_types)
db_cursor = db_connection.cursor()
# fetch all the directories
sql = """
SELECT id, parent_id, filename FROM files
WHERE type=1 ORDER BY parent_id, filename
"""
sql = """SELECT id, parent_id, filename FROM files
WHERE type=1 ORDER BY parent_id, filename"""
db_cursor.execute(sql)
data = db_cursor.fetchall()
try:
sql = """
SELECT id, parent_id, filename FROM files
WHERE type=1 ORDER BY parent_id, filename
"""
sql = """SELECT id, parent_id, filename FROM files
WHERE type=1 ORDER BY parent_id, filename"""
db_cursor.execute(sql)
data = db_cursor.fetchall()
except:
@@ -1148,19 +1222,22 @@ class MainModel(ModelMT):
# launch scanning.
get_children()
if __debug__:
print "m_main.py: __fetch_db_into_treestore() tree generation time: ", (datetime.now() - start_date)
print "m_main.py: __fetch_db_into_treestore()",
print "tree generation time: ", (datetime.now() - start_date)
db_connection.close()
return
def __append_added_volume(self):
"""append branch from DB to existing tree model"""
#connect
detect_types = sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES
db_connection = sqlite.connect("%s" %
(self.internal_dirname + '/db.sqlite'),
detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)
detect_types = detect_types)
db_cursor = db_connection.cursor()
sql = """SELECT id, parent_id, filename FROM files WHERE type=1 ORDER BY parent_id, filename"""
sql = """SELECT id, parent_id, filename FROM files
WHERE type=1 ORDER BY parent_id, filename"""
db_cursor.execute(sql)
data = db_cursor.fetchall()
@@ -1187,7 +1264,8 @@ class MainModel(ModelMT):
# launch scanning.
get_children()
if __debug__:
print "m_main.py: __append_added_volume() tree generation time: ", (datetime.now() - start_date)
print "m_main.py: __append_added_volume() tree generation time: ",
print datetime.now() - start_date
db_connection.close()
return
@@ -1197,12 +1275,3 @@ class MainModel(ModelMT):
else:
return txt
def __list_to_string(self, array):
arg =''
for c in array:
if len(arg) > 0:
arg+=", %d" % c
else:
arg = "%d" % c
return arg
pass # end of class

View File

@@ -31,6 +31,7 @@ class MainView(View):
application. The widgets set is loaded from glade file"""
GLADE = os.path.join(utils.globals.GLADE_DIR, "main.glade")
def __init__(self, ctrl):
View.__init__(self, ctrl, self.GLADE)
@@ -38,6 +39,7 @@ class MainView(View):
self['separatormenuitem4'].hide()
self['list1'].hide()
self['thumbnails1'].hide()
#self['tag_cloud_textview'].drag_dest_set(0, [], 0)
return
pass # end of class