1
0
mirror of https://github.com/gryf/pygtktalog.git synced 2025-12-17 11:30:19 +01:00

Implementation of discs tree, added popup menu

This commit is contained in:
2010-05-02 11:14:54 +02:00
parent dbb01acd3f
commit 9769dfdb76
6 changed files with 160 additions and 74 deletions

15
README
View File

@@ -24,12 +24,15 @@ FEATURES
REQUIREMENTS REQUIREMENTS
------------ ------------
pyGTKtalog is written in python with following dependencies: pyGTKtalog was developed using python and following libraries:
* python 2.5 or higher (not tested on python 3000) * python 2.6
* `pygtk 2.12 <http://www.pygtk.org>`_ or higher * `pygtk 2.16 <http://www.pygtk.org>`_
* `pygtkmvc 1.99 <http://apps.sourceforge.net/trac/pygtkmvc/wiki>`_ or higher * `pygtkmvc 1.99 <http://apps.sourceforge.net/trac/pygtkmvc/wiki>`_
* `sqlalchemy 0.5.5 <http://www.sqlalchemy.org>`_ or higher * `sqlalchemy 0.6 <http://www.sqlalchemy.org>`_
It may work on other (lower) version of libraries, and it should work with
higher versions of libraries.
Optional modules Optional modules
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
@@ -72,7 +75,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
---- ----

View File

@@ -1,6 +1,6 @@
""" """
Project: pyGTKtalog Project: pyGTKtalog
Description: Initialize for main module - i18n and so. Description: Initialization for main module - i18n and so.
Type: core Type: core
Author: Roman 'gryf' Dobosz, gryf73@gmail.com Author: Roman 'gryf' Dobosz, gryf73@gmail.com
Created: 2009-05-05 Created: 2009-05-05

View File

@@ -15,7 +15,7 @@ from pygtktalog.logger import get_logger
# setup SQLAlchemy logging facility # setup SQLAlchemy logging facility
# TODO: Logger("sqlalchemy") # TODO: Logger("sqlalchemy")
# or maybe it will be better to separate sqlalchemy stuff from application # or maybe it will be better to separate sqlalchemy stuff from application
get_logger("sqlalchemy", 'INFO') #get_logger("sqlalchemy", 'INFO')
# Prepare SQLAlchemy objects # Prepare SQLAlchemy objects
Meta = MetaData() Meta = MetaData()

View File

@@ -40,10 +40,13 @@ def get_logger(module_name, level=None, to_file=False):
if to_file: if to_file:
log_handler = logging.FileHandler(path) log_handler = logging.FileHandler(path)
formatter = logging.Formatter("%(asctime)s %(filename)s:%(lineno) - %(name)s - %(levelname)s - %(message)s") formatter = logging.Formatter("%(asctime)s %(filename)s:%(lineno) - "
"%(name)s - %(levelname)s - "
"%(message)s")
else: else:
log_handler = logging.StreamHandler(sys.stderr) log_handler = logging.StreamHandler(sys.stderr)
formatter = logging.Formatter("%(name)s - %(filename)s:%(lineno)s - %(levelname)s - %(message)s") formatter = logging.Formatter("%(name)s - %(filename)s:%(lineno)s - "
"%(levelname)s - %(message)s")
log_handler.setFormatter(formatter) log_handler.setFormatter(formatter)
log.addHandler(log_handler) log.addHandler(log_handler)

View File

