1
0
mirror of https://github.com/gryf/pygtktalog.git synced 2025-12-17 11:30:19 +01:00
Files
pygtktalog/pygtktalog/models/main.py
2010-05-02 19:24:04 +02:00

231 lines
7.4 KiB
Python

"""
Project: pyGTKtalog
Description: Model for main application
Type: core
Author: Roman 'gryf' Dobosz, gryf73@gmail.com
Created: 2009-05-02
"""
import os
import bz2
from string import printable
from tempfile import mkstemp
import gtk
import gobject
from gtkmvc import ModelMT
from pygtktalog.dbobjects import File, Exif, Group, Gthumb
from pygtktalog.dbobjects import Image, Tag, Thumbnail
from pygtktalog.dbcommon import connect, Meta, Session
from pygtktalog.logger import get_logger
LOG = get_logger("main model")
class MainModel(ModelMT):
"""
Main model for application.
It is responsible for communicate with database objects and I/O
operations.
"""
status_bar_message = _("Idle")
current_disc = None
__observables__ = ("status_bar_message", "current_disc")
def __init__(self, filename=None):
"""
Initialization. Make some nice defaults.
Arguments:
filename - String that indicates optionally compressed with bzip2
file containing sqlite3 database.
"""
ModelMT.__init__(self)
# Opened/saved database location in filesystem. Could be compressed.
self.cat_fname = filename
# Temporary (usually in /tmp) working database.
self.tmp_filename = None
# Flag indicates, that db was compressed
# TODO: make it depend on configuration
self.compressed = False
self.db_unsaved = False
self.discs = gtk.TreeStore(gobject.TYPE_INT,
gobject.TYPE_STRING,
str,
gobject.TYPE_INT,
gobject.TYPE_PYOBJECT)
if self.cat_fname:
self.open(self.cat_fname)
def open(self, filename):
"""
Open catalog file and read db
Arguments:
@filename - see MainModel __init__ docstring.
Returns: Bool - true for success, false otherwise.
"""
LOG.debug("filename: '%s'", filename)
self.unsaved_project = False
if not os.path.exists(filename):
LOG.warn("db file '%s' doesn't exist.", filename)
return False
self.cat_fname = filename
if self._open_or_decompress():
return self._populate_discs_from_db()
else:
return False
def new(self):
"""
Create new catalog
"""
self._cleanup_and_create_temp_db_file()
def cleanup(self):
"""
Remove temporary directory tree from filesystem
"""
if self.tmp_filename is None:
return
try:
os.unlink(self.tmp_filename)
LOG.debug("file %s succesfully deleted", self.tmp_filename)
except OSError:
LOG.exception("temporary db file doesn't exists!")
except TypeError:
# TODO: file not exist - create? print error message?
LOG.exception("temporary db file doesn't exists!")
def _create_empty_db(self):
"""
Create new DB
"""
self._cleanup_and_create_temp_db_file()
def _examine_file(self, filename):
"""
Try to recognize file.
Arguments:
@filename - String with full path to file to examine
Returns: 'sql', 'bz2' or None for file sqlite, compressed with bzip2
or other respectively
"""
try:
head_of_file = open(filename).read(15)
LOG.debug("head of file: %s", filter(lambda x: x in printable,
head_of_file))
except IOError:
LOG.exception("Error opening file '%s'!", filename)
self.cleanup()
self.cat_fname = None
self.tmp_filename = None
return None
if head_of_file == "SQLite format 3":
LOG.debug("File format: uncompressed sqlite")
return 'sql'
elif head_of_file[0:10] == "BZh91AY&SY":
LOG.debug("File format: bzip2")
return 'bz2'
else:
return None
def _open_or_decompress(self):
"""
Try to open file, which user thinks is our catalog file.
Returns: Bool - true for success, false otherwise
"""
filename = os.path.abspath(self.cat_fname)
LOG.info("catalog file: %s", filename)
self._cleanup_and_create_temp_db_file()
LOG.debug("tmp database file: %s", str(self.tmp_filename))
examine = self._examine_file(filename)
if examine == "sql":
db_tmp = open(self.tmp_filename, "wb")
db_tmp.write(open(filename).read())
db_tmp.close()
elif examine == "bz2":
open_file = bz2.BZ2File(filename)
try:
db_tmp = open(self.tmp_filename, "w")
db_tmp.write(open_file.read())
db_tmp.close()
open_file.close()
except IOError:
self.cleanup()
self.filename = None
self.internal_dirname = None
LOG.exception("File is probably not a bz2!")
return False
if self._examine_file(self.tmp_filename) is not 'sql':
LOG.error("Error opening file '%s' - not a catalog file!",
self.tmp_filename)
self.cleanup()
self.cat_fname = None
self.tmp_filename = None
return False
else:
LOG.error("Error opening file '%s' - not a catalog file!",
self.tmp_filename)
self.cleanup()
self.filename = None
self.internal_dirname = None
return False
connect(os.path.abspath(self.tmp_filename))
return True
def _cleanup_and_create_temp_db_file(self):
self.cleanup()
fd, self.tmp_filename = mkstemp()
# close file descriptor, otherwise it can be source of app crash!
# http://www.logilab.org/blogentry/17873
os.close(fd)
def _populate_discs_from_db(self):
"""
Read objects from database, fill TreeStore model with discs
information
"""
session = Session()
dirs = session.query(File).filter(File.type == 1)
dirs = dirs.order_by(File.filename).all()
def get_children(parent_id=1, iterator=None):
"""
Get all children of the selected parent.
Arguments:
@parent_id - integer with id of the parent (from db)
@iterator - TODO
"""
for fileob in dirs:
if fileob.parent_id == parent_id:
myiter = self.discs.insert_before(iterator, None)
self.discs.set_value(myiter, 0, fileob.id)
self.discs.set_value(myiter, 1, fileob.filename)
if iterator is None:
self.discs.set_value(myiter, 2, gtk.STOCK_CDROM)
else:
self.discs.set_value(myiter, 2, gtk.STOCK_DIRECTORY)
self.discs.set_value(myiter, 3, fileob.parent_id)
self.discs.set_value(myiter, 4, fileob)
get_children(fileob.id, myiter)
return
get_children()
session.close()
return True
def get_root_entries(self, id):
LOG.debug("not implemented!, get_root_entries, id: %s", str(id))