mirror of
https://github.com/gryf/pygtktalog.git
synced 2025-12-17 11:30:19 +01:00
* Finally, version 1.0.
This commit is contained in:
10
README
10
README
@@ -1,4 +1,4 @@
|
|||||||
pyGTKtalog 1.0 RC3
|
pyGTKtalog 1.0
|
||||||
==================
|
==================
|
||||||
|
|
||||||
pyGTKtalog is Linux/FreeBSD program for indexing CD/DVD or directories on
|
pyGTKtalog is Linux/FreeBSD program for indexing CD/DVD or directories on
|
||||||
@@ -107,6 +107,14 @@ Catalog file is tared and gziped sqlite database and directories with images and
|
|||||||
thumbnails. If there are more images, the size of catalog file will grow. So be
|
thumbnails. If there are more images, the size of catalog file will grow. So be
|
||||||
carefull with adding big images in your catalog file!
|
carefull with adding big images in your catalog file!
|
||||||
|
|
||||||
|
There is also converter form old database to new. In fact no image are stored in
|
||||||
|
archive with katalog. All thumnails will be lost. All images without big image
|
||||||
|
will be lost. There ar serious changes with application design, and I decided,
|
||||||
|
that is better to keep media unpacked on disk, instead of pack it every time
|
||||||
|
with save and unpack with open methods. New design prevent from deleting eny
|
||||||
|
file from media directory (placed in ~/.pygtktalog/images). Functionality for
|
||||||
|
exporting images and corresponding db file is planned.
|
||||||
|
|
||||||
BUGS
|
BUGS
|
||||||
====
|
====
|
||||||
|
|
||||||
|
|||||||
@@ -179,17 +179,6 @@
|
|||||||
<signal name="activate" handler="on_del_all_images_activate"/>
|
<signal name="activate" handler="on_del_all_images_activate"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<widget class="GtkMenuItem" id="del_all_images_thumb">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
|
||||||
<property name="tooltip" translatable="yes">Deletes all images from files in current colection.
|
|
||||||
Thumbnails from image tabs will be keep.</property>
|
|
||||||
<property name="label" translatable="yes">Delete all images without thumbnals</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<signal name="activate" handler="on_del_all_images_thumb_activate"/>
|
|
||||||
</widget>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenuItem" id="del_all_thumb">
|
<widget class="GtkMenuItem" id="del_all_thumb">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -199,6 +188,14 @@ Thumbnails from image tabs will be keep.</property>
|
|||||||
<signal name="activate" handler="on_del_all_thumb_activate"/>
|
<signal name="activate" handler="on_del_all_thumb_activate"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkMenuItem" id="save_all_img">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">Save all images...</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="on_save_all_img_activate"/>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkSeparatorMenuItem" id="separator12">
|
<widget class="GtkSeparatorMenuItem" id="separator12">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -1007,20 +1004,18 @@ thumbnail from first image will be generated.</property>
|
|||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenuItem" id="img_delete">
|
<widget class="GtkMenuItem" id="img_delete">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
|
||||||
<property name="label" translatable="yes">_Delete images</property>
|
<property name="label" translatable="yes">_Delete images</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<signal name="activate" handler="on_img_delete_activate"/>
|
<signal name="activate" handler="on_img_delete_activate"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenuItem" id="img_delete2">
|
<widget class="GtkMenuItem" id="img_thumbset">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
<property name="events">GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
<property name="tooltip" translatable="yes">Delete selected images, but leave thumbnails</property>
|
<property name="label" translatable="yes">Set as _thumbnail</property>
|
||||||
<property name="label" translatable="yes">De_lete images (keep thumbs)</property>
|
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<signal name="activate" handler="on_img_delete2_activate"/>
|
<signal name="activate" handler="on_img_thumbset_activate"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class MainController(Controller):
|
|||||||
widgets_all = ('tag_path_box', 'hpaned1',
|
widgets_all = ('tag_path_box', 'hpaned1',
|
||||||
'file1', 'edit1', 'view1', 'help1',
|
'file1', 'edit1', 'view1', 'help1',
|
||||||
'add_cd', 'add_directory1', 'del_all_images',
|
'add_cd', 'add_directory1', 'del_all_images',
|
||||||
'del_all_images_thumb', 'del_all_thumb', 'stat1',
|
'del_all_thumb', 'stat1',
|
||||||
'tb_new','tb_open', 'tb_save', 'tb_addcd', 'tb_adddir',
|
'tb_new','tb_open', 'tb_save', 'tb_addcd', 'tb_adddir',
|
||||||
'tb_find', 'tb_quit')
|
'tb_find', 'tb_quit')
|
||||||
widgets_cancel = ('cancel','cancel1')
|
widgets_cancel = ('cancel','cancel1')
|
||||||
@@ -120,7 +120,7 @@ class MainController(Controller):
|
|||||||
self.view['tag_cloud_textview'].connect("populate-popup",
|
self.view['tag_cloud_textview'].connect("populate-popup",
|
||||||
self.on_tag_cloud_textview_popup)
|
self.on_tag_cloud_textview_popup)
|
||||||
# in case model has opened file, register tags
|
# in case model has opened file, register tags
|
||||||
if self.model.internal_dirname:
|
if self.model.db_tmp_path:
|
||||||
self.__tag_cloud()
|
self.__tag_cloud()
|
||||||
else:
|
else:
|
||||||
self.model.new()
|
self.model.new()
|
||||||
@@ -345,7 +345,7 @@ class MainController(Controller):
|
|||||||
ImageView(img)
|
ImageView(img)
|
||||||
else:
|
else:
|
||||||
Dialogs.Inf("Image view", "No Image",
|
Dialogs.Inf("Image view", "No Image",
|
||||||
"This item have no real image, only thumbnail.")
|
"Image file does not exist.")
|
||||||
|
|
||||||
def on_rename1_activate(self, widget):
|
def on_rename1_activate(self, widget):
|
||||||
model, iter = self.view['discs'].get_selection().get_selected()
|
model, iter = self.view['discs'].get_selection().get_selected()
|
||||||
@@ -805,37 +805,23 @@ class MainController(Controller):
|
|||||||
description)
|
description)
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_img_delete2_activate(self, menu_item):
|
def on_img_thumbset_activate(self, menu_item):
|
||||||
"""remove images, but keep thumbnails"""
|
"""set selected image as thumbnail"""
|
||||||
list_of_paths = self.view['images'].get_selected_items()
|
list_of_paths = self.view['images'].get_selected_items()
|
||||||
|
|
||||||
if not list_of_paths:
|
if not list_of_paths:
|
||||||
Dialogs.Inf("Delete images", "No images selected",
|
Dialogs.Inf("Set thumbnail", "No image selected",
|
||||||
"You have to select at least one image to delete.")
|
"You have to select one image to set as thumbnail.")
|
||||||
return
|
return
|
||||||
|
if len(list_of_paths) >1:
|
||||||
if self.model.config.confd['delwarn']:
|
Dialogs.Inf("Set thumbnail", "To many images selected",
|
||||||
description = 'Selected images will be permanently removed from '
|
"You have to select one image to set as thumbnail.")
|
||||||
description += 'catalog,\nthumbnails will be keeped.'
|
|
||||||
obj = Dialogs.Qst('Delete images', 'Delete selected images?',
|
|
||||||
description)
|
|
||||||
if not obj.run():
|
|
||||||
return
|
return
|
||||||
|
|
||||||
model = self.view['images'].get_model()
|
model = self.view['images'].get_model()
|
||||||
for path in list_of_paths:
|
iter = model.get_iter(list_of_paths[0])
|
||||||
iter = model.get_iter(path)
|
|
||||||
id = model.get_value(iter, 0)
|
id = model.get_value(iter, 0)
|
||||||
self.model.delete_images_wth_thumbs(id)
|
self.model.set_image_as_thumbnail(id)
|
||||||
|
|
||||||
try:
|
|
||||||
path, column = self.view['files'].get_cursor()
|
|
||||||
model = self.view['files'].get_model()
|
|
||||||
iter = model.get_iter(path)
|
|
||||||
id = model.get_value(iter, 0)
|
|
||||||
self.__get_item_info(id)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.model.unsaved_project = True
|
self.model.unsaved_project = True
|
||||||
self.__set_title(filepath=self.model.filename, modified=True)
|
self.__set_title(filepath=self.model.filename, modified=True)
|
||||||
@@ -1263,31 +1249,6 @@ class MainController(Controller):
|
|||||||
pass
|
pass
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_del_all_images_thumb_activate(self, menu_item):
|
|
||||||
if self.model.config.confd['delwarn']:
|
|
||||||
title = 'Delete images'
|
|
||||||
question = 'Delete all images?'
|
|
||||||
dsc = "All images without thumbnails will be permanently removed"
|
|
||||||
dsc += " from catalog."
|
|
||||||
obj = Dialogs.Qst(title, question, dsc)
|
|
||||||
if not obj.run():
|
|
||||||
return
|
|
||||||
|
|
||||||
self.model.delete_all_images_wth_thumbs()
|
|
||||||
self.model.unsaved_project = True
|
|
||||||
self.__set_title(filepath=self.model.filename, modified=True)
|
|
||||||
|
|
||||||
try:
|
|
||||||
path, column = self.view['files'].get_cursor()
|
|
||||||
model = self.view['files'].get_model()
|
|
||||||
fiter = model.get_iter(path)
|
|
||||||
fid = model.get_value(fiter, 0)
|
|
||||||
if fid:
|
|
||||||
self.__get_item_info(fid)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return
|
|
||||||
|
|
||||||
def on_del_all_thumb_activate(self, menu_item):
|
def on_del_all_thumb_activate(self, menu_item):
|
||||||
if self.model.config.confd['delwarn']:
|
if self.model.config.confd['delwarn']:
|
||||||
title = 'Delete images'
|
title = 'Delete images'
|
||||||
|
|||||||
@@ -157,9 +157,11 @@ class ConfigModel(Model):
|
|||||||
dstring = ('cd','ejectapp','imgprog')
|
dstring = ('cd','ejectapp','imgprog')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
path = os.environ['HOME']
|
path = os.path.join(os.environ['HOME'], ".pygtktalog")
|
||||||
except:
|
except KeyError:
|
||||||
path = "/tmp"
|
raise KeyError, "Cannot stat path for current user home!"
|
||||||
|
|
||||||
|
path = os.path.join(path, "config.ini")
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Model.__init__(self)
|
Model.__init__(self)
|
||||||
@@ -179,12 +181,12 @@ class ConfigModel(Model):
|
|||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
try:
|
try:
|
||||||
os.lstat("%s/.pygtktalog" % self.path)
|
os.lstat(self.path)
|
||||||
except:
|
except:
|
||||||
print "Saving preferences to %s/.pygtktalog" % self.path
|
print "Saving preferences to %s." % self.path
|
||||||
if __debug__:
|
if __debug__:
|
||||||
print "m_config.py: save() Saving preferences to",
|
print "m_config.py: save() Saving preferences to",
|
||||||
print "%s/.pygtktalog" % self.path
|
print "%s" % self.path
|
||||||
newIni = Ini()
|
newIni = Ini()
|
||||||
|
|
||||||
# main section
|
# main section
|
||||||
@@ -224,12 +226,12 @@ class ConfigModel(Model):
|
|||||||
|
|
||||||
# write config
|
# write config
|
||||||
try:
|
try:
|
||||||
f = open("%s/.pygtktalog" % self.path,"w")
|
f = open(self.path, "w")
|
||||||
success = True
|
success = True
|
||||||
except:
|
except:
|
||||||
if __debug__:
|
if __debug__:
|
||||||
print "m_config.py: save() Cannot open config file",
|
print "m_config.py: save() Cannot open config file",
|
||||||
print "%s for writing." % (self.path, "/.pygtktalog")
|
print "%s for writing." % self.path
|
||||||
success = False
|
success = False
|
||||||
f.write(newIni.show())
|
f.write(newIni.show())
|
||||||
f.close()
|
f.close()
|
||||||
@@ -239,7 +241,7 @@ class ConfigModel(Model):
|
|||||||
try:
|
try:
|
||||||
# try to read config file
|
# try to read config file
|
||||||
parser = ConfigParser()
|
parser = ConfigParser()
|
||||||
parser.read("%s/.pygtktalog" % self.path)
|
parser.read(self.path)
|
||||||
r = {}
|
r = {}
|
||||||
h = {}
|
h = {}
|
||||||
self.recent = []
|
self.recent = []
|
||||||
|
|||||||
@@ -25,8 +25,9 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import shutil
|
import shutil
|
||||||
import tarfile
|
import bz2
|
||||||
import math
|
import math
|
||||||
|
from tempfile import mkstemp
|
||||||
|
|
||||||
import gtk
|
import gtk
|
||||||
import gobject
|
import gobject
|
||||||
@@ -47,6 +48,8 @@ except:
|
|||||||
from utils.parse_exif import ParseExif
|
from utils.parse_exif import ParseExif
|
||||||
from utils.gthumb import GthumbCommentParser
|
from utils.gthumb import GthumbCommentParser
|
||||||
|
|
||||||
|
from utils.no_thumb import no_thumb as no_thumb_img
|
||||||
|
|
||||||
class MainModel(ModelMT):
|
class MainModel(ModelMT):
|
||||||
"""Create, load, save, manipulate db file which is container for data"""
|
"""Create, load, save, manipulate db file which is container for data"""
|
||||||
|
|
||||||
@@ -91,6 +94,7 @@ class MainModel(ModelMT):
|
|||||||
self.unsaved_project = False
|
self.unsaved_project = False
|
||||||
self.filename = None # catalog saved/opened filename
|
self.filename = None # catalog saved/opened filename
|
||||||
self.internal_dirname = None
|
self.internal_dirname = None
|
||||||
|
self.image_path = None
|
||||||
self.db_connection = None
|
self.db_connection = None
|
||||||
self.db_cursor = None
|
self.db_cursor = None
|
||||||
self.abort = False
|
self.abort = False
|
||||||
@@ -105,6 +109,7 @@ class MainModel(ModelMT):
|
|||||||
self.statusmsg = "Idle"
|
self.statusmsg = "Idle"
|
||||||
self.selected_tags = {}
|
self.selected_tags = {}
|
||||||
self.search_created = False
|
self.search_created = False
|
||||||
|
self.db_tmp_path = False
|
||||||
|
|
||||||
# Directory tree: id, name, icon, type
|
# Directory tree: id, name, icon, type
|
||||||
self.discs_tree = gtk.TreeStore(gobject.TYPE_INT,
|
self.discs_tree = gtk.TreeStore(gobject.TYPE_INT,
|
||||||
@@ -150,6 +155,30 @@ class MainModel(ModelMT):
|
|||||||
# - #rgb
|
# - #rgb
|
||||||
# - #rrggbb
|
# - #rrggbb
|
||||||
self.tag_cloud = []
|
self.tag_cloud = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
path = os.path.join(os.environ['HOME'], ".pygtktalog")
|
||||||
|
imgpath = os.path.join(path, "images")
|
||||||
|
except KeyError:
|
||||||
|
raise KeyError, "Cannot stat path for current user home!"
|
||||||
|
|
||||||
|
if os.path.exists(path):
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
raise RuntimeError, "There is regular file \"%s\" on the way. Please remove it." % \
|
||||||
|
path
|
||||||
|
else:
|
||||||
|
os.mkdir(path)
|
||||||
|
|
||||||
|
|
||||||
|
if os.path.exists(imgpath):
|
||||||
|
if not os.path.isdir(imgpath):
|
||||||
|
print "Warning:",
|
||||||
|
"There is regular file \"%s\" on the way. Please remove it, otherwise images cannot be used" % imgpath
|
||||||
|
else:
|
||||||
|
os.mkdir(imgpath)
|
||||||
|
|
||||||
|
self.image_path = imgpath
|
||||||
|
|
||||||
self.new()
|
self.new()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -323,49 +352,57 @@ class MainModel(ModelMT):
|
|||||||
|
|
||||||
def add_image(self, image, file_id, only_thumbs=False):
|
def add_image(self, image, file_id, only_thumbs=False):
|
||||||
"""add single image to file/directory"""
|
"""add single image to file/directory"""
|
||||||
sql = """INSERT INTO images(file_id, thumbnail, filename)
|
imp = Img(image, self.image_path).save()
|
||||||
VALUES(?, null, null)"""
|
if imp:
|
||||||
|
# check if there is that image already
|
||||||
|
sql = """SELECT filename FROM images WHERE file_id=? and filename=?"""
|
||||||
|
self.db_cursor.execute(sql, (file_id, imp))
|
||||||
|
res = self.db_cursor.fetchone()
|
||||||
|
if res and res[0]:
|
||||||
|
# there is such an image. going back.
|
||||||
|
if __debug__:
|
||||||
|
print res[0]
|
||||||
|
return
|
||||||
|
|
||||||
|
# check if file have have thumbnail. if not, make it with first
|
||||||
|
# image
|
||||||
|
sql = """SELECT id FROM thumbnails WHERE file_id=?"""
|
||||||
self.db_cursor.execute(sql, (file_id,))
|
self.db_cursor.execute(sql, (file_id,))
|
||||||
|
res = self.db_cursor.fetchone()
|
||||||
|
thumb = 1
|
||||||
|
if not(res and res[0]):
|
||||||
|
sql = """INSERT INTO thumbnails(filename, file_id) VALUES(?, ?)"""
|
||||||
|
self.db_cursor.execute(sql, (imp, file_id))
|
||||||
|
|
||||||
|
# insert picture into db
|
||||||
|
sql = """INSERT INTO images(file_id, filename)
|
||||||
|
VALUES(?, ?)"""
|
||||||
|
self.db_cursor.execute(sql, (file_id, imp))
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
|
|
||||||
sql = """SELECT id FROM images WHERE thumbnail is null
|
## check if file have have thumbnail. if not, make it with image
|
||||||
AND filename IS null AND file_id=?"""
|
#sql = """SELECT id from thumbnails where file_id=?"""
|
||||||
self.db_cursor.execute(sql, (file_id,))
|
#self.db_cursor.execute(sql, (file_id,))
|
||||||
res = self.db_cursor.fetchone()
|
#res = self.db_cursor.fetchone()
|
||||||
if res:
|
#if not res:
|
||||||
thp, imp, rec = Img(image, self.internal_dirname).save(res[0])
|
# sql = """insert into thumbnails(file_id, filename)
|
||||||
if rec != -1:
|
# values (?, ?)"""
|
||||||
sql = """UPDATE images SET filename=?,
|
# self.db_cursor.execute(sql, (file_id, thp))
|
||||||
thumbnail=? WHERE id=?"""
|
# self.db_connection.commit()
|
||||||
if only_thumbs:
|
#
|
||||||
os.unlink(imp)
|
|
||||||
img = None
|
|
||||||
else:
|
|
||||||
img = imp.split(self.internal_dirname)[1][1:]
|
|
||||||
self.db_cursor.execute(sql,
|
|
||||||
(img,
|
|
||||||
thp.split(self.internal_dirname)[1][1:],
|
|
||||||
res[0]))
|
|
||||||
|
|
||||||
# check if file have have thumbnail. if not, make it with image
|
|
||||||
sql = """SELECT id from thumbnails where file_id=?"""
|
|
||||||
self.db_cursor.execute(sql, (file_id,))
|
|
||||||
res = self.db_cursor.fetchone()
|
|
||||||
if not res:
|
|
||||||
self.add_thumbnail(image, file_id)
|
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
|
|
||||||
def del_images(self, file_id):
|
def del_images(self, file_id):
|
||||||
"""removes images and their thumbnails from selected file/dir"""
|
"""removes images and their thumbnails from selected file/dir"""
|
||||||
# remove images
|
## 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, (file_id,))
|
#self.db_cursor.execute(sql, (file_id,))
|
||||||
res = self.db_cursor.fetchall()
|
#res = self.db_cursor.fetchall()
|
||||||
if len(res) > 0:
|
#if len(res) > 0:
|
||||||
for filen in res:
|
# for filen in res:
|
||||||
if filen[0]:
|
# if filen[0]:
|
||||||
os.unlink(os.path.join(self.internal_dirname, filen[0]))
|
# os.unlink(os.path.join(self.internal_dirname, filen[0]))
|
||||||
os.unlink(os.path.join(self.internal_dirname, filen[1]))
|
# os.unlink(os.path.join(self.internal_dirname, filen[1]))
|
||||||
|
|
||||||
# remove images records
|
# remove images records
|
||||||
sql = """DELETE FROM images WHERE file_id = ?"""
|
sql = """DELETE FROM images WHERE file_id = ?"""
|
||||||
@@ -380,109 +417,122 @@ class MainModel(ModelMT):
|
|||||||
self.db_cursor.execute(sql, (image_id,))
|
self.db_cursor.execute(sql, (image_id,))
|
||||||
res = self.db_cursor.fetchone()
|
res = self.db_cursor.fetchone()
|
||||||
if res and res[0]:
|
if res and res[0]:
|
||||||
source = os.path.join(self.internal_dirname, res[0])
|
source = os.path.join(self.image_path, res[0])
|
||||||
count = 1
|
count = 1
|
||||||
dest = os.path.join(file_path, res[1] + "_%d." % count + \
|
dest = os.path.join(file_path, res[1] + "_%04d." % count + 'jpg')
|
||||||
res[0].split('.')[-1])
|
|
||||||
|
|
||||||
while os.path.exists(dest):
|
while os.path.exists(dest):
|
||||||
count += 1
|
count += 1
|
||||||
dest = os.path.join(file_path, res[1] + "_%d." % count + \
|
dest = os.path.join(file_path, res[1] + "_%04d." %\
|
||||||
res[0].split('.')[-1])
|
count + 'jpg')
|
||||||
|
if not os.path.exists(source):
|
||||||
|
return False
|
||||||
shutil.copy(source, dest)
|
shutil.copy(source, dest)
|
||||||
return True
|
return True
|
||||||
#os.unlink()
|
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def delete_images_wth_thumbs(self, image_id):
|
def delete_images_wth_thumbs(self, image_id):
|
||||||
"""removes image (without thumbnail) on specified image id"""
|
"""removes image (without thumbnail) on specified image id"""
|
||||||
sql = """SELECT filename FROM images WHERE id=?"""
|
print "method removed"
|
||||||
self.db_cursor.execute(sql, (image_id,))
|
#sql = """SELECT filename FROM images WHERE id=?"""
|
||||||
res = self.db_cursor.fetchone()
|
#self.db_cursor.execute(sql, (image_id,))
|
||||||
if res:
|
#res = self.db_cursor.fetchone()
|
||||||
if res[0]:
|
#if res:
|
||||||
os.unlink(os.path.join(self.internal_dirname, res[0]))
|
# if res[0]:
|
||||||
|
# os.unlink(os.path.join(self.internal_dirname, res[0]))
|
||||||
|
#
|
||||||
|
# if __debug__:
|
||||||
|
# print "m_main.py: delete_image(): removed images:"
|
||||||
|
# print res[0]
|
||||||
|
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: delete_image(): removed images:"
|
|
||||||
print res[0]
|
|
||||||
# remove images records
|
# remove images records
|
||||||
sql = """UPDATE images set filename=NULL WHERE id = ?"""
|
#sql = """UPDATE images set filename=NULL WHERE id = ?"""
|
||||||
self.db_cursor.execute(sql, (image_id,))
|
#self.db_cursor.execute(sql, (image_id,))
|
||||||
self.db_connection.commit()
|
#self.db_connection.commit()
|
||||||
|
|
||||||
def delete_all_images_wth_thumbs(self):
|
def delete_all_images_wth_thumbs(self):
|
||||||
"""removes all images (without thumbnails) from collection"""
|
"""removes all images (without thumbnails) from collection"""
|
||||||
sql = """SELECT filename FROM images"""
|
print "method removed"
|
||||||
self.db_cursor.execute(sql)
|
#sql = """SELECT filename FROM images"""
|
||||||
res = self.db_cursor.fetchall()
|
#self.db_cursor.execute(sql)
|
||||||
for row in res:
|
#res = self.db_cursor.fetchall()
|
||||||
if row[0]:
|
#for row in res:
|
||||||
os.unlink(os.path.join(self.internal_dirname, row[0]))
|
# if row[0]:
|
||||||
if __debug__:
|
# os.unlink(os.path.join(self.internal_dirname, row[0]))
|
||||||
print "m_main.py: delete_all_images(): removed image:",
|
# if __debug__:
|
||||||
print row[0]
|
# print "m_main.py: delete_all_images(): removed image:",
|
||||||
|
# print row[0]
|
||||||
|
|
||||||
# remove images records
|
# remove images records
|
||||||
sql = """UPDATE images set filename=NULL"""
|
#sql = """UPDATE images set filename=NULL"""
|
||||||
self.db_cursor.execute(sql)
|
#self.db_cursor.execute(sql)
|
||||||
self.db_connection.commit()
|
#self.db_connection.commit()
|
||||||
|
|
||||||
def delete_image(self, image_id):
|
def delete_image(self, image_id):
|
||||||
"""removes image on specified image 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, (image_id,))
|
#self.db_cursor.execute(sql, (image_id,))
|
||||||
res = self.db_cursor.fetchone()
|
#res = self.db_cursor.fetchone()
|
||||||
if res:
|
#if res:
|
||||||
if res[0]:
|
# if res[0]:
|
||||||
os.unlink(os.path.join(self.internal_dirname, res[0]))
|
# os.unlink(os.path.join(self.internal_dirname, res[0]))
|
||||||
os.unlink(os.path.join(self.internal_dirname, res[1]))
|
# os.unlink(os.path.join(self.internal_dirname, res[1]))
|
||||||
|
#
|
||||||
|
# if __debug__:
|
||||||
|
# print "m_main.py: delete_image(): removed images:"
|
||||||
|
# print res[0]
|
||||||
|
# print res[1]
|
||||||
|
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: delete_image(): removed images:"
|
|
||||||
print res[0]
|
|
||||||
print res[1]
|
|
||||||
# remove images records
|
# remove images records
|
||||||
sql = """DELETE FROM images WHERE id = ?"""
|
sql = """DELETE FROM images WHERE id = ?"""
|
||||||
self.db_cursor.execute(sql, (image_id,))
|
self.db_cursor.execute(sql, (image_id,))
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
|
|
||||||
|
def set_image_as_thumbnail(self, image_id):
|
||||||
|
"""set image as file thumbnail"""
|
||||||
|
sql = """SELECT file_id, filename FROM images WHERE id=?"""
|
||||||
|
self.db_cursor.execute(sql, (image_id,))
|
||||||
|
res = self.db_cursor.fetchone()
|
||||||
|
if res and res[0]:
|
||||||
|
sql = """DELETE FROM thumbnails WHERE file_id=?"""
|
||||||
|
self.db_cursor.execute(sql, (res[0],))
|
||||||
|
sql = """INSERT INTO thumbnails(file_id, filename) VALUES(?, ?)"""
|
||||||
|
self.db_cursor.execute(sql, (res[0], res[1]))
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def delete_all_images(self):
|
def delete_all_images(self):
|
||||||
"""removes all images (with thumbnails) from collection"""
|
"""removes all images from collection"""
|
||||||
# remove images records
|
# remove images records
|
||||||
sql = """DELETE FROM images"""
|
sql = """DELETE FROM images"""
|
||||||
self.db_cursor.execute(sql)
|
self.db_cursor.execute(sql)
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
try:
|
#try:
|
||||||
shutil.rmtree(os.path.join(self.internal_dirname, 'images'))
|
# shutil.rmtree(os.path.join(self.internal_dirname, 'images'))
|
||||||
except:
|
#except:
|
||||||
pass
|
# pass
|
||||||
|
|
||||||
def add_thumbnail(self, img_fn, file_id):
|
def add_thumbnail(self, img_fn, file_id):
|
||||||
"""generate and add thumbnail to selected file/dir"""
|
"""generate and add thumbnail to selected file/dir"""
|
||||||
if self.config.confd['thumbs']:
|
if self.config.confd['thumbs']:
|
||||||
self.del_thumbnail(file_id)
|
self.del_thumbnail(file_id)
|
||||||
thumb = Thumbnail(img_fn, base=self.internal_dirname)
|
im, exif = Thumbnail(img_fn, self.image_path).save()
|
||||||
retval = thumb.save(file_id)
|
|
||||||
if retval[2] != -1:
|
sql = """INSERT INTO thumbnails(file_id, filename) values (?, ?)"""
|
||||||
path = retval[0].split(self.internal_dirname)[1][1:]
|
self.db_cursor.execute(sql, (file_id, im))
|
||||||
sql = """insert into thumbnails(file_id, filename)
|
|
||||||
values (?, ?)"""
|
|
||||||
self.db_cursor.execute(sql, (file_id, path))
|
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def del_thumbnail(self, file_id):
|
def del_thumbnail(self, file_id):
|
||||||
"""removes thumbnail from selected file/dir"""
|
"""removes thumbnail from selected file/dir"""
|
||||||
|
|
||||||
# remove thumbnail files
|
# remove thumbnail files
|
||||||
sql = """SELECT filename FROM thumbnails WHERE file_id=?"""
|
#sql = """SELECT filename FROM thumbnails WHERE file_id=?"""
|
||||||
self.db_cursor.execute(sql, (file_id,))
|
#self.db_cursor.execute(sql, (file_id,))
|
||||||
res = self.db_cursor.fetchone()
|
#res = self.db_cursor.fetchone()
|
||||||
if res:
|
#if res:
|
||||||
os.unlink(os.path.join(self.internal_dirname, res[0]))
|
# os.unlink(os.path.join(self.internal_dirname, res[0]))
|
||||||
|
|
||||||
# remove thumbs records
|
# remove thumbs records
|
||||||
sql = """DELETE FROM thumbnails WHERE file_id=?"""
|
sql = """DELETE FROM thumbnails WHERE file_id=?"""
|
||||||
@@ -495,26 +545,33 @@ class MainModel(ModelMT):
|
|||||||
sql = """DELETE FROM thumbnails"""
|
sql = """DELETE FROM thumbnails"""
|
||||||
self.db_cursor.execute(sql)
|
self.db_cursor.execute(sql)
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
try:
|
#try:
|
||||||
shutil.rmtree(os.path.join(self.internal_dirname, 'thumbnails'))
|
# shutil.rmtree(os.path.join(self.internal_dirname, 'thumbnails'))
|
||||||
except:
|
#except:
|
||||||
pass
|
# pass
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
"""remove temporary directory tree from filesystem"""
|
"""remove temporary directory tree from filesystem"""
|
||||||
self.__close_db_connection()
|
self.__close_db_connection()
|
||||||
if self.internal_dirname != None:
|
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(self.internal_dirname)
|
os.unlink(self.db_tmp_path)
|
||||||
except OSError:
|
except:
|
||||||
|
if __debug__:
|
||||||
|
print "Exception in removing temporary db file!"
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
#if self.internal_dirname != None:
|
||||||
|
# try:
|
||||||
|
# shutil.rmtree(self.internal_dirname)
|
||||||
|
# except OSError:
|
||||||
|
# pass
|
||||||
return
|
return
|
||||||
|
|
||||||
def new(self):
|
def new(self):
|
||||||
"""create new project"""
|
"""create new project"""
|
||||||
self.unsaved_project = False
|
self.unsaved_project = False
|
||||||
self.filename = None
|
self.filename = None
|
||||||
self.__create_internal_dirname()
|
self.__create_temporary_db_file()
|
||||||
self.__connect_to_db()
|
self.__connect_to_db()
|
||||||
self.__create_database()
|
self.__create_database()
|
||||||
self.__clear_trees()
|
self.__clear_trees()
|
||||||
@@ -525,6 +582,10 @@ class MainModel(ModelMT):
|
|||||||
|
|
||||||
def save(self, filename=None):
|
def save(self, filename=None):
|
||||||
"""save tared directory at given catalog fielname"""
|
"""save tared directory at given catalog fielname"""
|
||||||
|
|
||||||
|
# flush all changes
|
||||||
|
self.db_connection.commit()
|
||||||
|
|
||||||
if not filename and not self.filename:
|
if not filename and not self.filename:
|
||||||
if __debug__:
|
if __debug__:
|
||||||
return False, "no filename detected!"
|
return False, "no filename detected!"
|
||||||
@@ -540,59 +601,86 @@ class MainModel(ModelMT):
|
|||||||
def open(self, filename=None):
|
def open(self, filename=None):
|
||||||
"""try to open db file"""
|
"""try to open db file"""
|
||||||
self.unsaved_project = False
|
self.unsaved_project = False
|
||||||
self.__create_internal_dirname()
|
self.__create_temporary_db_file()
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.tag_cloud = []
|
self.tag_cloud = []
|
||||||
self.selected_tags = {}
|
self.selected_tags = {}
|
||||||
self.clear_search_tree()
|
self.clear_search_tree()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tar = tarfile.open(filename, "r:gz")
|
test_file = open(filename).read(15)
|
||||||
except:
|
except IOError:
|
||||||
try:
|
|
||||||
tar = tarfile.open(filename, "r")
|
|
||||||
except:
|
|
||||||
self.filename = None
|
self.filename = None
|
||||||
self.internal_dirname = None
|
self.internal_dirname = None
|
||||||
return
|
return False
|
||||||
|
|
||||||
os.chdir(self.internal_dirname)
|
if test_file == "SQLite format 3":
|
||||||
|
db_tmp = open(self.db_tmp_path, "wb")
|
||||||
|
db_tmp.write(open(filename).read())
|
||||||
|
db_tmp.close()
|
||||||
|
elif test_file[0:10] == "BZh91AY&SY":
|
||||||
|
open_file = bz2.BZ2File(filename)
|
||||||
try:
|
try:
|
||||||
tar.extractall()
|
curdb = open(self.db_tmp_path, "w")
|
||||||
if __debug__:
|
curdb.write(open_file.read())
|
||||||
print "m_main.py: extracted tarfile into",
|
curdb.close()
|
||||||
print self.internal_dirname
|
open_file.close()
|
||||||
except AttributeError:
|
except IOError:
|
||||||
# python 2.4 tarfile module lacks of method extractall()
|
# file is not bz2
|
||||||
directories = []
|
self.filename = None
|
||||||
for tarinfo in tar:
|
self.internal_dirname = None
|
||||||
if tarinfo.isdir():
|
return False
|
||||||
# Extract directory with a safe mode, so that
|
|
||||||
# all files below can be extracted as well.
|
|
||||||
try:
|
|
||||||
os.makedirs(os.path.join('.', tarinfo.name), 0700)
|
|
||||||
except EnvironmentError:
|
|
||||||
pass
|
|
||||||
directories.append(tarinfo)
|
|
||||||
else:
|
else:
|
||||||
tar.extract(tarinfo, '.')
|
self.filename = None
|
||||||
|
self.internal_dirname = None
|
||||||
# Reverse sort directories.
|
return False
|
||||||
directories.sort(lambda a, b: cmp(a.name, b.name))
|
#try:
|
||||||
directories.reverse()
|
# tar = tarfile.open(filename, "r:gz")
|
||||||
|
#except:
|
||||||
# Set correct owner, mtime and filemode on directories.
|
# try:
|
||||||
for tarinfo in directories:
|
# tar = tarfile.open(filename, "r")
|
||||||
try:
|
# except:
|
||||||
os.chown(os.path.join('.', tarinfo.name),
|
# self.filename = None
|
||||||
tarinfo.uid, tarinfo.gid)
|
# self.internal_dirname = None
|
||||||
os.utime(os.path.join('.', tarinfo.name),
|
# return
|
||||||
(0, tarinfo.mtime))
|
#
|
||||||
except OSError:
|
#os.chdir(self.internal_dirname)
|
||||||
if __debug__:
|
#try:
|
||||||
print "m_main.py: open(): setting corrext owner,",
|
# tar.extractall()
|
||||||
print "mtime etc"
|
# if __debug__:
|
||||||
tar.close()
|
# print "m_main.py: extracted tarfile into",
|
||||||
|
# print self.internal_dirname
|
||||||
|
#except AttributeError:
|
||||||
|
# # python 2.4 tarfile module lacks of method extractall()
|
||||||
|
# directories = []
|
||||||
|
# for tarinfo in tar:
|
||||||
|
# if tarinfo.isdir():
|
||||||
|
# # Extract directory with a safe mode, so that
|
||||||
|
# # all files below can be extracted as well.
|
||||||
|
# try:
|
||||||
|
# os.makedirs(os.path.join('.', tarinfo.name), 0700)
|
||||||
|
# except EnvironmentError:
|
||||||
|
# pass
|
||||||
|
# directories.append(tarinfo)
|
||||||
|
# else:
|
||||||
|
# tar.extract(tarinfo, '.')
|
||||||
|
#
|
||||||
|
# # Reverse sort directories.
|
||||||
|
# directories.sort(lambda a, b: cmp(a.name, b.name))
|
||||||
|
# directories.reverse()
|
||||||
|
#
|
||||||
|
# # Set correct owner, mtime and filemode on directories.
|
||||||
|
# for tarinfo in directories:
|
||||||
|
# try:
|
||||||
|
# os.chown(os.path.join('.', tarinfo.name),
|
||||||
|
# tarinfo.uid, tarinfo.gid)
|
||||||
|
# os.utime(os.path.join('.', tarinfo.name),
|
||||||
|
# (0, tarinfo.mtime))
|
||||||
|
# except OSError:
|
||||||
|
# if __debug__:
|
||||||
|
# print "m_main.py: open(): setting corrext owner,",
|
||||||
|
# print "mtime etc"
|
||||||
|
#tar.close()
|
||||||
|
|
||||||
self.__connect_to_db()
|
self.__connect_to_db()
|
||||||
self.__fetch_db_into_treestore()
|
self.__fetch_db_into_treestore()
|
||||||
@@ -858,9 +946,9 @@ class MainModel(ModelMT):
|
|||||||
"""get file info from database"""
|
"""get file info from database"""
|
||||||
retval = {}
|
retval = {}
|
||||||
sql = """SELECT f.filename, f.date, f.size, f.type,
|
sql = """SELECT f.filename, f.date, f.size, f.type,
|
||||||
t.filename, f.description, f.note
|
f.description, f.note, t.filename
|
||||||
FROM files f
|
FROM files f
|
||||||
LEFT JOIN thumbnails t ON t.file_id = f.id
|
LEFT JOIN thumbnails t on f.id = t.file_id
|
||||||
WHERE f.id = ?"""
|
WHERE f.id = ?"""
|
||||||
self.db_cursor.execute(sql, (file_id,))
|
self.db_cursor.execute(sql, (file_id,))
|
||||||
res = self.db_cursor.fetchone()
|
res = self.db_cursor.fetchone()
|
||||||
@@ -873,26 +961,32 @@ class MainModel(ModelMT):
|
|||||||
|
|
||||||
retval['filename'] = res[0]
|
retval['filename'] = res[0]
|
||||||
|
|
||||||
|
if res[4]:
|
||||||
|
retval['description'] = res[4]
|
||||||
|
|
||||||
if res[5]:
|
if res[5]:
|
||||||
retval['description'] = res[5]
|
retval['note'] = res[5]
|
||||||
|
|
||||||
if res[6]:
|
if res[6]:
|
||||||
retval['note'] = res[6]
|
thumbfile = os.path.join(self.image_path, res[6] + "_t")
|
||||||
|
if os.path.exists(thumbfile):
|
||||||
|
pix = gtk.gdk.pixbuf_new_from_file(thumbfile)
|
||||||
|
retval['thumbnail'] = thumbfile
|
||||||
|
|
||||||
if res[4]:
|
sql = """SELECT id, filename FROM images
|
||||||
path = os.path.join(self.internal_dirname, res[4])
|
|
||||||
retval['thumbnail'] = path
|
|
||||||
|
|
||||||
sql = """SELECT id, thumbnail FROM images
|
|
||||||
WHERE file_id = ?"""
|
WHERE file_id = ?"""
|
||||||
self.db_cursor.execute(sql, (file_id,))
|
self.db_cursor.execute(sql, (file_id,))
|
||||||
res = self.db_cursor.fetchall()
|
res = self.db_cursor.fetchall()
|
||||||
if res:
|
if res:
|
||||||
self.images_store = gtk.ListStore(gobject.TYPE_INT, gtk.gdk.Pixbuf)
|
self.images_store = gtk.ListStore(gobject.TYPE_INT, gtk.gdk.Pixbuf)
|
||||||
for idi, thb in res:
|
for im_id, filename in res:
|
||||||
img = os.path.join(self.internal_dirname, thb)
|
thumbfile = os.path.join(self.image_path, filename + "_t")
|
||||||
pix = gtk.gdk.pixbuf_new_from_file(img)
|
if os.path.exists(thumbfile):
|
||||||
self.images_store.append([idi, pix])
|
pix = gtk.gdk.pixbuf_new_from_file(thumbfile)
|
||||||
|
else:
|
||||||
|
pix = gtk.gdk.pixbuf_new_from_inline(len(no_thumb_img),
|
||||||
|
no_thumb_img, False)
|
||||||
|
self.images_store.append([im_id, pix])
|
||||||
retval['images'] = True
|
retval['images'] = True
|
||||||
|
|
||||||
sql = """SELECT camera, date, aperture, exposure_program,
|
sql = """SELECT camera, date, aperture, exposure_program,
|
||||||
@@ -998,23 +1092,23 @@ class MainModel(ModelMT):
|
|||||||
arg = str(tuple(fids))
|
arg = str(tuple(fids))
|
||||||
|
|
||||||
# remove thumbnails
|
# 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)
|
#db_cursor.execute(sql)
|
||||||
res = db_cursor.fetchall()
|
#res = db_cursor.fetchall()
|
||||||
if len(res) > 0:
|
#if len(res) > 0:
|
||||||
for row in res:
|
# for row in res:
|
||||||
os.unlink(os.path.join(self.internal_dirname, row[0]))
|
# os.unlink(os.path.join(self.image_path, row[0]))
|
||||||
|
|
||||||
# remove images
|
# remove images
|
||||||
sql = """SELECT filename, thumbnail FROM images
|
#sql = """SELECT filename, thumbnail FROM images
|
||||||
WHERE file_id IN %s""" % arg
|
# WHERE file_id IN %s""" % arg
|
||||||
db_cursor.execute(sql)
|
#db_cursor.execute(sql)
|
||||||
res = db_cursor.fetchall()
|
#res = db_cursor.fetchall()
|
||||||
if len(res) > 0:
|
#if len(res) > 0:
|
||||||
for row in res:
|
# for row in res:
|
||||||
if row[0]:
|
# if row[0]:
|
||||||
os.unlink(os.path.join(self.internal_dirname, row[0]))
|
# os.unlink(os.path.join(self.internal_dirname, row[0]))
|
||||||
os.unlink(os.path.join(self.internal_dirname, row[1]))
|
# os.unlink(os.path.join(self.internal_dirname, row[1]))
|
||||||
|
|
||||||
# remove thumbs records
|
# remove thumbs records
|
||||||
sql = """DELETE FROM thumbnails WHERE file_id = ?"""
|
sql = """DELETE FROM thumbnails WHERE file_id = ?"""
|
||||||
@@ -1160,9 +1254,10 @@ class MainModel(ModelMT):
|
|||||||
sql = """SELECT filename FROM images WHERE id=?"""
|
sql = """SELECT filename FROM images WHERE id=?"""
|
||||||
self.db_cursor.execute(sql, (img_id,))
|
self.db_cursor.execute(sql, (img_id,))
|
||||||
res = self.db_cursor.fetchone()
|
res = self.db_cursor.fetchone()
|
||||||
if res:
|
if res and res[0]:
|
||||||
if res[0]:
|
path = os.path.join(self.image_path, res[0])
|
||||||
return os.path.join(self.internal_dirname, res[0])
|
if os.path.exists(path):
|
||||||
|
return path
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def update_desc_and_note(self, file_id, desc='', note=''):
|
def update_desc_and_note(self, file_id, desc='', note=''):
|
||||||
@@ -1278,14 +1373,14 @@ class MainModel(ModelMT):
|
|||||||
|
|
||||||
def __connect_to_db(self):
|
def __connect_to_db(self):
|
||||||
"""initialize db connection and store it in class attributes"""
|
"""initialize db connection and store it in class attributes"""
|
||||||
self.db_connection = sqlite.connect("%s" % \
|
self.db_connection = sqlite.connect(self.db_tmp_path,
|
||||||
(self.internal_dirname + '/db.sqlite'),
|
|
||||||
detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)
|
detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)
|
||||||
self.db_cursor = self.db_connection.cursor()
|
self.db_cursor = self.db_connection.cursor()
|
||||||
return
|
return
|
||||||
|
|
||||||
def __close_db_connection(self):
|
def __close_db_connection(self):
|
||||||
"""close db conection"""
|
"""close db conection"""
|
||||||
|
|
||||||
if self.db_cursor != None:
|
if self.db_cursor != None:
|
||||||
self.db_cursor.close()
|
self.db_cursor.close()
|
||||||
self.db_cursor = None
|
self.db_cursor = None
|
||||||
@@ -1294,42 +1389,66 @@ class MainModel(ModelMT):
|
|||||||
self.db_connection = None
|
self.db_connection = None
|
||||||
return
|
return
|
||||||
|
|
||||||
def __create_internal_dirname(self):
|
def __create_temporary_db_file(self):
|
||||||
"""create temporary directory for working thumb/image files and
|
"""create temporary db file"""
|
||||||
database"""
|
|
||||||
# TODO: change this stupid rutine into tempfile mkdtemp method
|
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
self.internal_dirname = "/tmp/pygtktalog%d" % \
|
self.db_tmp_path = mkstemp()[1]
|
||||||
datetime.now().microsecond
|
|
||||||
try:
|
|
||||||
os.mkdir(self.internal_dirname)
|
|
||||||
except IOError, (errno, strerror):
|
|
||||||
print "m_main.py: __create_internal_dirname(): ", strerror
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def __compress_and_save(self):
|
def __compress_and_save(self):
|
||||||
"""create (and optionaly compress) tar archive from working directory
|
"""create (and optionaly compress) tar archive from working directory
|
||||||
and write it to specified file"""
|
and write it to specified file"""
|
||||||
|
|
||||||
|
# flush all changes
|
||||||
|
self.db_connection.commit()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.config.confd['compress']:
|
if self.config.confd['compress']:
|
||||||
tar = tarfile.open(self.filename, "w:gz")
|
output_file = bz2.BZ2File(self.filename, "w")
|
||||||
else:
|
else:
|
||||||
tar = tarfile.open(self.filename, "w")
|
output_file = open(self.filename, "w")
|
||||||
if __debug__:
|
if __debug__:
|
||||||
print "m_main.py: __compress_and_save(): tar open successed"
|
print "m_main.py: __compress_and_save(): tar open successed"
|
||||||
|
|
||||||
except IOError, (errno, strerror):
|
except IOError, (errno, strerror):
|
||||||
return False, strerror
|
return False, strerror
|
||||||
|
|
||||||
os.chdir(self.internal_dirname)
|
dbpath = open(self.db_tmp_path)
|
||||||
tar.add('.')
|
output_file.write(dbpath.read())
|
||||||
tar.close()
|
dbpath.close()
|
||||||
|
output_file.close()
|
||||||
|
|
||||||
self.unsaved_project = False
|
self.unsaved_project = False
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
def __create_database(self):
|
def __create_database(self):
|
||||||
"""make all necessary tables in db file"""
|
"""make all necessary tables in db file
|
||||||
|
|
||||||
|
|
||||||
|
,------------. ,------------.
|
||||||
|
|files | |tags |
|
||||||
|
+------------+ +------------+
|
||||||
|
|→|pk id | |pk id |
|
||||||
|
|_|fk parent_id| |fk group_id |
|
||||||
|
|filename | |tag |
|
||||||
|
|filepath | +------------+
|
||||||
|
|date |
|
||||||
|
|size | ,------------
|
||||||
|
|source | |tags_files
|
||||||
|
|note | |
|
||||||
|
|description | |
|
||||||
|
+------------+ |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
self.db_cursor.execute("""create table
|
self.db_cursor.execute("""create table
|
||||||
files(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
files(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
parent_id INTEGER,
|
parent_id INTEGER,
|
||||||
@@ -1359,7 +1478,6 @@ class MainModel(ModelMT):
|
|||||||
self.db_cursor.execute("""create table
|
self.db_cursor.execute("""create table
|
||||||
images(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
images(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
file_id INTEGER,
|
file_id INTEGER,
|
||||||
thumbnail TEXT,
|
|
||||||
filename TEXT);""")
|
filename TEXT);""")
|
||||||
self.db_cursor.execute("""create table
|
self.db_cursor.execute("""create table
|
||||||
exif(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
exif(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
@@ -1463,8 +1581,7 @@ class MainModel(ModelMT):
|
|||||||
self.busy = True
|
self.busy = True
|
||||||
|
|
||||||
# new conection for this task, because it's running in separate thread
|
# new conection for this task, because it's running in separate thread
|
||||||
db_connection = sqlite.connect("%s" % \
|
db_connection = sqlite.connect(self.db_tmp_path,
|
||||||
(self.internal_dirname + '/db.sqlite'),
|
|
||||||
detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES,
|
detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES,
|
||||||
isolation_level="EXCLUSIVE")
|
isolation_level="EXCLUSIVE")
|
||||||
db_cursor = db_connection.cursor()
|
db_cursor = db_connection.cursor()
|
||||||
@@ -1627,15 +1744,13 @@ class MainModel(ModelMT):
|
|||||||
|
|
||||||
# Images - thumbnails and exif data
|
# Images - thumbnails and exif data
|
||||||
if self.config.confd['thumbs'] and ext in self.IMG:
|
if self.config.confd['thumbs'] and ext in self.IMG:
|
||||||
t = Thumbnail(current_file,
|
thumb = Thumbnail(current_file, self.image_path)
|
||||||
base=self.internal_dirname)
|
th, exif = thumb.save()
|
||||||
tpath, exif, ret_code = t.save(fileid)
|
if th:
|
||||||
if ret_code != -1:
|
|
||||||
sql = """INSERT INTO
|
sql = """INSERT INTO
|
||||||
thumbnails(file_id, filename)
|
thumbnails(file_id, filename)
|
||||||
VALUES(?, ?)"""
|
VALUES(?, ?)"""
|
||||||
t = tpath.split(self.internal_dirname)[1][1:]
|
db_cursor.execute(sql, (fileid, th))
|
||||||
db_cursor.execute(sql, (fileid, t))
|
|
||||||
|
|
||||||
# exif - store data in exif table
|
# exif - store data in exif table
|
||||||
jpg = ['jpg', 'jpeg']
|
jpg = ['jpg', 'jpeg']
|
||||||
@@ -1750,8 +1865,7 @@ class MainModel(ModelMT):
|
|||||||
|
|
||||||
#connect
|
#connect
|
||||||
detect_types = sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES
|
detect_types = sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES
|
||||||
db_connection = sqlite.connect("%s" % \
|
db_connection = sqlite.connect(self.db_tmp_path,
|
||||||
(self.internal_dirname + '/db.sqlite'),
|
|
||||||
detect_types = detect_types)
|
detect_types = detect_types)
|
||||||
db_cursor = db_connection.cursor()
|
db_cursor = db_connection.cursor()
|
||||||
|
|
||||||
@@ -1803,8 +1917,7 @@ class MainModel(ModelMT):
|
|||||||
"""append branch from DB to existing tree model"""
|
"""append branch from DB to existing tree model"""
|
||||||
#connect
|
#connect
|
||||||
detect_types = sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES
|
detect_types = sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES
|
||||||
db_connection = sqlite.connect("%s" %
|
db_connection = sqlite.connect(self.db_tmp_path,
|
||||||
(self.internal_dirname + '/db.sqlite'),
|
|
||||||
detect_types = detect_types)
|
detect_types = detect_types)
|
||||||
db_cursor = db_connection.cursor()
|
db_cursor = db_connection.cursor()
|
||||||
|
|
||||||
|
|||||||
@@ -280,8 +280,8 @@ class ChooseDBFilename(object):
|
|||||||
|
|
||||||
f = gtk.FileFilter()
|
f = gtk.FileFilter()
|
||||||
f.set_name("Catalog files")
|
f.set_name("Catalog files")
|
||||||
f.add_pattern("*.pgt")
|
f.add_pattern("*.sqlite")
|
||||||
f.add_pattern("*.pgt.tgz")
|
f.add_pattern("*.sqlite.bz2")
|
||||||
self.dialog.add_filter(f)
|
self.dialog.add_filter(f)
|
||||||
f = gtk.FileFilter()
|
f = gtk.FileFilter()
|
||||||
f.set_name("All files")
|
f.set_name("All files")
|
||||||
@@ -299,13 +299,9 @@ class ChooseDBFilename(object):
|
|||||||
if response == gtk.RESPONSE_OK:
|
if response == gtk.RESPONSE_OK:
|
||||||
filename = self.dialog.get_filename()
|
filename = self.dialog.get_filename()
|
||||||
print filename, ' do ',
|
print filename, ' do ',
|
||||||
if filename[-8:].lower() != '.pgt.tgz' and \
|
if filename[-11:].lower() != '.sqlite.bz2' and \
|
||||||
filename[-4:].lower() != '.pgt':
|
filename[-7:].lower() != '.sqlite':
|
||||||
filename = filename + '.pgt.tgz'
|
filename = filename + '.sqlite.bz2'
|
||||||
elif filename[-4:].lower() == '.pgt':
|
|
||||||
filename = filename[:-4] + '.pgt.tgz'
|
|
||||||
else:
|
|
||||||
filename = filename[:-8] + '.pgt.tgz'
|
|
||||||
print filename
|
print filename
|
||||||
self.__class__.URI = self.dialog.get_current_folder_uri()
|
self.__class__.URI = self.dialog.get_current_folder_uri()
|
||||||
self.dialog.destroy()
|
self.dialog.destroy()
|
||||||
@@ -337,8 +333,8 @@ class LoadDBFile(object):
|
|||||||
|
|
||||||
f = gtk.FileFilter()
|
f = gtk.FileFilter()
|
||||||
f.set_name("Catalog files")
|
f.set_name("Catalog files")
|
||||||
f.add_pattern("*.pgt")
|
f.add_pattern("*.sqlite")
|
||||||
f.add_pattern("*.pgt.tgz")
|
f.add_pattern("*.sqlite.bz2")
|
||||||
self.dialog.add_filter(f)
|
self.dialog.add_filter(f)
|
||||||
f = gtk.FileFilter()
|
f = gtk.FileFilter()
|
||||||
f.set_name("All files")
|
f.set_name("All files")
|
||||||
|
|||||||
Reference in New Issue
Block a user