@@ -7,6 +7,7 @@
""" """
import os import os
import bz2 import bz2
from string import printable
from tempfile import mkstemp from tempfile import mkstemp
import gtk import gtk
@@ -22,17 +23,26 @@ LOG = get_logger("main model")
class MainModel(ModelMT): class MainModel(ModelMT):
"""
Main model for application.
It is responsible for communicate with database objects and I/O
operations.
"""
status_bar_message = _("Idle") status_bar_message = _("Idle")
current_disc = None current_disc = None
__observables__ = ("status_bar_message", "current_disc") __observables__ = ("status_bar_message", "current_disc")
def __init__(self, filename=None): def __init__(self, filename=None):
"""Initialization. Make some nice defaults.""" """
print "model" Initialization. Make some nice defaults.
Arguments:
filename - String that indicates optionally compressed with bzip2
file containing sqlite3 database.
"""
ModelMT.__init__(self) ModelMT.__init__(self)
# Opened/saved database location in filesystem. Could be compressed. # Opened/saved database location in filesystem. Could be compressed.
self.db_filename = filename self.cat_fname = filename
# Temporary (usually in /tmp) working database. # Temporary (usually in /tmp) working database.
self.tmp_filename = None self.tmp_filename = None
# Flag indicates, that db was compressed # Flag indicates, that db was compressed
@@ -41,45 +51,50 @@ class MainModel(ModelMT):
self.db_unsaved = False self.db_unsaved = False
self.discs = gtk.TreeStore(str, gobject.TYPE_STRING) self.discs = gtk.TreeStore(gobject.TYPE_INT,
gobject.TYPE_STRING,
str,
gobject.TYPE_INT)
# XXX remove this on production! if self.cat_fname:
myiter = self.discs.insert_before(None, None) self.open(self.cat_fname)
self.discs.set_value(myiter, 1, "bubu")
self.discs.set_value(myiter, 1, "foo")
self.discs.set_value(myiter, 1, "bar")
itr = self.discs.append(None, None) def open(self, filename):
self.discs.set_value(itr, 0, gtk.STOCK_DIRECTORY) """
self.discs.set_value(itr, 1, "foobar") Open catalog file and read db
for nr, name in enumerate(('foo', 'bar', 'baz')): Arguments:
self.discs.append(itr, (gtk.STOCK_FILE, "%s %d" % (name, nr))) @filename - see MainModel __init__ docstring.
Returns: Bool - true for success, false otherwise.
#self.open() """
LOG.debug("filename: '%s'", filename)
def open(self, filename=None):
self.unsaved_project = False self.unsaved_project = False
if filename is not None and not os.path.exists(filename): if not os.path.exists(filename):
LOG.warn("db file '%s' doesn't exist", filename) LOG.warn("db file '%s' doesn't exist.", filename)
return False return False
if filename: self.cat_fname = filename
self.db_filename = filename
if self.db_filename: if self._open_or_decompress():
return self.__open_or_decompress() return self._read_db()
else: else:
self.__create_empty_db() return False
return True
def new(self):
"""
Create new catalog
"""
self._cleanup_and_create_temp_db_file()
def cleanup(self): def cleanup(self):
"""remove temporary directory tree from filesystem""" """
Remove temporary directory tree from filesystem
"""
if self.tmp_filename is None: if self.tmp_filename is None:
return return
#import ipdb; ipdb.set_trace()
LOG.debug("cleanup()")
try: try:
os.unlink(self.tmp_filename) os.unlink(self.tmp_filename)
LOG.debug("file %s succesfully deleted", self.tmp_filename)
except OSError: except OSError:
LOG.exception("temporary db file doesn't exists!") LOG.exception("temporary db file doesn't exists!")
except TypeError: except TypeError:
@@ -87,32 +102,57 @@ class MainModel(ModelMT):
LOG.exception("temporary db file doesn't exists!") LOG.exception("temporary db file doesn't exists!")
def __create_empty_db(self): def _create_empty_db(self):
pass """
Create new DB
"""
self._cleanup_and_create_temp_db_file()
def __open_or_decompress(self): def _examine_file(self, filename):
filename = os.path.abspath(self.db_filename) """
LOG.info("database file: %s", 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
self.__cleanup_and_create_temp_db_file() 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)) LOG.debug("tmp database file: %s", str(self.tmp_filename))
try: examine = self._examine_file(filename)
test_file = open(filename).read(15) if examine == "sql":
LOG.debug("test_file: %s", test_file)
except IOError:
self.cleanup()
self.db_filename = None
self.tmp_filename = None
LOG.exception("Error opening file!")
return False
if test_file == "SQLite format 3":
db_tmp = open(self.tmp_filename, "wb") db_tmp = open(self.tmp_filename, "wb")
db_tmp.write(open(filename).read()) db_tmp.write(open(filename).read())
db_tmp.close() db_tmp.close()
LOG.debug("file format: sqlite") elif examine == "bz2":
elif test_file[0:10] == "BZh91AY&SY":
open_file = bz2.BZ2File(filename) open_file = bz2.BZ2File(filename)
try: try:
db_tmp = open(self.tmp_filename, "w") db_tmp = open(self.tmp_filename, "w")
@@ -120,27 +160,67 @@ class MainModel(ModelMT):
db_tmp.close() db_tmp.close()
open_file.close() open_file.close()
except IOError: except IOError:
# file is not bz2
self.cleanup() self.cleanup()
self.filename = None self.filename = None
self.internal_dirname = None self.internal_dirname = None
# TODO: add logger
LOG.exception("File is probably not a bz2!") LOG.exception("File is probably not a bz2!")
return False 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: else:
LOG.error("Error opening file '%s' - not a catalog file!",
self.tmp_filename)
self.cleanup()
self.filename = None self.filename = None
self.internal_dirname = None self.internal_dirname = None
return False return False
connect(os.path.abspath(self.tmp_filename)) connect(os.path.abspath(self.tmp_filename))
return True return True
def __cleanup_and_create_temp_db_file(self): def _cleanup_and_create_temp_db_file(self):
self.cleanup() self.cleanup()
fd, self.tmp_filename = mkstemp() fd, self.tmp_filename = mkstemp()
# close file descriptor, otherwise it can be source of app crash! # close file descriptor, otherwise it can be source of app crash!
# http://www.logilab.org/blogentry/17873 # http://www.logilab.org/blogentry/17873
os.close(fd) os.close(fd)
def _read_db(self):
"""
"""
session = Session()
dirs = session.query(File).filter(File.type == 1).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)
get_children(fileob.id, myiter)
return
get_children()
session.close()
return True
# TODO: get this thing right # TODO: get this thing right
def get_root_entries(self, id): def get_root_entries(self, id):
LOG.debug("id: %s" (type(id))) LOG.debug("id: %s", str(id))

View File

@@ -53,21 +53,21 @@ class DiscsView(View):
Initialize view Initialize view
""" """
View.__init__(self) View.__init__(self)
#self.discs_popup = DiscsPopupView() self.popup_menu = DiscsPopupView()
#class DiscsPopupView(View): class DiscsPopupView(View):
# """ """
# Separate Discs PopUp subview. Separate Discs PopUp subview.
# """ """
# glade = get_glade("discs.glade") glade = get_glade("discs.glade")
# top = 'discs_popup' top = 'discs_popup'
# def __init__(self): def __init__(self):
# """ """
# Initialize view Initialize view
# """ """
# View.__init__(self) View.__init__(self)
#class FilesView(View): #class FilesView(View):