mirror of
https://github.com/gryf/pygtktalog.git
synced 2025-12-18 12:00:21 +01:00
Readme update, some cleanup
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
@@ -7,12 +7,33 @@ gwhere <http://www.gwhere.org/home.php3>. There is no coincidence in name of
|
|||||||
application, because it's meant 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.
|
||||||
|
|
||||||
|
WARNING!
|
||||||
|
========
|
||||||
|
|
||||||
|
This version is mostly outdated, full of bugs, and may eat your data! First
|
||||||
|
usable version (this is what you are looking at right now) was completed around
|
||||||
|
2009 year, but implementation was done much earlier. During that time GTK2 was
|
||||||
|
changed significantly several times, because of that couple of pyGTKtalog
|
||||||
|
functionalities goes bad.
|
||||||
|
|
||||||
|
The reason for keeping this branch is for history and for GUI to the new engine
|
||||||
|
which was rewritten couple of years ago and have only cli tool to manipulate
|
||||||
|
DBs.
|
||||||
|
|
||||||
|
In other words - pyGTKtalog version on this branch is safe for **view only**
|
||||||
|
your catalog database, while it may corrupt database or other files while trying
|
||||||
|
to create/update your databases in any way.
|
||||||
|
|
||||||
|
You have been warned.
|
||||||
|
|
||||||
|
The rest of the README file:
|
||||||
|
|
||||||
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
|
- stores selected 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,16 +51,16 @@ pyGTKtalog is written in python with following dependencies:
|
|||||||
|
|
||||||
Optional modules:
|
Optional modules:
|
||||||
|
|
||||||
- PIL <http://www.pythonware.com/products/pil/index.htm> for image
|
- PIL <http://www.pythonware.com/products/pil/index.htm> for image
|
||||||
manipulation
|
manipulation
|
||||||
|
|
||||||
Additional pyGTKtalog uses pygtkmvc <http://pygtkmvc.sourceforge.net> by
|
Additional pyGTKtalog uses pygtkmvc <http://pygtkmvc.sourceforge.net> by
|
||||||
Roberto Cavada and EXIF module by Gene Cash (slightly updatetd to EXIF 2.2 by
|
Roberto Cavada and EXIF module by Gene Cash (slightly updatetd to EXIF 2.2 by
|
||||||
me) which are included in sources.
|
me) which are included in sources.
|
||||||
|
|
||||||
pyGTKtalog extensively 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
|
small possibility of using it Windows (probably with limitations) and quite
|
||||||
big possibility to run it on other sophisticated 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).
|
||||||
|
|
||||||
INSTALLATION
|
INSTALLATION
|
||||||
@@ -60,7 +81,7 @@ you have to do is:
|
|||||||
- then modify pyGTKtalog line 6 to match right pygtktalog.py directory
|
- then modify pyGTKtalog line 6 to match right pygtktalog.py directory
|
||||||
|
|
||||||
Then, just run pyGTKtalog script.
|
Then, just run pyGTKtalog script.
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
@@ -124,7 +145,8 @@ design prevent from deleting any file from media directory (placed in
|
|||||||
~/.pygtktalog/images). Functionality for exporting images and corresponding db
|
~/.pygtktalog/images). Functionality for exporting images and corresponding db
|
||||||
file is planned.
|
file is planned.
|
||||||
|
|
||||||
BUGS
|
LICENSE
|
||||||
====
|
=======
|
||||||
|
|
||||||
All bugs please report to Roman 'gryf' Dobosz <roman.dobosz@gmail.com>
|
This work is licensed under the terms of the GNU GPL, version 3. See the LICENCE
|
||||||
|
file in top-level directory.
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import tarfile
|
|
||||||
|
|
||||||
try:
|
|
||||||
import sqlite3 as sqlite
|
|
||||||
except ImportError:
|
|
||||||
from pysqlite2 import dbapi2 as sqlite
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class OldModel(object):
|
|
||||||
"""Create, load, save, manipulate db file which is container for data"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""initialize"""
|
|
||||||
self.db_cursor = None
|
|
||||||
self.db_connection = None
|
|
||||||
self.internal_dirname = None
|
|
||||||
|
|
||||||
def cleanup(self):
|
|
||||||
"""remove temporary directory tree from filesystem"""
|
|
||||||
self.__close_db_connection()
|
|
||||||
if self.internal_dirname != None:
|
|
||||||
try:
|
|
||||||
shutil.rmtree(self.internal_dirname)
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
return
|
|
||||||
|
|
||||||
def open(self, filename=None):
|
|
||||||
"""try to open db file"""
|
|
||||||
self.__create_internal_dirname()
|
|
||||||
self.filename = filename
|
|
||||||
|
|
||||||
try:
|
|
||||||
tar = tarfile.open(filename, "r:gz")
|
|
||||||
except:
|
|
||||||
try:
|
|
||||||
tar = tarfile.open(filename, "r")
|
|
||||||
except:
|
|
||||||
self.internal_dirname = None
|
|
||||||
return False
|
|
||||||
|
|
||||||
os.chdir(self.internal_dirname)
|
|
||||||
try:
|
|
||||||
tar.extractall()
|
|
||||||
if __debug__:
|
|
||||||
print "OldModel 73: 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 "OldModel 103: open(): setting corrext owner,",
|
|
||||||
print "mtime etc"
|
|
||||||
tar.close()
|
|
||||||
self.__connect_to_db()
|
|
||||||
return True
|
|
||||||
|
|
||||||
# private class functions
|
|
||||||
def __connect_to_db(self):
|
|
||||||
"""initialize db connection and store it in class attributes"""
|
|
||||||
self.db_connection = sqlite.connect("%s" % \
|
|
||||||
(self.internal_dirname + '/db.sqlite'),
|
|
||||||
detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)
|
|
||||||
self.db_cursor = self.db_connection.cursor()
|
|
||||||
return
|
|
||||||
|
|
||||||
def __close_db_connection(self):
|
|
||||||
"""close db conection"""
|
|
||||||
if self.db_cursor != None:
|
|
||||||
self.db_cursor.close()
|
|
||||||
self.db_cursor = None
|
|
||||||
if self.db_connection != None:
|
|
||||||
self.db_connection.close()
|
|
||||||
self.db_connection = None
|
|
||||||
return
|
|
||||||
|
|
||||||
def __create_internal_dirname(self):
|
|
||||||
"""create temporary directory for working thumb/image files and
|
|
||||||
database"""
|
|
||||||
# TODO: change this stupid rutine into tempfile mkdtemp method
|
|
||||||
self.cleanup()
|
|
||||||
self.internal_dirname = "/tmp/pygtktalog%d" % \
|
|
||||||
datetime.now().microsecond
|
|
||||||
try:
|
|
||||||
os.mkdir(self.internal_dirname)
|
|
||||||
except IOError, (errno, strerror):
|
|
||||||
print "OldModel 138: __create_internal_dirname(): ", strerror
|
|
||||||
return
|
|
||||||
|
|
||||||
def setup_path():
|
|
||||||
"""Sets up the python include paths to include needed directories"""
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
from src.utils.globals import TOPDIR
|
|
||||||
sys.path = [os.path.join(TOPDIR, "src")] + sys.path
|
|
||||||
return
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
"""run the stuff"""
|
|
||||||
if len(sys.argv) != 3:
|
|
||||||
print "Usage: %s old_katalog_filename new_katalog_filename" % \
|
|
||||||
sys.argv[0]
|
|
||||||
print "All available pictures will be exported aswell, however",
|
|
||||||
print "thumbnails without"
|
|
||||||
print "images will be lost."
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
# Directory from where pygtkatalog was invoced. We need it for calculate
|
|
||||||
# path for argument (catalog file)
|
|
||||||
execution_dir = os.path.abspath(os.path.curdir)
|
|
||||||
|
|
||||||
# Directory, where this files lies. We need it to setup private source
|
|
||||||
# paths
|
|
||||||
libraries_dir = os.path.dirname(__file__)
|
|
||||||
os.chdir(libraries_dir)
|
|
||||||
|
|
||||||
setup_path()
|
|
||||||
|
|
||||||
from shutil import copy
|
|
||||||
|
|
||||||
from utils.img import Img
|
|
||||||
from models.m_main import MainModel as NewModel
|
|
||||||
|
|
||||||
model = OldModel()
|
|
||||||
new_model = NewModel()
|
|
||||||
if not model.open(os.path.join(execution_dir, sys.argv[1])):
|
|
||||||
print "cannot open katalog in 1.0RC1 format"
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
model.db_cursor.execute("""create table
|
|
||||||
images2(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
file_id INTEGER,
|
|
||||||
filename TEXT);""")
|
|
||||||
|
|
||||||
model.db_cursor.execute("delete from thumbnails")
|
|
||||||
result = model.db_cursor.execute("select file_id, filename from images")
|
|
||||||
# (id, filename)
|
|
||||||
# (4921, u'images/13/39.jpg')
|
|
||||||
for row in result.fetchall():
|
|
||||||
if row[1] and os.path.exists(os.path.join(model.internal_dirname,
|
|
||||||
row[1])):
|
|
||||||
im = Img(os.path.join(model.internal_dirname, row[1]),
|
|
||||||
new_model.image_path)
|
|
||||||
image = im.save()
|
|
||||||
sql = "insert into images2(file_id, filename) values (?, ?)"
|
|
||||||
model.db_cursor.execute(sql, (row[0], image))
|
|
||||||
|
|
||||||
model.db_cursor.execute("select id from thumbnails where file_id=?", (row[0], ))
|
|
||||||
thumb = model.db_cursor.fetchone()
|
|
||||||
if not (thumb and thumb[0]):
|
|
||||||
sql = "insert into thumbnails(file_id, filename) values (?, ?)"
|
|
||||||
model.db_cursor.execute(sql, (row[0], image))
|
|
||||||
|
|
||||||
|
|
||||||
model.db_connection.commit()
|
|
||||||
model.db_cursor.execute("drop table images")
|
|
||||||
model.db_cursor.execute("alter table images2 rename to images")
|
|
||||||
|
|
||||||
copy(os.path.join(model.internal_dirname, 'db.sqlite'),
|
|
||||||
os.path.join(execution_dir, sys.argv[2]))
|
|
||||||
# remove stuff
|
|
||||||
model.cleanup()
|
|
||||||
Reference in New Issue
Block a user