mirror of
https://github.com/gryf/pygtktalog.git
synced 2025-12-17 19:40:21 +01:00
* Added another part of tag cloud.
This commit is contained in:
@@ -434,6 +434,47 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkExpander" id="tag_cloud_ex">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="activate" handler="on_tag_cloud_ex_activate"/>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<child>
|
||||
<widget class="GtkTextView" id="tag_cloud_textview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="wrap_mode">GTK_WRAP_WORD</property>
|
||||
<property name="cursor_visible">False</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Tag cloud</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
@@ -458,46 +499,6 @@
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkExpander" id="keywords">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<child>
|
||||
<widget class="GtkTextView" id="keyword_textview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="wrap_mode">GTK_WRAP_WORD</property>
|
||||
<property name="cursor_visible">False</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Keywords</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
@@ -524,6 +525,7 @@
|
||||
<property name="rules_hint">True</property>
|
||||
<signal name="row_activated" handler="on_files_row_activated"/>
|
||||
<signal name="cursor_changed" handler="on_files_cursor_changed"/>
|
||||
<signal name="key_release_event" handler="on_files_key_release_event"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
@@ -49,13 +49,13 @@ class MainController(Controller):
|
||||
widgets = (
|
||||
"discs","files",
|
||||
'save1','save_as1','cut1','copy1','paste1','delete1','add_cd','add_directory1',
|
||||
'tb_save','tb_addcd','tb_find','keywords','description',
|
||||
'tb_save','tb_addcd','tb_find','tag_cloud_ex','description',
|
||||
)
|
||||
widgets_all = (
|
||||
"discs","files",
|
||||
'file1','edit1','add_cd','add_directory1','help1',
|
||||
'tb_save','tb_addcd','tb_find','tb_new','tb_open','tb_quit',
|
||||
'keywords','description',
|
||||
'tag_cloud_ex','description',
|
||||
)
|
||||
|
||||
widgets_cancel = ('cancel','cancel1')
|
||||
@@ -103,18 +103,20 @@ class MainController(Controller):
|
||||
self.view['vpaned1'].set_position(self.model.config.confd['v'])
|
||||
self.view['main'].resize(self.model.config.confd['wx'],self.model.config.confd['wy'])
|
||||
|
||||
# zainicjalizuj statusbar
|
||||
# initialize statusbar
|
||||
self.context_id = self.view['mainStatus'].get_context_id('detailed res')
|
||||
self.statusbar_id = self.view['mainStatus'].push(self.context_id, "Idle")
|
||||
|
||||
# inicjalizacja drzew
|
||||
# initialize treeviews
|
||||
self.__setup_disc_treeview()
|
||||
self.__setup_files_treeview()
|
||||
|
||||
# w przypadku podania jako argument z linii komend bazy, odblokuj cały ten staff
|
||||
# in case passing catalog filename in command line, unlock gui
|
||||
if self.model.filename != None:
|
||||
self.__activateUI(self.model.filename)
|
||||
|
||||
self.view['vpaned2'].set_position(18)
|
||||
print self.view['tag_cloud_textview'].get_window(gtk.TEXT_WINDOW_TEXT)
|
||||
# generate recent menu
|
||||
self.__generate_recent_menu()
|
||||
|
||||
@@ -124,6 +126,23 @@ class MainController(Controller):
|
||||
|
||||
#########################################################################
|
||||
# Connect signals from GUI, like menu objects, toolbar buttons and so on.
|
||||
def on_tag_cloud_textview_motion_notify_event(self, widget):
|
||||
print 'e'
|
||||
w = self.view['tag_cloud_textview'].get_window(gtk.TEXT_WINDOW_TEXT)
|
||||
if w:
|
||||
w.set_cursor(None)
|
||||
|
||||
def on_tag_cloud_ex_activate(self, widget):
|
||||
# TODO: change this fsckin amatourish positioning!
|
||||
if widget.get_expanded():
|
||||
self.view['vpaned2'].set_position(18)
|
||||
else:
|
||||
|
||||
w = self.view['tag_cloud_textview'].get_window(gtk.TEXT_WINDOW_TEXT)
|
||||
if w:
|
||||
w.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
|
||||
self.view['vpaned2'].set_position(200)
|
||||
|
||||
def on_main_destroy_event(self, window, event):
|
||||
self.__doQuit()
|
||||
return True
|
||||
@@ -196,8 +215,6 @@ class MainController(Controller):
|
||||
"""Show files on right treeview, after clicking the left disc treeview."""
|
||||
model = self.view['discs'].get_model()
|
||||
selected_item = self.model.discs_tree.get_value(self.model.discs_tree.get_iter(self.view['discs'].get_cursor()[0]),0)
|
||||
if __debug__:
|
||||
print "c_main.py, on_discs_cursor_changed()",selected_item
|
||||
self.model.get_root_entries(selected_item)
|
||||
|
||||
self.__get_item_info(selected_item)
|
||||
@@ -271,23 +288,42 @@ class MainController(Controller):
|
||||
buf = self.view['details'].get_buffer()
|
||||
buf.set_text('')
|
||||
self.view['details'].set_buffer(buf)'''
|
||||
if __debug__:
|
||||
print "c_main.py: on_files_cursor_changed() directory selected"
|
||||
else:
|
||||
#file, show what you got.
|
||||
#self.details.get_top_widget()
|
||||
selected_item = self.model.files_list.get_value(model.get_iter(treeview.get_cursor()[0]),0)
|
||||
self.__get_item_info(selected_item)
|
||||
if __debug__:
|
||||
print "c_main.py: on_files_cursor_changed() some other thing selected"
|
||||
except:
|
||||
if __debug__:
|
||||
print "c_main.py: on_files_cursor_changed() insufficient iterator"
|
||||
return
|
||||
|
||||
def on_files_key_release_event(self, a, event):
|
||||
if gtk.gdk.keyval_name(event.keyval) == 'BackSpace':
|
||||
d_path, d_column = self.view['discs'].get_cursor()
|
||||
if d_path and d_column:
|
||||
# easy way
|
||||
model = self.view['discs'].get_model()
|
||||
child_iter = model.get_iter(d_path)
|
||||
parent_iter = model.iter_parent(child_iter)
|
||||
if parent_iter:
|
||||
self.view['discs'].set_cursor(model.get_path(parent_iter))
|
||||
else:
|
||||
# hard way
|
||||
f_model = self.view['files'].get_model()
|
||||
first_child_value = f_model.get_value(f_model.get_iter_first(), 0)
|
||||
# get two steps up
|
||||
parent_value = self.model.get_parent_discs_value(self.model.get_parent_discs_value(first_child_value))
|
||||
iter = self.model.discs_tree.get_iter_first()
|
||||
while iter:
|
||||
if self.model.discs_tree.get_value(iter,0) == parent_value:
|
||||
self.view['discs'].set_cursor(self.model.discs_tree.get_path(iter))
|
||||
iter = None
|
||||
else:
|
||||
iter = self.model.discs_tree.iter_next()
|
||||
|
||||
def on_files_row_activated(self, files_obj, row, column):
|
||||
"""On directory doubleclick in files listview dive into desired branch."""
|
||||
# TODO: map backspace key for moving to upper level of directiories
|
||||
f_iter = self.model.files_list.get_iter(row)
|
||||
current_id = self.model.files_list.get_value(f_iter,0)
|
||||
|
||||
@@ -441,9 +477,12 @@ class MainController(Controller):
|
||||
"""Save database to file under different filename."""
|
||||
path = Dialogs.ChooseDBFilename().show_dialog()
|
||||
if path:
|
||||
self.__setTitle(filepath=path)
|
||||
self.model.save(path)
|
||||
self.model.config.add_recent(path)
|
||||
ret, err = self.model.save(path)
|
||||
if ret:
|
||||
self.model.config.add_recent(path)
|
||||
self.__setTitle(filepath=path)
|
||||
else:
|
||||
Dialogs.Err("Error writing file - pyGTKtalog","Cannot write file %s." % path, "%s" % err)
|
||||
pass
|
||||
|
||||
def __addCD(self, label=None):
|
||||
@@ -499,6 +538,9 @@ class MainController(Controller):
|
||||
return False
|
||||
|
||||
def __newDB(self):
|
||||
|
||||
self.__tag_cloud()
|
||||
|
||||
"""Create new database file"""
|
||||
if self.model.unsaved_project:
|
||||
if not Dialogs.Qst('Unsaved data - pyGTKtalog',
|
||||
@@ -515,6 +557,9 @@ class MainController(Controller):
|
||||
|
||||
self.__activateUI()
|
||||
|
||||
self.view['tag_cloud_ex'].set_sensitive(True)
|
||||
rect = self.view['tag_cloud_ex'].allocation
|
||||
print rect.width, rect.height, rect.x, rect.y
|
||||
return
|
||||
|
||||
def __setup_disc_treeview(self):
|
||||
@@ -677,22 +722,32 @@ class MainController(Controller):
|
||||
"""react on click on connected tag items"""
|
||||
if event.type == gtk.gdk.BUTTON_RELEASE:
|
||||
print tag.get_property('name')
|
||||
elif event.type == gtk.gdk.MOTION_NOTIFY:
|
||||
w = self.view['tag_cloud_textview'].get_window(gtk.TEXT_WINDOW_TEXT)
|
||||
if w:
|
||||
w.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
|
||||
else:
|
||||
w = self.view['tag_cloud_textview'].get_window(gtk.TEXT_WINDOW_TEXT)
|
||||
if w:
|
||||
w.set_cursor(None)
|
||||
|
||||
|
||||
def insert_blank(b, iter):
|
||||
if b.is_end() and b.is_start():
|
||||
iter = b.get_end_iter()
|
||||
if iter.is_end() and iter.is_start():
|
||||
return iter
|
||||
else:
|
||||
b.insert(iter, " ")
|
||||
iter = b.get_end_iter()
|
||||
return iter
|
||||
|
||||
if len(self.model.tag_cloud) > 0:
|
||||
buff = self.view['keyword_textview'].get_buffer()
|
||||
buff = gtk.TextBuffer()
|
||||
for cloud in self.model.tag_cloud:
|
||||
iter = insert_blank(buff, buff.get_end_iter())
|
||||
tag = buff.create_tag(cloud['id'])
|
||||
tag.set_property('size-points', cloud['size'])
|
||||
tag.connect('event', foo, tag)
|
||||
tag.set_property('foreground', cloud['color'])
|
||||
tag.connect('event', tag_cloud_click, tag)
|
||||
buff.insert_with_tags(iter, cloud['name'], tag)
|
||||
self.view['keyword_textview'].set_buffer(buff)
|
||||
self.view['tag_cloud_textview'].set_buffer(buff)
|
||||
pass # end of class
|
||||
|
||||
@@ -109,7 +109,7 @@ class ConfigModel(Model):
|
||||
'confirm abandon current catalog':'confirmabandon',
|
||||
'show toolbar':'showtoolbar',
|
||||
'show statusbar and progress bar':'showstatusbar',
|
||||
'compress collection':'compress',
|
||||
'compress catalog':'compress',
|
||||
'retrive extra informatin':'retrive',
|
||||
'scan exif data':'exif',
|
||||
'include gthumb image description':'gthumb',
|
||||
|
||||
@@ -27,6 +27,7 @@ import sys
|
||||
import base64
|
||||
import shutil
|
||||
import tarfile
|
||||
import tempfile
|
||||
|
||||
import gtk
|
||||
import gobject
|
||||
@@ -35,184 +36,15 @@ from gtkmvc.model_mt import ModelMT
|
||||
|
||||
from pysqlite2 import dbapi2 as sqlite
|
||||
from datetime import datetime
|
||||
#import mx.DateTime
|
||||
|
||||
try:
|
||||
import threading as _threading
|
||||
except ImportError:
|
||||
if __debug__:
|
||||
print "m_main.py: import exception: _threading"
|
||||
import dummy_threading as _threading
|
||||
try:
|
||||
import Image, ImageEnhance
|
||||
except:
|
||||
if __debug__:
|
||||
print "m_main.py: import exception: Image|ImageEnhance"
|
||||
pass
|
||||
|
||||
from utils import EXIF
|
||||
|
||||
from m_config import ConfigModel
|
||||
from m_details import DetailsModel
|
||||
|
||||
class Thumbnail(object):
|
||||
def __init__(self, filename=None, x=160, y=120, root='thumbnails', base=''):
|
||||
self.root = root
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.filename = filename
|
||||
self.base = base
|
||||
|
||||
def save(self, image_id):
|
||||
"""Save thumbnail into specific directory structure
|
||||
return full path to the file and exif object or None"""
|
||||
filepath = os.path.join(self.base, self.__get_and_make_path(image_id))
|
||||
f = open(self.filename, 'rb')
|
||||
exif = None
|
||||
returncode = -1
|
||||
try:
|
||||
exif = EXIF.process_file(f)
|
||||
f.close()
|
||||
if exif.has_key('JPEGThumbnail'):
|
||||
thumbnail = exif['JPEGThumbnail']
|
||||
f = open(filepath,'wb')
|
||||
f.write(thumbnail)
|
||||
f.close()
|
||||
if exif.has_key('Image Orientation'):
|
||||
orientation = exif['Image Orientation'].values[0]
|
||||
if orientation > 1:
|
||||
t = "/tmp/thumb%d.jpg" % datetime.now().microsecond
|
||||
im_in = Image.open(filepath)
|
||||
im_out = None
|
||||
if orientation == 8:
|
||||
# Rotated 90 CCW
|
||||
im_out = im_in.transpose(Image.ROTATE_90)
|
||||
elif orientation == 6:
|
||||
# Rotated 90 CW
|
||||
im_out = im_in.transpose(Image.ROTATE_270)
|
||||
elif orientation == 3:
|
||||
# Rotated 180
|
||||
im_out = im_in.transpose(Image.ROTATE_180)
|
||||
elif orientation == 2:
|
||||
# Mirrored horizontal
|
||||
im_out = im_in.transpose(Image.FLIP_LEFT_RIGHT)
|
||||
elif orientation == 4:
|
||||
# Mirrored vertical
|
||||
im_out = im_in.transpose(Image.FLIP_TOP_BOTTOM)
|
||||
elif orientation == 5:
|
||||
# Mirrored horizontal then rotated 90 CCW
|
||||
im_out = im_in.transpose(Image.FLIP_LEFT_RIGHT).transpose(Image.ROTATE_90)
|
||||
elif orientation == 7:
|
||||
# Mirrored horizontal then rotated 90 CW
|
||||
im_out = im_in.transpose(Image.FLIP_LEFT_RIGHT).transpose(Image.ROTATE_270)
|
||||
|
||||
if im_out:
|
||||
im_out.save(t, 'JPEG')
|
||||
shutil.move(t, filepath)
|
||||
else:
|
||||
f.close()
|
||||
returncode = 0
|
||||
else:
|
||||
im = self.__scale_image(True)
|
||||
if im:
|
||||
im.save(filepath, "JPEG")
|
||||
returncode = 1
|
||||
except:
|
||||
f.close()
|
||||
im = self.__scale_image(True)
|
||||
if im:
|
||||
im.save(filepath, "JPEG")
|
||||
returncode = 2
|
||||
return filepath, exif, returncode
|
||||
|
||||
# private class functions
|
||||
def __get_and_make_path(self, img_id):
|
||||
"""Make directory structure regards of id
|
||||
and return filepath WITHOUT extension"""
|
||||
t = os.path.join(self.base, self.root)
|
||||
try: os.mkdir(t)
|
||||
except: pass
|
||||
h = hex(img_id)
|
||||
if len(h[2:])>6:
|
||||
try: os.mkdir(os.path.join(t, h[2:4]))
|
||||
except: pass
|
||||
try: os.mkdir(os.path.join(t, h[2:4], h[4:6]))
|
||||
except: pass
|
||||
path = os.path.join(t, h[2:4], h[4:6], h[6:8])
|
||||
try: os.mkdir(path)
|
||||
except: pass
|
||||
img = "%s.%s" % (h[8:], 'jpg')
|
||||
elif len(h[2:])>4:
|
||||
try: os.mkdir(os.path.join(t, h[2:4]))
|
||||
except: pass
|
||||
path = os.path.join(t, h[2:4], h[4:6])
|
||||
try: os.mkdir(path)
|
||||
except: pass
|
||||
img = "%s.%s" % (h[6:], 'jpg')
|
||||
elif len(h[2:])>2:
|
||||
path = os.path.join(t, h[2:4])
|
||||
try: os.mkdir(path)
|
||||
except: pass
|
||||
img = "%s.%s" %(h[4:], 'jpg')
|
||||
else:
|
||||
path = t
|
||||
img = "%s.%s" %(h[2:], 'jpg')
|
||||
return(os.path.join(t, img))
|
||||
|
||||
def __scale_image(self, factor=False):
|
||||
"""generate scaled Image object for given file
|
||||
args:
|
||||
factor - if False, adjust height into self.y
|
||||
if True, use self.x for scale portrait pictures height.
|
||||
returns Image object, or False
|
||||
"""
|
||||
try:
|
||||
im = Image.open(self.filename).convert('RGB')
|
||||
except:
|
||||
return False
|
||||
x, y = im.size
|
||||
|
||||
if x > self.x or y > self.y:
|
||||
if x==y:
|
||||
# square
|
||||
imt = im.resize((self.y, self.y), Image.ANTIALIAS)
|
||||
elif x > y:
|
||||
# landscape
|
||||
if int(y/(x/float(self.x))) > self.y:
|
||||
# landscape image: height is non standard
|
||||
self.x1 = int(float(self.y) * self.y / self.x)
|
||||
if float(self.y) * self.y / self.x - self.x1 > 0.49:
|
||||
self.x1 += 1
|
||||
imt = im.resize(((int(x/(y/float(self.y))),self.y)),Image.ANTIALIAS)
|
||||
elif x/self.x==y/self.y:
|
||||
# aspect ratio ok
|
||||
imt = im.resize((self.x, self.y), Image.ANTIALIAS)
|
||||
else:
|
||||
imt = im.resize((self.x,int(y/(x/float(self.x)))), 1)
|
||||
else:
|
||||
# portrait
|
||||
if factor:
|
||||
if y>self.x:
|
||||
imt = im.resize(((int(x/(y/float(self.x))),self.x)),Image.ANTIALIAS)
|
||||
else:
|
||||
imt = im
|
||||
else:
|
||||
self.x1 = int(float(self.y) * self.y / self.x)
|
||||
if float(self.y) * self.y / self.x - self.x1 > 0.49:
|
||||
self.x1 += 1
|
||||
|
||||
if x/self.x1==y/self.y:
|
||||
# aspect ratio ok
|
||||
imt = im.resize((self.x1,self.y),Image.ANTIALIAS)
|
||||
else:
|
||||
imt = im.resize(((int(x/(y/float(self.y))),self.y)),Image.ANTIALIAS)
|
||||
return imt
|
||||
else:
|
||||
return im
|
||||
|
||||
class Picture(object):
|
||||
def __init__(self, *args):
|
||||
self.x = None
|
||||
self.y = None
|
||||
from utils.thumbnail import Thumbnail
|
||||
|
||||
class MainModel(ModelMT):
|
||||
"""Create, load, save, manipulate db file which is container for data"""
|
||||
@@ -241,7 +73,7 @@ class MainModel(ModelMT):
|
||||
ModelMT.__init__(self)
|
||||
self.config = ConfigModel()
|
||||
self.unsaved_project = False
|
||||
self.filename = None # collection saved/opened filename
|
||||
self.filename = None # catalog saved/opened filename
|
||||
self.internal_dirname = None
|
||||
self.db_connection = None
|
||||
self.db_cursor = None
|
||||
@@ -259,6 +91,13 @@ class MainModel(ModelMT):
|
||||
gobject.TYPE_UINT64,
|
||||
gobject.TYPE_STRING, gobject.TYPE_INT,
|
||||
gobject.TYPE_STRING, str)
|
||||
|
||||
# tag cloud array element is a dict with 4 keys:
|
||||
# elem = {'id': str(id), 'name': tagname, 'size': size, 'color': color}
|
||||
# where color is in one of format:
|
||||
# - named (i.e. red, blue, black and so on)
|
||||
# - #rgb
|
||||
# - #rrggbb
|
||||
self.tag_cloud = []
|
||||
return
|
||||
|
||||
@@ -268,8 +107,6 @@ class MainModel(ModelMT):
|
||||
try:
|
||||
shutil.rmtree(self.internal_dirname)
|
||||
except:
|
||||
if __debug__:
|
||||
print "m_main.py: cleanup()", self.internal_dirname
|
||||
pass
|
||||
return
|
||||
|
||||
@@ -287,10 +124,13 @@ class MainModel(ModelMT):
|
||||
return
|
||||
|
||||
def save(self, filename=None):
|
||||
"""save tared directory at given catalog fielname"""
|
||||
if filename:
|
||||
self.filename = filename
|
||||
self.__compress_and_save()
|
||||
return
|
||||
val, err = self.__compress_and_save()
|
||||
if not val:
|
||||
self.filename = None
|
||||
return val, err
|
||||
|
||||
def open(self, filename=None):
|
||||
"""try to open db file"""
|
||||
@@ -304,7 +144,6 @@ class MainModel(ModelMT):
|
||||
try:
|
||||
tar = tarfile.open(filename, "r")
|
||||
except:
|
||||
print "%s: file cannot be read!" % filename
|
||||
self.filename = None
|
||||
self.internal_dirname = None
|
||||
return
|
||||
@@ -312,6 +151,7 @@ class MainModel(ModelMT):
|
||||
os.chdir(self.internal_dirname)
|
||||
try:
|
||||
tar.extractall()
|
||||
print "m_main.py: extracted tarfile into", self.internal_dirname
|
||||
except AttributeError:
|
||||
# python's 2.4 tarfile module lacks of method extractall()
|
||||
directories = []
|
||||
@@ -372,13 +212,6 @@ class MainModel(ModelMT):
|
||||
self.files_list.clear()
|
||||
except:
|
||||
pass
|
||||
# parent for virtual '..' dir
|
||||
#myiter = self.filemodel.insert_before(None,None)
|
||||
#self.cur.execute("SELECT parent FROM files_connect WHERE child=? AND depth = 1",(id,))
|
||||
#self.filemodel.set_value(myiter,0,self.cur.fetchone()[0])
|
||||
#self.filemodel.set_value(myiter,1,'..')
|
||||
#if __debug__:
|
||||
# print datetime.fromtimestamp(ch[3])
|
||||
|
||||
# directories first
|
||||
self.db_cursor.execute("SELECT id, filename, size, date FROM files \
|
||||
@@ -413,32 +246,38 @@ class MainModel(ModelMT):
|
||||
self.files_list.set_value(myiter, 4, ch[4])
|
||||
self.files_list.set_value(myiter, 5, 'kategoria srategoria')
|
||||
if ch[4] == self.FIL:
|
||||
if ch[5] == self.F_IMG and ch[6] != None:
|
||||
if ch[6] != None:
|
||||
# TODO: change icon to thumbnail
|
||||
self.files_list.set_value(myiter, 6, gtk.STOCK_FILE)
|
||||
else:
|
||||
self.files_list.set_value(myiter, 6, gtk.STOCK_FILE)
|
||||
elif ch[4] == self.LIN:
|
||||
self.files_list.set_value(myiter, 6, gtk.STOCK_INDEX)
|
||||
return
|
||||
def get_parent_discs_value(self, child_id):
|
||||
if child_id:
|
||||
self.db_cursor.execute("SELECT parent_id FROM files where id=?", (child_id,))
|
||||
set = self.db_cursor.fetchone()
|
||||
if set:
|
||||
return set[0]
|
||||
return None
|
||||
|
||||
def get_file_info(self, id):
|
||||
"""get file info from database"""
|
||||
retval = {}
|
||||
self.db_cursor.execute("SELECT filename, date, size, type, filetype, \
|
||||
id FROM files WHERE id = ?", (id,))
|
||||
self.db_cursor.execute("SELECT f.filename, f.date, f.size, f.type, \
|
||||
t.filename \
|
||||
FROM files f \
|
||||
LEFT JOIN thumbnails t ON t.file_id = f.id \
|
||||
WHERE f.id = ?", (id,))
|
||||
set = self.db_cursor.fetchone()
|
||||
if set:
|
||||
string = "Filename: %s\nDate: %s\nSize: %s\ntype: %s" % \
|
||||
(set[0], datetime.fromtimestamp(set[1]), set[2], set[3])
|
||||
string = "ID: %d\nFilename: %s\nDate: %s\nSize: %s\ntype: %s" % \
|
||||
(id, set[0], datetime.fromtimestamp(set[1]), set[2], set[3])
|
||||
retval['description'] = string
|
||||
|
||||
if set[4] == self.F_IMG:
|
||||
self.db_cursor.execute("SELECT filename FROM thumbnails \
|
||||
WHERE file_id = ?",
|
||||
(id,))
|
||||
set = self.db_cursor.fetchone()
|
||||
if set:
|
||||
retval['thumbnail'] = os.path.join(self.internal_dirname, set[0])
|
||||
if set[4]:
|
||||
retval['thumbnail'] = os.path.join(self.internal_dirname, set[4])
|
||||
return retval
|
||||
|
||||
def get_source(self, path):
|
||||
@@ -505,28 +344,31 @@ class MainModel(ModelMT):
|
||||
|
||||
def __create_internal_dirname(self):
|
||||
self.cleanup()
|
||||
self.internal_dirname = "/tmp/pygtktalog%d" % datetime.now().microsecond
|
||||
self.internal_dirname = "/tm/pygtktalog%d" % datetime.now().microsecond
|
||||
try:
|
||||
os.mkdir(self.internal_dirname)
|
||||
except:
|
||||
if __debug__:
|
||||
print "m_main.py: __create_internal_dirname(): cannot create \
|
||||
temporary directory, or directory exists"
|
||||
pass
|
||||
except IOError, (errno, strerror):
|
||||
print "m_main.py: __create_internal_dirname(): ", strerror
|
||||
return
|
||||
|
||||
def __compress_and_save(self):
|
||||
if self.config.confd['compress']:
|
||||
tar = tarfile.open(self.filename, "w:gz")
|
||||
else:
|
||||
tar = tarfile.open(self.filename, "w")
|
||||
try:
|
||||
if self.config.confd['compress']:
|
||||
tar = tarfile.open(self.filename, "w:gz")
|
||||
else:
|
||||
tar = tarfile.open(self.filename, "w")
|
||||
if __debug__:
|
||||
print "m_main.py: __compress_and_save(): tar open successed"
|
||||
|
||||
except IOError, (errno, strerror):
|
||||
return False, strerror
|
||||
|
||||
os.chdir(self.internal_dirname)
|
||||
tar.add('.')
|
||||
tar.close()
|
||||
|
||||
self.unsaved_project = False
|
||||
return
|
||||
return True, None
|
||||
|
||||
def __create_database(self):
|
||||
"""make all necessary tables in db file"""
|
||||
@@ -778,7 +620,16 @@ class MainModel(ModelMT):
|
||||
detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)
|
||||
db_cursor = db_connection.cursor()
|
||||
|
||||
print "%s" % \
|
||||
(self.internal_dirname + '/db.sqlite')
|
||||
|
||||
# fetch all the directories
|
||||
sql = """
|
||||
SELECT id, parent_id, filename FROM files
|
||||
WHERE type=1 ORDER BY parent_id, filename
|
||||
"""
|
||||
db_cursor.execute(sql)
|
||||
data = db_cursor.fetchall()
|
||||
try:
|
||||
sql = """
|
||||
SELECT id, parent_id, filename FROM files
|
||||
|
||||
Reference in New Issue
Block a user