mirror of
https://github.com/gryf/pygtktalog.git
synced 2025-12-18 20:10:24 +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
|
||||
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
|
||||
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.
|
||||
|
||||
FEATURES
|
||||
========
|
||||
|
||||
- scan for files in selected media
|
||||
- get/generate thumbnails from exif and other images
|
||||
- most important exif tags
|
||||
- get/generate thumbnails from EXIF and other images
|
||||
- most important EXIF tags
|
||||
- add/edit description and notes
|
||||
- fetch comments for images made in gThumb <http://gthumb.sourceforge.net>
|
||||
- add/remove unlimited images to any file or directory
|
||||
@@ -30,19 +30,20 @@ pyGTKtalog is written in python with following dependencies:
|
||||
|
||||
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
|
||||
Cavada and EXIF module by Gene Cash (slightly updatetd to EXIF 2.2 by me) which
|
||||
are included in sources.
|
||||
Additional pyGTKtalog uses pygtkmvc <http://pygtkmvc.sourceforge.net> by
|
||||
Roberto Cavada and EXIF module by Gene Cash (slightly updatetd to EXIF 2.2 by
|
||||
me) which are included in sources.
|
||||
|
||||
pyGTKtalog extensivly uses external programs in unix spirit, however there is
|
||||
small possibility of using it Windows (probably with limitations) and quite big
|
||||
possiblity to run it on other sofisticated unix-like systems (i.e.
|
||||
pyGTKtalog extensively uses external programs in unix spirit, however there is
|
||||
small possibility of using it Windows (probably with limitations) and quite
|
||||
big possibility to run it on other sophisticated unix-like systems (i.e.
|
||||
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
|
||||
directory to pyGTKtalog and simply run:
|
||||
@@ -80,11 +81,12 @@ For version 2.0:
|
||||
- command line support: query, adding media to collection etc
|
||||
- internationalization
|
||||
- export to XLS
|
||||
- user definied group of tags (represented by color in cloud tag)
|
||||
- hiding specified files - configurable, like dot prefixed, cfg and manualy
|
||||
selected
|
||||
- user defined group of tags (represented by color in cloud tag)
|
||||
- hiding specified files - configurable, like dot prefixed, config files and
|
||||
manually selected
|
||||
- tests
|
||||
- warning about existing image in media directory
|
||||
|
||||
Removed:
|
||||
- filetypes handling (movies, images, archives, documents etc). Now it have
|
||||
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>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ __version__ = "1.0.1"
|
||||
LICENCE = ''
|
||||
import os.path
|
||||
from os import popen
|
||||
from utils import deviceHelper
|
||||
from utils import device_helper
|
||||
from gtkmvc import Controller
|
||||
|
||||
from c_config import ConfigController
|
||||
@@ -526,9 +526,9 @@ class MainController(Controller):
|
||||
|
||||
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'])
|
||||
mount = device_helper.volmount(self.model.config.confd['cd'])
|
||||
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:
|
||||
label = Dialogs.InputDiskLabel(guessed_label).run()
|
||||
if label:
|
||||
@@ -541,7 +541,7 @@ class MainController(Controller):
|
||||
self.model.unsaved_project = True
|
||||
self.__set_title(filepath=self.model.filename, modified=True)
|
||||
else:
|
||||
deviceHelper.volumount(self.model.config.confd['cd'])
|
||||
device_helper.volumount(self.model.config.confd['cd'])
|
||||
return True
|
||||
else:
|
||||
Dialogs.Wrn("Error mounting device - pyGTKtalog",
|
||||
@@ -1373,7 +1373,7 @@ class MainController(Controller):
|
||||
# umount/eject cd
|
||||
ejectapp = self.model.config.confd['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'])
|
||||
if msg != 'ok':
|
||||
Dialogs.Wrn("error ejecting device - pyGTKtalog",
|
||||
@@ -1381,7 +1381,7 @@ class MainController(Controller):
|
||||
self.model.config.confd['cd'],
|
||||
"Last eject message:\n%s" % msg)
|
||||
else:
|
||||
msg = deviceHelper.volumount(self.model.config.confd['cd'])
|
||||
msg = device_helper.volumount(self.model.config.confd['cd'])
|
||||
if msg != 'ok':
|
||||
Dialogs.Wrn("error unmounting device - pyGTKtalog",
|
||||
"Cannot unmount device pointed to %s" %
|
||||
|
||||
@@ -34,7 +34,11 @@ import gobject
|
||||
|
||||
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
|
||||
|
||||
import threading as _threading
|
||||
@@ -50,6 +54,20 @@ from utils.gthumb import GthumbCommentParser
|
||||
|
||||
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):
|
||||
"""Create, load, save, manipulate db file which is container for data"""
|
||||
|
||||
@@ -169,7 +187,6 @@ class MainModel(ModelMT):
|
||||
else:
|
||||
os.mkdir(path)
|
||||
|
||||
|
||||
if os.path.exists(imgpath):
|
||||
if not os.path.isdir(imgpath):
|
||||
print "Warning:",
|
||||
@@ -360,8 +377,6 @@ class MainModel(ModelMT):
|
||||
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
|
||||
@@ -556,8 +571,6 @@ class MainModel(ModelMT):
|
||||
try:
|
||||
os.unlink(self.db_tmp_path)
|
||||
except:
|
||||
if __debug__:
|
||||
print "Exception in removing temporary db file!"
|
||||
pass
|
||||
|
||||
#if self.internal_dirname != None:
|
||||
@@ -573,6 +586,7 @@ class MainModel(ModelMT):
|
||||
self.filename = None
|
||||
self.__create_temporary_db_file()
|
||||
self.__connect_to_db()
|
||||
self._set_image_path()
|
||||
self.__create_database()
|
||||
self.__clear_trees()
|
||||
self.clear_search_tree()
|
||||
@@ -592,6 +606,14 @@ class MainModel(ModelMT):
|
||||
return
|
||||
|
||||
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
|
||||
val, err = self.__compress_and_save()
|
||||
if not val:
|
||||
@@ -683,6 +705,7 @@ class MainModel(ModelMT):
|
||||
#tar.close()
|
||||
|
||||
self.__connect_to_db()
|
||||
self._set_image_path()
|
||||
self.__fetch_db_into_treestore()
|
||||
self.config.add_recent(filename)
|
||||
self.get_tags()
|
||||
@@ -758,8 +781,9 @@ class MainModel(ModelMT):
|
||||
self.search_list.set_value(myiter, 3,
|
||||
self.__get_file_path(row[0]))
|
||||
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, 7, gtk.STOCK_DIRECTORY)
|
||||
|
||||
@@ -794,8 +818,7 @@ class MainModel(ModelMT):
|
||||
self.search_list.set_value(myiter, 3,
|
||||
self.__get_file_path(row[0]))
|
||||
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, row[4])
|
||||
if row[4] == self.FIL:
|
||||
self.search_list.set_value(myiter, 7, gtk.STOCK_FILE)
|
||||
@@ -825,9 +848,7 @@ class MainModel(ModelMT):
|
||||
|
||||
#self.__fetch_db_into_treestore()
|
||||
self.unsaved_project = True
|
||||
else:
|
||||
if __debug__:
|
||||
print "m_main.py: rename(): no label defined"
|
||||
|
||||
return
|
||||
|
||||
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, 3, self.__get_file_path(row[0]))
|
||||
self.files_list.set_value(myiter, 4, row[2])
|
||||
self.files_list.set_value(myiter, 5,
|
||||
datetime.fromtimestamp(row[3]))
|
||||
self.files_list.set_value(myiter, 5, mangle_date(row[3]))
|
||||
self.files_list.set_value(myiter, 6, 1)
|
||||
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, 3, self.__get_file_path(row[0]))
|
||||
self.files_list.set_value(myiter, 4, row[2])
|
||||
self.files_list.set_value(myiter, 5,
|
||||
datetime.fromtimestamp(row[3]))
|
||||
self.files_list.set_value(myiter, 5, mangle_date(row[3]))
|
||||
self.files_list.set_value(myiter, 6, row[4])
|
||||
if row[4] == self.FIL:
|
||||
self.files_list.set_value(myiter, 7, gtk.STOCK_FILE)
|
||||
@@ -954,11 +973,10 @@ class MainModel(ModelMT):
|
||||
res = self.db_cursor.fetchone()
|
||||
if res:
|
||||
retval['fileinfo'] = {'id': file_id,
|
||||
'date': datetime.fromtimestamp(res[1]),
|
||||
'size': res[2], 'type': res[3]}
|
||||
|
||||
retval['fileinfo']['disc'] = self.__get_file_root(file_id)
|
||||
|
||||
'size': res[2],
|
||||
'type': res[3],
|
||||
'date': mangle_date(res[1]),
|
||||
'disc': self.__get_file_root(file_id)}
|
||||
retval['filename'] = res[0]
|
||||
|
||||
if res[4]:
|
||||
@@ -969,9 +987,13 @@ class MainModel(ModelMT):
|
||||
|
||||
if res[6]:
|
||||
thumbfile = os.path.join(self.image_path, res[6] + "_t")
|
||||
thumb2 = os.path.join(self.image_path, res[6])
|
||||
if os.path.exists(thumbfile):
|
||||
pix = gtk.gdk.pixbuf_new_from_file(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
|
||||
WHERE file_id = ?"""
|
||||
@@ -981,8 +1003,13 @@ class MainModel(ModelMT):
|
||||
self.images_store = gtk.ListStore(gobject.TYPE_INT, gtk.gdk.Pixbuf)
|
||||
for im_id, filename in res:
|
||||
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):
|
||||
pix = gtk.gdk.pixbuf_new_from_file(thumbfile)
|
||||
elif os.path.exists(thumb2):
|
||||
pix = gtk.gdk.pixbuf_new_from_file(thumb2)
|
||||
else:
|
||||
pix = gtk.gdk.pixbuf_new_from_inline(len(no_thumb_img),
|
||||
no_thumb_img, False)
|
||||
@@ -1083,13 +1110,10 @@ class MainModel(ModelMT):
|
||||
sql = """DELETE FROM tags_files WHERE file_id = ?"""
|
||||
db_cursor.executemany(sql, generator())
|
||||
|
||||
if __debug__:
|
||||
print "m_main.py: delete(): deleting:", fids
|
||||
|
||||
if len(fids) == 1:
|
||||
arg = "(%d)" % fids[0]
|
||||
else:
|
||||
arg = str(tuple(fids))
|
||||
#if len(fids) == 1:
|
||||
# arg = "(%d)" % fids[0]
|
||||
#else:
|
||||
# arg = str(tuple(fids))
|
||||
|
||||
# remove thumbnails
|
||||
#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])
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
path = os.path.join('/home/gryf/.pygtktalog/imgs2/', res[0])
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
return None
|
||||
|
||||
def update_desc_and_note(self, file_id, desc='', note=''):
|
||||
"""update note and description"""
|
||||
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()
|
||||
return
|
||||
|
||||
@@ -1378,6 +1405,34 @@ class MainModel(ModelMT):
|
||||
self.db_cursor = self.db_connection.cursor()
|
||||
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):
|
||||
"""close db conection"""
|
||||
|
||||
@@ -1407,8 +1462,6 @@ class MainModel(ModelMT):
|
||||
output_file = bz2.BZ2File(self.filename, "w")
|
||||
else:
|
||||
output_file = open(self.filename, "w")
|
||||
if __debug__:
|
||||
print "m_main.py: __compress_and_save(): tar open successed"
|
||||
|
||||
except IOError, (errno, strerror):
|
||||
return False, strerror
|
||||
@@ -1597,8 +1650,6 @@ class MainModel(ModelMT):
|
||||
for root, dirs, files in os.walk(self.path):
|
||||
count += len(files)
|
||||
except:
|
||||
if __debug__:
|
||||
print 'm_main.py: os.walk in %s' % self.path
|
||||
pass
|
||||
|
||||
if count > 0:
|
||||
@@ -1630,14 +1681,14 @@ class MainModel(ModelMT):
|
||||
files(parent_id, filename, filepath, date,
|
||||
size, type, source)
|
||||
VALUES(?,?,?,?,?,?,?)"""
|
||||
db_cursor.execute(sql, (parent_id, name, path, date, size,
|
||||
filetype, self.source))
|
||||
db_cursor.execute(sql, (parent_id, name, path.decode("utf-8"),
|
||||
date, size, filetype, self.source))
|
||||
else:
|
||||
self.discs_tree.set_value(myit, 2, gtk.STOCK_DIRECTORY)
|
||||
sql = """INSERT INTO
|
||||
files(parent_id, filename, filepath, date, size, type)
|
||||
VALUES(?,?,?,?,?,?)"""
|
||||
db_cursor.execute(sql, (parent_id, name, path,
|
||||
db_cursor.execute(sql, (parent_id, name, path.decode("utf-8"),
|
||||
date, size, filetype))
|
||||
|
||||
sql = """SELECT seq FROM sqlite_sequence WHERE name='files'"""
|
||||
@@ -1645,14 +1696,13 @@ class MainModel(ModelMT):
|
||||
currentid = db_cursor.fetchone()[0]
|
||||
|
||||
self.discs_tree.set_value(myit, 0, currentid)
|
||||
|
||||
self.discs_tree.set_value(myit, 1, name)
|
||||
self.discs_tree.set_value(myit, 3, parent_id)
|
||||
|
||||
try:
|
||||
root, dirs, files = os.walk(path).next()
|
||||
except:
|
||||
if __debug__:
|
||||
print "m_main.py: cannot access ", path
|
||||
#return -1
|
||||
return 0
|
||||
|
||||
@@ -1721,8 +1771,12 @@ class MainModel(ModelMT):
|
||||
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))
|
||||
try:
|
||||
db_cursor.execute(sql, (currentid, unicode(j),
|
||||
unicode(current_file),
|
||||
st_mtime, st_size, self.FIL))
|
||||
except:
|
||||
raise
|
||||
|
||||
if self.count % 32 == 0:
|
||||
update = True
|
||||
@@ -1812,7 +1866,10 @@ class MainModel(ModelMT):
|
||||
|
||||
sql = """UPDATE files SET description=?
|
||||
WHERE id=?"""
|
||||
db_cursor.execute(sql, (desc, fileid))
|
||||
db_cursor.execute(sql,
|
||||
(unicode(desc.decode("utf8",
|
||||
"ignore")),
|
||||
fileid))
|
||||
|
||||
### end of scan
|
||||
if update:
|
||||
@@ -1827,18 +1884,11 @@ class MainModel(ModelMT):
|
||||
return _size
|
||||
|
||||
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)
|
||||
db_cursor.close()
|
||||
db_connection.rollback()
|
||||
else:
|
||||
if __debug__:
|
||||
print "m_main.py: __scan() __recurse() goes without interrupt"
|
||||
if self.currentid:
|
||||
if __debug__:
|
||||
print "m_main.py: __scan() removing old branch"
|
||||
self.statusmsg = "Removing old branch..."
|
||||
self.delete(self.currentid, db_cursor, db_connection)
|
||||
|
||||
@@ -1847,8 +1897,6 @@ class MainModel(ModelMT):
|
||||
db_cursor.close()
|
||||
db_connection.commit()
|
||||
db_connection.close()
|
||||
if __debug__:
|
||||
print "m_main.py: __scan() time: ", (datetime.now() - timestamp)
|
||||
|
||||
self.busy = False
|
||||
|
||||
@@ -1903,13 +1951,8 @@ class MainModel(ModelMT):
|
||||
gtk.STOCK_DIRECTORY)
|
||||
return
|
||||
|
||||
if __debug__:
|
||||
start_date = datetime.now()
|
||||
# launch scanning.
|
||||
get_children()
|
||||
if __debug__:
|
||||
print "m_main.py: __fetch_db_into_treestore()",
|
||||
print "tree generation time: ", (datetime.now() - start_date)
|
||||
db_connection.close()
|
||||
return
|
||||
|
||||
@@ -1944,13 +1987,8 @@ class MainModel(ModelMT):
|
||||
gtk.STOCK_DIRECTORY)
|
||||
return
|
||||
|
||||
if __debug__:
|
||||
start_date = datetime.now()
|
||||
# launch scanning.
|
||||
get_children()
|
||||
if __debug__:
|
||||
print "m_main.py: __append_added_volume() tree generation time: ",
|
||||
print datetime.now() - start_date
|
||||
db_connection.close()
|
||||
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 hashlib import sha512
|
||||
|
||||
import Image
|
||||
from PIL import Image
|
||||
|
||||
|
||||
class Img(object):
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ from os import path
|
||||
import sys
|
||||
|
||||
from utils import EXIF
|
||||
import Image
|
||||
from PIL import Image
|
||||
|
||||
class Thumbnail(object):
|
||||
"""Class for generate/extract thumbnail from image file"""
|
||||
@@ -56,7 +56,7 @@ class Thumbnail(object):
|
||||
# rotated 90 CW
|
||||
8: Image.ROTATE_90} # Rotated 90 CCW
|
||||
flips = {7: Image.FLIP_LEFT_RIGHT, 5: Image.FLIP_LEFT_RIGHT}
|
||||
|
||||
|
||||
image_file = open(self.filename, 'rb')
|
||||
try:
|
||||
exif = EXIF.process_file(image_file)
|
||||
@@ -71,7 +71,7 @@ class Thumbnail(object):
|
||||
if __debug__:
|
||||
print "file", self.filename, "with hash", self.sha512, "exists"
|
||||
return self.sha512, exif
|
||||
|
||||
|
||||
if 'JPEGThumbnail' in exif:
|
||||
if __debug__:
|
||||
print self.filename, "exif thumb"
|
||||
@@ -79,15 +79,15 @@ class Thumbnail(object):
|
||||
thumb_file = open(self.thumbnail_path, 'wb')
|
||||
thumb_file.write(exif_thumbnail)
|
||||
thumb_file.close()
|
||||
|
||||
|
||||
if 'Image Orientation' in exif:
|
||||
orient = exif['Image Orientation'].values[0]
|
||||
if orient > 1 and orient in orientations:
|
||||
temp_image_path = mkstemp()[1]
|
||||
|
||||
|
||||
thumb_image = Image.open(self.thumbnail_path)
|
||||
tmp_thumb_img = thumb_image.transpose(orientations[orient])
|
||||
|
||||
|
||||
if orient in flips:
|
||||
tmp_thumb_img = tmp_thumb_img.transpose(flips[orient])
|
||||
|
||||
|
||||
@@ -34,9 +34,8 @@ class ImageView(object):
|
||||
image = gtk.Image()
|
||||
image.set_from_file(image_filename)
|
||||
|
||||
pixbuf = image.get_pixbuf()
|
||||
pic_width = pixbuf.get_width() + 23
|
||||
pic_height = pixbuf.get_height() + 23
|
||||
pic_width = image.size_request()[0] + 23
|
||||
pic_height = image.size_request()[1] + 23
|
||||
|
||||
screen_width = gtk.gdk.screen_width()
|
||||
screen_height = gtk.gdk.screen_height()
|
||||
|
||||
Reference in New Issue
Block a user