mirror of
https://github.com/gryf/pygtktalog.git
synced 2025-12-19 04:20:19 +01:00
Adapt GUI legacy version accept new databases
This commit is contained in:
33
README
33
README
@@ -4,15 +4,15 @@ 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
|
||||||
filesystem. It is similar to gtktalog <http://www.nongnu.org/gtktalog/> or
|
filesystem. It is similar to gtktalog <http://www.nongnu.org/gtktalog/> or
|
||||||
gwhere <http://www.gwhere.org/home.php3>. There is no coincidence in name of
|
gwhere <http://www.gwhere.org/home.php3>. There is no coincidence in name of
|
||||||
application, because it's ment to be replacement (in some way) for gtktalog,
|
application, because it's meant to be replacement (in some way) for gtktalog,
|
||||||
which seems to be dead project for years.
|
which seems to be dead project for years.
|
||||||
|
|
||||||
FEATURES
|
FEATURES
|
||||||
========
|
========
|
||||||
|
|
||||||
- scan for files in selected media
|
- scan for files in selected media
|
||||||
- get/generate thumbnails from exif and other images
|
- get/generate thumbnails from EXIF and other images
|
||||||
- most important exif tags
|
- most important EXIF tags
|
||||||
- add/edit description and notes
|
- add/edit description and notes
|
||||||
- fetch comments for images made in gThumb <http://gthumb.sourceforge.net>
|
- fetch comments for images made in gThumb <http://gthumb.sourceforge.net>
|
||||||
- add/remove unlimited images to any file or directory
|
- add/remove unlimited images to any file or directory
|
||||||
@@ -30,19 +30,20 @@ pyGTKtalog is written in python with following dependencies:
|
|||||||
|
|
||||||
Optional modules:
|
Optional modules:
|
||||||
|
|
||||||
- PIL <http://www.pythonware.com/products/pil/index.htm> for image manipulation
|
- PIL <http://www.pythonware.com/products/pil/index.htm> for image
|
||||||
|
manipulation
|
||||||
|
|
||||||
Additional pyGTKtalog uses pygtkmvc <http://pygtkmvc.sourceforge.net> by Roberto
|
Additional pyGTKtalog uses pygtkmvc <http://pygtkmvc.sourceforge.net> by
|
||||||
Cavada and EXIF module by Gene Cash (slightly updatetd to EXIF 2.2 by me) which
|
Roberto Cavada and EXIF module by Gene Cash (slightly updatetd to EXIF 2.2 by
|
||||||
are included in sources.
|
me) which are included in sources.
|
||||||
|
|
||||||
pyGTKtalog extensivly uses external programs in unix spirit, however there is
|
pyGTKtalog extensively uses external programs in unix spirit, however there is
|
||||||
small possibility of using it Windows (probably with limitations) and quite big
|
small possibility of using it Windows (probably with limitations) and quite
|
||||||
possiblity to run it on other sofisticated unix-like systems (i.e.
|
big possibility to run it on other sophisticated unix-like systems (i.e.
|
||||||
BeOS/ZETA/Haiku, QNX or MacOSX).
|
BeOS/ZETA/Haiku, QNX or MacOSX).
|
||||||
|
|
||||||
INSTALATION
|
INSTALLATION
|
||||||
===========
|
============
|
||||||
|
|
||||||
You don't have to install it if you don't want to. You can just change current
|
You don't have to install it if you don't want to. You can just change current
|
||||||
directory to pyGTKtalog and simply run:
|
directory to pyGTKtalog and simply run:
|
||||||
@@ -80,11 +81,12 @@ For version 2.0:
|
|||||||
- command line support: query, adding media to collection etc
|
- command line support: query, adding media to collection etc
|
||||||
- internationalization
|
- internationalization
|
||||||
- export to XLS
|
- export to XLS
|
||||||
- user definied group of tags (represented by color in cloud tag)
|
- user defined group of tags (represented by color in cloud tag)
|
||||||
- hiding specified files - configurable, like dot prefixed, cfg and manualy
|
- hiding specified files - configurable, like dot prefixed, config files and
|
||||||
selected
|
manually selected
|
||||||
- tests
|
- tests
|
||||||
- warning about existing image in media directory
|
- warning about existing image in media directory
|
||||||
|
|
||||||
Removed:
|
Removed:
|
||||||
- filetypes handling (movies, images, archives, documents etc). Now it have
|
- filetypes handling (movies, images, archives, documents etc). Now it have
|
||||||
common, unified external "plugin" system - simple text output from command
|
common, unified external "plugin" system - simple text output from command
|
||||||
@@ -126,4 +128,3 @@ BUGS
|
|||||||
====
|
====
|
||||||
|
|
||||||
All bugs please report to Roman 'gryf' Dobosz <roman.dobosz@gmail.com>
|
All bugs please report to Roman 'gryf' Dobosz <roman.dobosz@gmail.com>
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ __version__ = "1.0.1"
|
|||||||
LICENCE = ''
|
LICENCE = ''
|
||||||
import os.path
|
import os.path
|
||||||
from os import popen
|
from os import popen
|
||||||
from utils import deviceHelper
|
from utils import device_helper
|
||||||
from gtkmvc import Controller
|
from gtkmvc import Controller
|
||||||
|
|
||||||
from c_config import ConfigController
|
from c_config import ConfigController
|
||||||
@@ -526,9 +526,9 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_add_cd_activate(self, widget, label=None, current_id=None):
|
def on_add_cd_activate(self, widget, label=None, current_id=None):
|
||||||
"""Add directory structure from cd/dvd disc"""
|
"""Add directory structure from cd/dvd disc"""
|
||||||
mount = deviceHelper.volmount(self.model.config.confd['cd'])
|
mount = device_helper.volmount(self.model.config.confd['cd'])
|
||||||
if mount == 'ok':
|
if mount == 'ok':
|
||||||
guessed_label = deviceHelper.volname(self.model.config.confd['cd'])
|
guessed_label = device_helper.volname(self.model.config.confd['cd'])
|
||||||
if not label:
|
if not label:
|
||||||
label = Dialogs.InputDiskLabel(guessed_label).run()
|
label = Dialogs.InputDiskLabel(guessed_label).run()
|
||||||
if label:
|
if label:
|
||||||
@@ -541,7 +541,7 @@ class MainController(Controller):
|
|||||||
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)
|
||||||
else:
|
else:
|
||||||
deviceHelper.volumount(self.model.config.confd['cd'])
|
device_helper.volumount(self.model.config.confd['cd'])
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
Dialogs.Wrn("Error mounting device - pyGTKtalog",
|
Dialogs.Wrn("Error mounting device - pyGTKtalog",
|
||||||
@@ -1373,7 +1373,7 @@ class MainController(Controller):
|
|||||||
# umount/eject cd
|
# umount/eject cd
|
||||||
ejectapp = self.model.config.confd['ejectapp']
|
ejectapp = self.model.config.confd['ejectapp']
|
||||||
if self.model.config.confd['eject'] and ejectapp:
|
if self.model.config.confd['eject'] and ejectapp:
|
||||||
msg = deviceHelper.eject_cd(ejectapp,
|
msg = device_helper.eject_cd(ejectapp,
|
||||||
self.model.config.confd['cd'])
|
self.model.config.confd['cd'])
|
||||||
if msg != 'ok':
|
if msg != 'ok':
|
||||||
Dialogs.Wrn("error ejecting device - pyGTKtalog",
|
Dialogs.Wrn("error ejecting device - pyGTKtalog",
|
||||||
@@ -1381,7 +1381,7 @@ class MainController(Controller):
|
|||||||
self.model.config.confd['cd'],
|
self.model.config.confd['cd'],
|
||||||
"Last eject message:\n%s" % msg)
|
"Last eject message:\n%s" % msg)
|
||||||
else:
|
else:
|
||||||
msg = deviceHelper.volumount(self.model.config.confd['cd'])
|
msg = device_helper.volumount(self.model.config.confd['cd'])
|
||||||
if msg != 'ok':
|
if msg != 'ok':
|
||||||
Dialogs.Wrn("error unmounting device - pyGTKtalog",
|
Dialogs.Wrn("error unmounting device - pyGTKtalog",
|
||||||
"Cannot unmount device pointed to %s" %
|
"Cannot unmount device pointed to %s" %
|
||||||
|
|||||||
@@ -34,7 +34,11 @@ import gobject
|
|||||||
|
|
||||||
from gtkmvc.model_mt import ModelMT
|
from gtkmvc.model_mt import ModelMT
|
||||||
|
|
||||||
from pysqlite2 import dbapi2 as sqlite
|
try:
|
||||||
|
import sqlite3 as sqlite
|
||||||
|
except ImportError:
|
||||||
|
from pysqlite2 import dbapi2 as sqlite
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import threading as _threading
|
import threading as _threading
|
||||||
@@ -50,6 +54,20 @@ from utils.gthumb import GthumbCommentParser
|
|||||||
|
|
||||||
from utils.no_thumb import no_thumb as no_thumb_img
|
from utils.no_thumb import no_thumb as no_thumb_img
|
||||||
|
|
||||||
|
def mangle_date(date):
|
||||||
|
"""Return date object depending on the record type."""
|
||||||
|
|
||||||
|
if date:
|
||||||
|
try:
|
||||||
|
dateobj = datetime.fromtimestamp(date)
|
||||||
|
except TypeError:
|
||||||
|
dateobj = datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f")
|
||||||
|
else:
|
||||||
|
dateobj = datetime.fromtimestamp(0)
|
||||||
|
|
||||||
|
return dateobj
|
||||||
|
|
||||||
|
|
||||||
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"""
|
||||||
|
|
||||||
@@ -169,7 +187,6 @@ class MainModel(ModelMT):
|
|||||||
else:
|
else:
|
||||||
os.mkdir(path)
|
os.mkdir(path)
|
||||||
|
|
||||||
|
|
||||||
if os.path.exists(imgpath):
|
if os.path.exists(imgpath):
|
||||||
if not os.path.isdir(imgpath):
|
if not os.path.isdir(imgpath):
|
||||||
print "Warning:",
|
print "Warning:",
|
||||||
@@ -360,8 +377,6 @@ class MainModel(ModelMT):
|
|||||||
res = self.db_cursor.fetchone()
|
res = self.db_cursor.fetchone()
|
||||||
if res and res[0]:
|
if res and res[0]:
|
||||||
# there is such an image. going back.
|
# there is such an image. going back.
|
||||||
if __debug__:
|
|
||||||
print res[0]
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# check if file have have thumbnail. if not, make it with first
|
# check if file have have thumbnail. if not, make it with first
|
||||||
@@ -556,8 +571,6 @@ class MainModel(ModelMT):
|
|||||||
try:
|
try:
|
||||||
os.unlink(self.db_tmp_path)
|
os.unlink(self.db_tmp_path)
|
||||||
except:
|
except:
|
||||||
if __debug__:
|
|
||||||
print "Exception in removing temporary db file!"
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#if self.internal_dirname != None:
|
#if self.internal_dirname != None:
|
||||||
@@ -573,6 +586,7 @@ class MainModel(ModelMT):
|
|||||||
self.filename = None
|
self.filename = None
|
||||||
self.__create_temporary_db_file()
|
self.__create_temporary_db_file()
|
||||||
self.__connect_to_db()
|
self.__connect_to_db()
|
||||||
|
self._set_image_path()
|
||||||
self.__create_database()
|
self.__create_database()
|
||||||
self.__clear_trees()
|
self.__clear_trees()
|
||||||
self.clear_search_tree()
|
self.clear_search_tree()
|
||||||
@@ -592,6 +606,14 @@ class MainModel(ModelMT):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if filename:
|
if filename:
|
||||||
|
if not '.sqlite' in filename:
|
||||||
|
filename += '.sqlite'
|
||||||
|
else:
|
||||||
|
filename = filename[:filename.rindex('.sqlite')] + '.sqlite'
|
||||||
|
|
||||||
|
if self.config.confd['compress']:
|
||||||
|
filename += '.bz2'
|
||||||
|
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
val, err = self.__compress_and_save()
|
val, err = self.__compress_and_save()
|
||||||
if not val:
|
if not val:
|
||||||
@@ -683,6 +705,7 @@ class MainModel(ModelMT):
|
|||||||
#tar.close()
|
#tar.close()
|
||||||
|
|
||||||
self.__connect_to_db()
|
self.__connect_to_db()
|
||||||
|
self._set_image_path()
|
||||||
self.__fetch_db_into_treestore()
|
self.__fetch_db_into_treestore()
|
||||||
self.config.add_recent(filename)
|
self.config.add_recent(filename)
|
||||||
self.get_tags()
|
self.get_tags()
|
||||||
@@ -758,8 +781,9 @@ class MainModel(ModelMT):
|
|||||||
self.search_list.set_value(myiter, 3,
|
self.search_list.set_value(myiter, 3,
|
||||||
self.__get_file_path(row[0]))
|
self.__get_file_path(row[0]))
|
||||||
self.search_list.set_value(myiter, 4, row[2])
|
self.search_list.set_value(myiter, 4, row[2])
|
||||||
self.search_list.set_value(myiter, 5,
|
|
||||||
datetime.fromtimestamp(row[3]))
|
self.search_list.set_value(myiter, 5, mangle_date(row[3]))
|
||||||
|
|
||||||
self.search_list.set_value(myiter, 6, 1)
|
self.search_list.set_value(myiter, 6, 1)
|
||||||
self.search_list.set_value(myiter, 7, gtk.STOCK_DIRECTORY)
|
self.search_list.set_value(myiter, 7, gtk.STOCK_DIRECTORY)
|
||||||
|
|
||||||
@@ -794,8 +818,7 @@ class MainModel(ModelMT):
|
|||||||
self.search_list.set_value(myiter, 3,
|
self.search_list.set_value(myiter, 3,
|
||||||
self.__get_file_path(row[0]))
|
self.__get_file_path(row[0]))
|
||||||
self.search_list.set_value(myiter, 4, row[2])
|
self.search_list.set_value(myiter, 4, row[2])
|
||||||
self.search_list.set_value(myiter, 5,
|
self.search_list.set_value(myiter, 5, mangle_date(row[3]))
|
||||||
datetime.fromtimestamp(row[3]))
|
|
||||||
self.search_list.set_value(myiter, 6, row[4])
|
self.search_list.set_value(myiter, 6, row[4])
|
||||||
if row[4] == self.FIL:
|
if row[4] == self.FIL:
|
||||||
self.search_list.set_value(myiter, 7, gtk.STOCK_FILE)
|
self.search_list.set_value(myiter, 7, gtk.STOCK_FILE)
|
||||||
@@ -825,9 +848,7 @@ class MainModel(ModelMT):
|
|||||||
|
|
||||||
#self.__fetch_db_into_treestore()
|
#self.__fetch_db_into_treestore()
|
||||||
self.unsaved_project = True
|
self.unsaved_project = True
|
||||||
else:
|
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: rename(): no label defined"
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def refresh_discs_tree(self):
|
def refresh_discs_tree(self):
|
||||||
@@ -879,8 +900,7 @@ class MainModel(ModelMT):
|
|||||||
self.files_list.set_value(myiter, 2, row[1])
|
self.files_list.set_value(myiter, 2, row[1])
|
||||||
self.files_list.set_value(myiter, 3, self.__get_file_path(row[0]))
|
self.files_list.set_value(myiter, 3, self.__get_file_path(row[0]))
|
||||||
self.files_list.set_value(myiter, 4, row[2])
|
self.files_list.set_value(myiter, 4, row[2])
|
||||||
self.files_list.set_value(myiter, 5,
|
self.files_list.set_value(myiter, 5, mangle_date(row[3]))
|
||||||
datetime.fromtimestamp(row[3]))
|
|
||||||
self.files_list.set_value(myiter, 6, 1)
|
self.files_list.set_value(myiter, 6, 1)
|
||||||
self.files_list.set_value(myiter, 7, gtk.STOCK_DIRECTORY)
|
self.files_list.set_value(myiter, 7, gtk.STOCK_DIRECTORY)
|
||||||
|
|
||||||
@@ -923,8 +943,7 @@ class MainModel(ModelMT):
|
|||||||
self.files_list.set_value(myiter, 2, row[1])
|
self.files_list.set_value(myiter, 2, row[1])
|
||||||
self.files_list.set_value(myiter, 3, self.__get_file_path(row[0]))
|
self.files_list.set_value(myiter, 3, self.__get_file_path(row[0]))
|
||||||
self.files_list.set_value(myiter, 4, row[2])
|
self.files_list.set_value(myiter, 4, row[2])
|
||||||
self.files_list.set_value(myiter, 5,
|
self.files_list.set_value(myiter, 5, mangle_date(row[3]))
|
||||||
datetime.fromtimestamp(row[3]))
|
|
||||||
self.files_list.set_value(myiter, 6, row[4])
|
self.files_list.set_value(myiter, 6, row[4])
|
||||||
if row[4] == self.FIL:
|
if row[4] == self.FIL:
|
||||||
self.files_list.set_value(myiter, 7, gtk.STOCK_FILE)
|
self.files_list.set_value(myiter, 7, gtk.STOCK_FILE)
|
||||||
@@ -954,11 +973,10 @@ class MainModel(ModelMT):
|
|||||||
res = self.db_cursor.fetchone()
|
res = self.db_cursor.fetchone()
|
||||||
if res:
|
if res:
|
||||||
retval['fileinfo'] = {'id': file_id,
|
retval['fileinfo'] = {'id': file_id,
|
||||||
'date': datetime.fromtimestamp(res[1]),
|
'size': res[2],
|
||||||
'size': res[2], 'type': res[3]}
|
'type': res[3],
|
||||||
|
'date': mangle_date(res[1]),
|
||||||
retval['fileinfo']['disc'] = self.__get_file_root(file_id)
|
'disc': self.__get_file_root(file_id)}
|
||||||
|
|
||||||
retval['filename'] = res[0]
|
retval['filename'] = res[0]
|
||||||
|
|
||||||
if res[4]:
|
if res[4]:
|
||||||
@@ -969,9 +987,13 @@ class MainModel(ModelMT):
|
|||||||
|
|
||||||
if res[6]:
|
if res[6]:
|
||||||
thumbfile = os.path.join(self.image_path, res[6] + "_t")
|
thumbfile = os.path.join(self.image_path, res[6] + "_t")
|
||||||
|
thumb2 = os.path.join(self.image_path, res[6])
|
||||||
if os.path.exists(thumbfile):
|
if os.path.exists(thumbfile):
|
||||||
pix = gtk.gdk.pixbuf_new_from_file(thumbfile)
|
pix = gtk.gdk.pixbuf_new_from_file(thumbfile)
|
||||||
retval['thumbnail'] = thumbfile
|
retval['thumbnail'] = thumbfile
|
||||||
|
elif os.path.exists(thumb2):
|
||||||
|
pix = gtk.gdk.pixbuf_new_from_file(thumb2)
|
||||||
|
retval['thumbnail'] = thumb2
|
||||||
|
|
||||||
sql = """SELECT id, filename FROM images
|
sql = """SELECT id, filename FROM images
|
||||||
WHERE file_id = ?"""
|
WHERE file_id = ?"""
|
||||||
@@ -981,8 +1003,13 @@ class MainModel(ModelMT):
|
|||||||
self.images_store = gtk.ListStore(gobject.TYPE_INT, gtk.gdk.Pixbuf)
|
self.images_store = gtk.ListStore(gobject.TYPE_INT, gtk.gdk.Pixbuf)
|
||||||
for im_id, filename in res:
|
for im_id, filename in res:
|
||||||
thumbfile = os.path.join(self.image_path, filename + "_t")
|
thumbfile = os.path.join(self.image_path, filename + "_t")
|
||||||
|
file_, ext_ = os.path.splitext(filename)
|
||||||
|
thumb2 = os.path.join(self.image_path,
|
||||||
|
"".join([file_, "_t", ext_]))
|
||||||
if os.path.exists(thumbfile):
|
if os.path.exists(thumbfile):
|
||||||
pix = gtk.gdk.pixbuf_new_from_file(thumbfile)
|
pix = gtk.gdk.pixbuf_new_from_file(thumbfile)
|
||||||
|
elif os.path.exists(thumb2):
|
||||||
|
pix = gtk.gdk.pixbuf_new_from_file(thumb2)
|
||||||
else:
|
else:
|
||||||
pix = gtk.gdk.pixbuf_new_from_inline(len(no_thumb_img),
|
pix = gtk.gdk.pixbuf_new_from_inline(len(no_thumb_img),
|
||||||
no_thumb_img, False)
|
no_thumb_img, False)
|
||||||
@@ -1083,13 +1110,10 @@ class MainModel(ModelMT):
|
|||||||
sql = """DELETE FROM tags_files WHERE file_id = ?"""
|
sql = """DELETE FROM tags_files WHERE file_id = ?"""
|
||||||
db_cursor.executemany(sql, generator())
|
db_cursor.executemany(sql, generator())
|
||||||
|
|
||||||
if __debug__:
|
#if len(fids) == 1:
|
||||||
print "m_main.py: delete(): deleting:", fids
|
# arg = "(%d)" % fids[0]
|
||||||
|
#else:
|
||||||
if len(fids) == 1:
|
# arg = str(tuple(fids))
|
||||||
arg = "(%d)" % fids[0]
|
|
||||||
else:
|
|
||||||
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
|
||||||
@@ -1258,12 +1282,15 @@ class MainModel(ModelMT):
|
|||||||
path = os.path.join(self.image_path, res[0])
|
path = os.path.join(self.image_path, res[0])
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
return path
|
return path
|
||||||
|
path = os.path.join('/home/gryf/.pygtktalog/imgs2/', 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=''):
|
||||||
"""update note and description"""
|
"""update note and description"""
|
||||||
sql = """UPDATE files SET description=?, note=? WHERE id=?"""
|
sql = """UPDATE files SET description=?, note=? WHERE id=?"""
|
||||||
self.db_cursor.execute(sql, (desc, note, file_id))
|
self.db_cursor.execute(sql, (unicode(desc), unicode(note), file_id))
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1378,6 +1405,34 @@ class MainModel(ModelMT):
|
|||||||
self.db_cursor = self.db_connection.cursor()
|
self.db_cursor = self.db_connection.cursor()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _set_image_path(self):
|
||||||
|
"""hack, hack, hack!"""
|
||||||
|
if not self.filename:
|
||||||
|
return
|
||||||
|
|
||||||
|
sql = ("select name from sqlite_master where name='config' and "
|
||||||
|
"type='table'")
|
||||||
|
if not self.db_cursor.execute(sql).fetchone():
|
||||||
|
return
|
||||||
|
|
||||||
|
sql = "SELECT value FROM config WHERE key = ?"
|
||||||
|
res = self.db_cursor.execute(sql, ("image_path", )).fetchone()
|
||||||
|
if not res:
|
||||||
|
return
|
||||||
|
|
||||||
|
if res[0] == ":same_as_db:":
|
||||||
|
dir_, file_ = (os.path.dirname(self.filename),
|
||||||
|
os.path.basename(self.filename))
|
||||||
|
file_base, dummy = os.path.splitext(file_)
|
||||||
|
self.image_path = os.path.abspath(os.path.join(dir_, file_base +
|
||||||
|
"_images"))
|
||||||
|
else:
|
||||||
|
self.image_path = res[0]
|
||||||
|
if "~" in self.image_path:
|
||||||
|
self.images_dir = os.path.expanduser(self.image_path)
|
||||||
|
if "$" in self.image_path:
|
||||||
|
self.images_dir = os.path.expandvars(self.image_path)
|
||||||
|
|
||||||
def __close_db_connection(self):
|
def __close_db_connection(self):
|
||||||
"""close db conection"""
|
"""close db conection"""
|
||||||
|
|
||||||
@@ -1407,8 +1462,6 @@ class MainModel(ModelMT):
|
|||||||
output_file = bz2.BZ2File(self.filename, "w")
|
output_file = bz2.BZ2File(self.filename, "w")
|
||||||
else:
|
else:
|
||||||
output_file = open(self.filename, "w")
|
output_file = open(self.filename, "w")
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: __compress_and_save(): tar open successed"
|
|
||||||
|
|
||||||
except IOError, (errno, strerror):
|
except IOError, (errno, strerror):
|
||||||
return False, strerror
|
return False, strerror
|
||||||
@@ -1597,8 +1650,6 @@ class MainModel(ModelMT):
|
|||||||
for root, dirs, files in os.walk(self.path):
|
for root, dirs, files in os.walk(self.path):
|
||||||
count += len(files)
|
count += len(files)
|
||||||
except:
|
except:
|
||||||
if __debug__:
|
|
||||||
print 'm_main.py: os.walk in %s' % self.path
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if count > 0:
|
if count > 0:
|
||||||
@@ -1630,14 +1681,14 @@ class MainModel(ModelMT):
|
|||||||
files(parent_id, filename, filepath, date,
|
files(parent_id, filename, filepath, date,
|
||||||
size, type, source)
|
size, type, source)
|
||||||
VALUES(?,?,?,?,?,?,?)"""
|
VALUES(?,?,?,?,?,?,?)"""
|
||||||
db_cursor.execute(sql, (parent_id, name, path, date, size,
|
db_cursor.execute(sql, (parent_id, name, path.decode("utf-8"),
|
||||||
filetype, self.source))
|
date, size, filetype, self.source))
|
||||||
else:
|
else:
|
||||||
self.discs_tree.set_value(myit, 2, gtk.STOCK_DIRECTORY)
|
self.discs_tree.set_value(myit, 2, gtk.STOCK_DIRECTORY)
|
||||||
sql = """INSERT INTO
|
sql = """INSERT INTO
|
||||||
files(parent_id, filename, filepath, date, size, type)
|
files(parent_id, filename, filepath, date, size, type)
|
||||||
VALUES(?,?,?,?,?,?)"""
|
VALUES(?,?,?,?,?,?)"""
|
||||||
db_cursor.execute(sql, (parent_id, name, path,
|
db_cursor.execute(sql, (parent_id, name, path.decode("utf-8"),
|
||||||
date, size, filetype))
|
date, size, filetype))
|
||||||
|
|
||||||
sql = """SELECT seq FROM sqlite_sequence WHERE name='files'"""
|
sql = """SELECT seq FROM sqlite_sequence WHERE name='files'"""
|
||||||
@@ -1645,14 +1696,13 @@ class MainModel(ModelMT):
|
|||||||
currentid = db_cursor.fetchone()[0]
|
currentid = db_cursor.fetchone()[0]
|
||||||
|
|
||||||
self.discs_tree.set_value(myit, 0, currentid)
|
self.discs_tree.set_value(myit, 0, currentid)
|
||||||
|
|
||||||
self.discs_tree.set_value(myit, 1, name)
|
self.discs_tree.set_value(myit, 1, name)
|
||||||
self.discs_tree.set_value(myit, 3, parent_id)
|
self.discs_tree.set_value(myit, 3, parent_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
root, dirs, files = os.walk(path).next()
|
root, dirs, files = os.walk(path).next()
|
||||||
except:
|
except:
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: cannot access ", path
|
|
||||||
#return -1
|
#return -1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -1721,8 +1771,12 @@ class MainModel(ModelMT):
|
|||||||
sql = """INSERT INTO
|
sql = """INSERT INTO
|
||||||
files(parent_id, filename, filepath, date, size, type)
|
files(parent_id, filename, filepath, date, size, type)
|
||||||
VALUES(?,?,?,?,?,?)"""
|
VALUES(?,?,?,?,?,?)"""
|
||||||
db_cursor.execute(sql, (currentid, j, current_file,
|
try:
|
||||||
st_mtime, st_size, self.FIL))
|
db_cursor.execute(sql, (currentid, unicode(j),
|
||||||
|
unicode(current_file),
|
||||||
|
st_mtime, st_size, self.FIL))
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
|
||||||
if self.count % 32 == 0:
|
if self.count % 32 == 0:
|
||||||
update = True
|
update = True
|
||||||
@@ -1812,7 +1866,10 @@ class MainModel(ModelMT):
|
|||||||
|
|
||||||
sql = """UPDATE files SET description=?
|
sql = """UPDATE files SET description=?
|
||||||
WHERE id=?"""
|
WHERE id=?"""
|
||||||
db_cursor.execute(sql, (desc, fileid))
|
db_cursor.execute(sql,
|
||||||
|
(unicode(desc.decode("utf8",
|
||||||
|
"ignore")),
|
||||||
|
fileid))
|
||||||
|
|
||||||
### end of scan
|
### end of scan
|
||||||
if update:
|
if update:
|
||||||
@@ -1827,18 +1884,11 @@ class MainModel(ModelMT):
|
|||||||
return _size
|
return _size
|
||||||
|
|
||||||
if __recurse(1, self.label, self.path, 0, 0, self.DIR) == -1:
|
if __recurse(1, self.label, self.path, 0, 0, self.DIR) == -1:
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: __scan() __recurse()",
|
|
||||||
print "interrupted self.abort = True"
|
|
||||||
self.discs_tree.remove(self.fresh_disk_iter)
|
self.discs_tree.remove(self.fresh_disk_iter)
|
||||||
db_cursor.close()
|
db_cursor.close()
|
||||||
db_connection.rollback()
|
db_connection.rollback()
|
||||||
else:
|
else:
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: __scan() __recurse() goes without interrupt"
|
|
||||||
if self.currentid:
|
if self.currentid:
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: __scan() removing old branch"
|
|
||||||
self.statusmsg = "Removing old branch..."
|
self.statusmsg = "Removing old branch..."
|
||||||
self.delete(self.currentid, db_cursor, db_connection)
|
self.delete(self.currentid, db_cursor, db_connection)
|
||||||
|
|
||||||
@@ -1847,8 +1897,6 @@ class MainModel(ModelMT):
|
|||||||
db_cursor.close()
|
db_cursor.close()
|
||||||
db_connection.commit()
|
db_connection.commit()
|
||||||
db_connection.close()
|
db_connection.close()
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: __scan() time: ", (datetime.now() - timestamp)
|
|
||||||
|
|
||||||
self.busy = False
|
self.busy = False
|
||||||
|
|
||||||
@@ -1903,13 +1951,8 @@ class MainModel(ModelMT):
|
|||||||
gtk.STOCK_DIRECTORY)
|
gtk.STOCK_DIRECTORY)
|
||||||
return
|
return
|
||||||
|
|
||||||
if __debug__:
|
|
||||||
start_date = datetime.now()
|
|
||||||
# launch scanning.
|
# launch scanning.
|
||||||
get_children()
|
get_children()
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: __fetch_db_into_treestore()",
|
|
||||||
print "tree generation time: ", (datetime.now() - start_date)
|
|
||||||
db_connection.close()
|
db_connection.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1944,13 +1987,8 @@ class MainModel(ModelMT):
|
|||||||
gtk.STOCK_DIRECTORY)
|
gtk.STOCK_DIRECTORY)
|
||||||
return
|
return
|
||||||
|
|
||||||
if __debug__:
|
|
||||||
start_date = datetime.now()
|
|
||||||
# launch scanning.
|
# launch scanning.
|
||||||
get_children()
|
get_children()
|
||||||
if __debug__:
|
|
||||||
print "m_main.py: __append_added_volume() tree generation time: ",
|
|
||||||
print datetime.now() - start_date
|
|
||||||
db_connection.close()
|
db_connection.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
# This Python file uses the following encoding: utf-8
|
|
||||||
#
|
|
||||||
# Author: Roman 'gryf' Dobosz gryf@elysium.pl
|
|
||||||
#
|
|
||||||
# Copyright (C) 2007 by Roman 'gryf' Dobosz
|
|
||||||
#
|
|
||||||
# This file is part of pyGTKtalog.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
|
||||||
"""
|
|
||||||
device (cd, dvd) helper
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
def volname(mntp):
|
|
||||||
"""read volume name from cd/dvd"""
|
|
||||||
dev = mountpoint_to_dev(mntp)
|
|
||||||
if dev != None:
|
|
||||||
try:
|
|
||||||
a = open(dev,"rb")
|
|
||||||
a.seek(32808)
|
|
||||||
b = a.read(32).strip()
|
|
||||||
a.close()
|
|
||||||
except:
|
|
||||||
return None
|
|
||||||
return b
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def volmount(mntp):
|
|
||||||
"""mount device, return 'ok' or error message"""
|
|
||||||
_in,_out,_err = os.popen3("mount %s" % mntp)
|
|
||||||
inf = _err.readlines()
|
|
||||||
if len(inf) > 0:
|
|
||||||
for i in inf:
|
|
||||||
i.strip()
|
|
||||||
return i
|
|
||||||
else:
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def volumount(mntp):
|
|
||||||
"""mount device, return 'ok' or error message"""
|
|
||||||
_in,_out,_err = os.popen3("umount %s" % mntp)
|
|
||||||
inf = _err.readlines()
|
|
||||||
if len(inf) > 0:
|
|
||||||
for error in inf:
|
|
||||||
error.strip()
|
|
||||||
|
|
||||||
if error.strip()[:7] == 'umount:':
|
|
||||||
return error.strip()
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def check_mount(dev):
|
|
||||||
"""Refresh the entries from fstab or mount."""
|
|
||||||
mounts = os.popen('mount')
|
|
||||||
for line in mounts.readlines():
|
|
||||||
parts = line.split()
|
|
||||||
device, txt1, mount_point, txt2, filesystem, options = parts
|
|
||||||
if device == dev:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def mountpoint_to_dev(mntp):
|
|
||||||
"""guess mountpoint from fstab"""
|
|
||||||
fstab = open("/etc/fstab")
|
|
||||||
for line in fstab.readlines():
|
|
||||||
a = line.split()
|
|
||||||
try:
|
|
||||||
if a[1] == mntp and a[0][0] != '#':
|
|
||||||
fstab.close()
|
|
||||||
return a[0]
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
fstab.close()
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def eject_cd(eject_app, cd):
|
|
||||||
"""mount device, return 'ok' or error message"""
|
|
||||||
if len(eject_app) > 0:
|
|
||||||
_in,_out,_err = os.popen3("%s %s" % (eject_app, cd))
|
|
||||||
inf = _err.readlines()
|
|
||||||
error = ''
|
|
||||||
|
|
||||||
for error in inf:
|
|
||||||
error.strip()
|
|
||||||
|
|
||||||
if error !='':
|
|
||||||
return error
|
|
||||||
|
|
||||||
return 'ok'
|
|
||||||
return "Eject program not specified"
|
|
||||||
|
|
||||||
@@ -26,7 +26,8 @@ from shutil import copy
|
|||||||
from os import path
|
from os import path
|
||||||
from hashlib import sha512
|
from hashlib import sha512
|
||||||
|
|
||||||
import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
class Img(object):
|
class Img(object):
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ from os import path
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from utils import EXIF
|
from utils import EXIF
|
||||||
import Image
|
from PIL import Image
|
||||||
|
|
||||||
class Thumbnail(object):
|
class Thumbnail(object):
|
||||||
"""Class for generate/extract thumbnail from image file"""
|
"""Class for generate/extract thumbnail from image file"""
|
||||||
@@ -56,7 +56,7 @@ class Thumbnail(object):
|
|||||||
# rotated 90 CW
|
# rotated 90 CW
|
||||||
8: Image.ROTATE_90} # Rotated 90 CCW
|
8: Image.ROTATE_90} # Rotated 90 CCW
|
||||||
flips = {7: Image.FLIP_LEFT_RIGHT, 5: Image.FLIP_LEFT_RIGHT}
|
flips = {7: Image.FLIP_LEFT_RIGHT, 5: Image.FLIP_LEFT_RIGHT}
|
||||||
|
|
||||||
image_file = open(self.filename, 'rb')
|
image_file = open(self.filename, 'rb')
|
||||||
try:
|
try:
|
||||||
exif = EXIF.process_file(image_file)
|
exif = EXIF.process_file(image_file)
|
||||||
@@ -71,7 +71,7 @@ class Thumbnail(object):
|
|||||||
if __debug__:
|
if __debug__:
|
||||||
print "file", self.filename, "with hash", self.sha512, "exists"
|
print "file", self.filename, "with hash", self.sha512, "exists"
|
||||||
return self.sha512, exif
|
return self.sha512, exif
|
||||||
|
|
||||||
if 'JPEGThumbnail' in exif:
|
if 'JPEGThumbnail' in exif:
|
||||||
if __debug__:
|
if __debug__:
|
||||||
print self.filename, "exif thumb"
|
print self.filename, "exif thumb"
|
||||||
@@ -79,15 +79,15 @@ class Thumbnail(object):
|
|||||||
thumb_file = open(self.thumbnail_path, 'wb')
|
thumb_file = open(self.thumbnail_path, 'wb')
|
||||||
thumb_file.write(exif_thumbnail)
|
thumb_file.write(exif_thumbnail)
|
||||||
thumb_file.close()
|
thumb_file.close()
|
||||||
|
|
||||||
if 'Image Orientation' in exif:
|
if 'Image Orientation' in exif:
|
||||||
orient = exif['Image Orientation'].values[0]
|
orient = exif['Image Orientation'].values[0]
|
||||||
if orient > 1 and orient in orientations:
|
if orient > 1 and orient in orientations:
|
||||||
temp_image_path = mkstemp()[1]
|
temp_image_path = mkstemp()[1]
|
||||||
|
|
||||||
thumb_image = Image.open(self.thumbnail_path)
|
thumb_image = Image.open(self.thumbnail_path)
|
||||||
tmp_thumb_img = thumb_image.transpose(orientations[orient])
|
tmp_thumb_img = thumb_image.transpose(orientations[orient])
|
||||||
|
|
||||||
if orient in flips:
|
if orient in flips:
|
||||||
tmp_thumb_img = tmp_thumb_img.transpose(flips[orient])
|
tmp_thumb_img = tmp_thumb_img.transpose(flips[orient])
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,8 @@ class ImageView(object):
|
|||||||
image = gtk.Image()
|
image = gtk.Image()
|
||||||
image.set_from_file(image_filename)
|
image.set_from_file(image_filename)
|
||||||
|
|
||||||
pixbuf = image.get_pixbuf()
|
pic_width = image.size_request()[0] + 23
|
||||||
pic_width = pixbuf.get_width() + 23
|
pic_height = image.size_request()[1] + 23
|
||||||
pic_height = pixbuf.get_height() + 23
|
|
||||||
|
|
||||||
screen_width = gtk.gdk.screen_width()
|
screen_width = gtk.gdk.screen_width()
|
||||||
screen_height = gtk.gdk.screen_height()
|
screen_height = gtk.gdk.screen_height()
|
||||||
|
|||||||
Reference in New Issue
Block a user