* src/plugins/MediaManager.py: conversion functions of path
* src/Utils.py: general methods to convert abs to rel * src/Editors/AddMedia.py: show existing descr and select file if pos * src/Editors/_EditPerson.py: view photo needs db for media path * src/Editors/_EditMedia.py: better path/mime handling * src/DataViews/MediaView.py: use full path to view Start of issue #1208 2008-02-11 Benny Malengier <benny.malengier@gramps-project.org> svn: r10017
This commit is contained in:
parent
c11f6d6a1b
commit
a1897e68d9
@ -1,3 +1,12 @@
|
|||||||
|
2008-02-11 Benny Malengier <benny.malengier@gramps-project.org>
|
||||||
|
* src/plugins/MediaManager.py: conversion functions of path
|
||||||
|
* src/Utils.py: general methods to convert abs to rel
|
||||||
|
* src/Editors/AddMedia.py: show existing descr and select file if pos
|
||||||
|
* src/Editors/_EditPerson.py: view photo needs db for media path
|
||||||
|
* src/Editors/_EditMedia.py: better path/mime handling
|
||||||
|
* src/DataViews/MediaView.py: use full path to view
|
||||||
|
Start of issue #1208
|
||||||
|
|
||||||
2008-02-11 Benny Malengier <benny.malengier@gramps-project.org>
|
2008-02-11 Benny Malengier <benny.malengier@gramps-project.org>
|
||||||
* src/Editors/_EditFamily.py: call editprimary correctly, double gid
|
* src/Editors/_EditFamily.py: call editprimary correctly, double gid
|
||||||
|
|
||||||
|
@ -230,7 +230,8 @@ class MediaView(PageView.ListView):
|
|||||||
mime_type = ref_obj.get_mime_type()
|
mime_type = ref_obj.get_mime_type()
|
||||||
app = Mime.get_application(mime_type)
|
app = Mime.get_application(mime_type)
|
||||||
if app:
|
if app:
|
||||||
Utils.launch(app[0], ref_obj.get_path())
|
Utils.launch(app[0], Utils.media_path_full(self.dbstate.db,
|
||||||
|
ref_obj.get_path()))
|
||||||
else:
|
else:
|
||||||
ErrorDialog(_("Cannot view %s") % ref_obj.get_path(),
|
ErrorDialog(_("Cannot view %s") % ref_obj.get_path(),
|
||||||
_("GRAMPS cannot find an application that can view "
|
_("GRAMPS cannot find an application that can view "
|
||||||
@ -325,7 +326,8 @@ class MediaView(PageView.ListView):
|
|||||||
self.ttips.disable()
|
self.ttips.disable()
|
||||||
else:
|
else:
|
||||||
obj = self.dbstate.db.get_object_from_handle(handle)
|
obj = self.dbstate.db.get_object_from_handle(handle)
|
||||||
pix = ThumbNails.get_thumbnail_image(obj.get_path())
|
pix = ThumbNails.get_thumbnail_image(
|
||||||
|
Utils.media_path_full(self.dbstate.db, obj.get_path()))
|
||||||
self.image.set_from_pixbuf(pix)
|
self.image.set_from_pixbuf(pix)
|
||||||
self.ttips.enable()
|
self.ttips.enable()
|
||||||
|
|
||||||
|
@ -107,9 +107,20 @@ class AddMediaObject(ManagedWindow.ManagedWindow):
|
|||||||
self.image = self.glade.get_widget("image")
|
self.image = self.glade.get_widget("image")
|
||||||
self.file_text = self.glade.get_widget("fname")
|
self.file_text = self.glade.get_widget("fname")
|
||||||
if not(self.last_directory and os.path.isdir(self.last_directory)):
|
if not(self.last_directory and os.path.isdir(self.last_directory)):
|
||||||
self.last_directory = const.HOME_DIR
|
self.last_directory = const.USER_HOME
|
||||||
print 'test', self.last_directory
|
#if existing path, use dir of path
|
||||||
self.file_text.set_current_folder(self.last_directory)
|
if not self.obj.get_path() == "":
|
||||||
|
fullname = Utils.media_path_full(self.dbase, self.obj.get_path())
|
||||||
|
dir = os.path.dirname(fullname)
|
||||||
|
if os.path.isdir(dir):
|
||||||
|
self.last_directory = dir
|
||||||
|
self.file_text.select_filename(fullname)
|
||||||
|
else:
|
||||||
|
self.file_text.set_current_folder(self.last_directory)
|
||||||
|
else:
|
||||||
|
self.file_text.set_current_folder(self.last_directory)
|
||||||
|
if not self.obj.get_description() == "":
|
||||||
|
self.description.set_text(self.obj.get_description())
|
||||||
|
|
||||||
self.relpath = self.glade.get_widget('relpath')
|
self.relpath = self.glade.get_widget('relpath')
|
||||||
self.relpath.set_active(self.relative_path)
|
self.relpath.set_active(self.relative_path)
|
||||||
@ -151,10 +162,7 @@ class AddMediaObject(ManagedWindow.ManagedWindow):
|
|||||||
filename = Utils.get_unicode_path(self.file_text.get_filename())
|
filename = Utils.get_unicode_path(self.file_text.get_filename())
|
||||||
full_file = filename
|
full_file = filename
|
||||||
|
|
||||||
pname = self.dbase.get_save_path()
|
pname = Utils.media_path(self.dbase)
|
||||||
if not os.path.isdir(pname):
|
|
||||||
pname = os.path.dirname(pname)
|
|
||||||
|
|
||||||
if self.relpath.get_active():
|
if self.relpath.get_active():
|
||||||
filename = Utils.relative_path(filename, pname)
|
filename = Utils.relative_path(filename, pname)
|
||||||
|
|
||||||
|
@ -128,22 +128,40 @@ class EditMedia(EditPrimary):
|
|||||||
ebox.connect('button-press-event', self.button_press_event)
|
ebox.connect('button-press-event', self.button_press_event)
|
||||||
|
|
||||||
self.mimetext = self.glade.get_widget("type")
|
self.mimetext = self.glade.get_widget("type")
|
||||||
self.draw_preview()
|
|
||||||
self.setup_filepath()
|
self.setup_filepath()
|
||||||
|
self.determine_mime()
|
||||||
|
self.draw_preview()
|
||||||
|
|
||||||
|
def determine_mime(self):
|
||||||
|
descr = Mime.get_description(self.obj.get_mime_type())
|
||||||
|
if descr:
|
||||||
|
self.mimetext.set_text(descr)
|
||||||
|
|
||||||
|
path = self.file_path.get_text()
|
||||||
|
path_full = Utils.media_path_full(self.db, path)
|
||||||
|
if path != self.obj.get_path() and path_full != self.obj.get_path():
|
||||||
|
#redetermine mime
|
||||||
|
mime = Mime.get_type(Utils.find_file(path_full))
|
||||||
|
self.obj.set_mime_type(mime)
|
||||||
|
descr = Mime.get_description(mime)
|
||||||
|
if descr:
|
||||||
|
self.mimetext.set_text(descr)
|
||||||
|
else:
|
||||||
|
self.mimetext.set_text(_('Unknown'))
|
||||||
|
#if mime type not set, is note
|
||||||
|
if not self.obj.get_mime_type():
|
||||||
|
self.mimetext.set_text(_('Note'))
|
||||||
|
|
||||||
def draw_preview(self):
|
def draw_preview(self):
|
||||||
mtype = self.obj.get_mime_type()
|
mtype = self.obj.get_mime_type()
|
||||||
if mtype:
|
if mtype:
|
||||||
pb = ThumbNails.get_thumbnail_image(
|
pb = ThumbNails.get_thumbnail_image(Utils.find_file(
|
||||||
Utils.find_file(self.obj.get_path()), mtype)
|
Utils.media_path_full(self.db, self.obj.get_path())),
|
||||||
|
mtype)
|
||||||
self.pixmap.set_from_pixbuf(pb)
|
self.pixmap.set_from_pixbuf(pb)
|
||||||
descr = Mime.get_description(mtype)
|
|
||||||
if descr:
|
|
||||||
self.mimetext.set_text(descr)
|
|
||||||
else:
|
else:
|
||||||
pb = Mime.find_mime_type_pixbuf('text/plain')
|
pb = Mime.find_mime_type_pixbuf('text/plain')
|
||||||
self.pixmap.set_from_pixbuf(pb)
|
self.pixmap.set_from_pixbuf(pb)
|
||||||
self.mimetext.set_text(_('Note'))
|
|
||||||
|
|
||||||
def setup_filepath(self):
|
def setup_filepath(self):
|
||||||
self.select = self.glade.get_widget('file_select')
|
self.select = self.glade.get_widget('file_select')
|
||||||
@ -192,9 +210,13 @@ class EditMedia(EditPrimary):
|
|||||||
mime_type = ref_obj.get_mime_type()
|
mime_type = ref_obj.get_mime_type()
|
||||||
app = Mime.get_application(mime_type)
|
app = Mime.get_application(mime_type)
|
||||||
if app:
|
if app:
|
||||||
Utils.launch(app[0], ref_obj.get_path())
|
Utils.launch(app[0], Utils.media_path_full(self.dbstate.db,
|
||||||
|
ref_obj.get_path()))
|
||||||
|
|
||||||
def select_file(self, val):
|
def select_file(self, val):
|
||||||
|
self.determine_mime()
|
||||||
|
path = self.file_path.get_text()
|
||||||
|
self.obj.set_path(Utils.get_unicode_path(path))
|
||||||
AddMediaObject(self.dbstate, self.uistate, self.track, self.obj,
|
AddMediaObject(self.dbstate, self.uistate, self.track, self.obj,
|
||||||
self._update_addmedia)
|
self._update_addmedia)
|
||||||
|
|
||||||
@ -208,10 +230,12 @@ class EditMedia(EditPrimary):
|
|||||||
obj.update()
|
obj.update()
|
||||||
fname = self.obj.get_path()
|
fname = self.obj.get_path()
|
||||||
self.file_path.set_text(fname)
|
self.file_path.set_text(fname)
|
||||||
|
self.determine_mime()
|
||||||
self.draw_preview()
|
self.draw_preview()
|
||||||
|
|
||||||
def save(self, *obj):
|
def save(self, *obj):
|
||||||
self.ok_button.set_sensitive(False)
|
self.ok_button.set_sensitive(False)
|
||||||
|
|
||||||
if self.object_is_empty():
|
if self.object_is_empty():
|
||||||
ErrorDialog(_("Cannot save media object"),
|
ErrorDialog(_("Cannot save media object"),
|
||||||
_("No data exists for this media object. Please "
|
_("No data exists for this media object. Please "
|
||||||
@ -233,11 +257,8 @@ class EditMedia(EditPrimary):
|
|||||||
self.ok_button.set_sensitive(True)
|
self.ok_button.set_sensitive(True)
|
||||||
return
|
return
|
||||||
|
|
||||||
path = self.glade.get_widget('path').get_text()
|
path = self.file_path.get_text()
|
||||||
|
self.determine_mime()
|
||||||
if path != self.obj.get_path():
|
|
||||||
mime = Mime.get_type(Utils.find_file(os.path.abspath(path)))
|
|
||||||
self.obj.set_mime_type(mime)
|
|
||||||
|
|
||||||
self.obj.set_path(Utils.get_unicode_path(path))
|
self.obj.set_path(Utils.get_unicode_path(path))
|
||||||
|
|
||||||
|
@ -486,7 +486,8 @@ class EditPerson(EditPrimary):
|
|||||||
if media_list:
|
if media_list:
|
||||||
photo = media_list[0]
|
photo = media_list[0]
|
||||||
object_handle = photo.get_reference_handle()
|
object_handle = photo.get_reference_handle()
|
||||||
Utils.view_photo(self.db.get_object_from_handle(object_handle))
|
Utils.view_photo(self.db.get_object_from_handle(object_handle),
|
||||||
|
self.db)
|
||||||
|
|
||||||
def _popup_change_description(self, obj):
|
def _popup_change_description(self, obj):
|
||||||
"""
|
"""
|
||||||
|
63
src/Utils.py
63
src/Utils.py
@ -51,7 +51,7 @@ import gen.lib
|
|||||||
import Errors
|
import Errors
|
||||||
from QuestionDialog import WarningDialog
|
from QuestionDialog import WarningDialog
|
||||||
|
|
||||||
from const import TEMP_DIR
|
from const import TEMP_DIR, USER_HOME
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
@ -262,14 +262,17 @@ def add_menuitem(menu, msg, obj, func):
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
def view_photo(photo):
|
def view_photo(photo, db):
|
||||||
|
"""
|
||||||
|
photo is a mediaobject, this utility launches a viewing application
|
||||||
|
"""
|
||||||
mime_type = photo.get_mime_type()
|
mime_type = photo.get_mime_type()
|
||||||
try:
|
try:
|
||||||
data = Mime.get_application(mime_type)
|
data = Mime.get_application(mime_type)
|
||||||
prog = data[0]
|
prog = data[0]
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
launch(prog, photo.get_path())
|
launch(prog, media_path_full(db, photo.get_path()))
|
||||||
|
|
||||||
def find_file( filename):
|
def find_file( filename):
|
||||||
# try the filename we got
|
# try the filename we got
|
||||||
@ -937,22 +940,66 @@ def get_type_converter_by_name(val_str):
|
|||||||
return unicode
|
return unicode
|
||||||
|
|
||||||
def relative_path(original, base):
|
def relative_path(original, base):
|
||||||
if not os.path.exists(original) or not os.path.isdir(base):
|
"""
|
||||||
|
Calculate the relative path from base to original, with base a directory,
|
||||||
|
and original an absolute path
|
||||||
|
On problems, original is returned unchanged
|
||||||
|
"""
|
||||||
|
if not os.path.isdir(base):
|
||||||
|
return original
|
||||||
|
#original and base must be absolute paths
|
||||||
|
if not os.path.isabs(base):
|
||||||
|
return original
|
||||||
|
if not os.path.isabs(original):
|
||||||
|
return original
|
||||||
|
original = os.path.normpath(original)
|
||||||
|
base = os.path.normpath(base)
|
||||||
|
|
||||||
|
# If the db_dir and obj_dir are on different drives (win only)
|
||||||
|
# then there cannot be a relative path. Return original obj_path
|
||||||
|
(base_drive, base) = os.path.splitdrive(base)
|
||||||
|
(orig_drive, orig_name) = os.path.splitdrive(original)
|
||||||
|
if base_drive.upper() != orig_drive.upper():
|
||||||
return original
|
return original
|
||||||
|
|
||||||
base_list = (os.path.abspath(base)).split(os.sep)
|
|
||||||
target_list = (os.path.abspath(original)).split(os.sep)
|
|
||||||
|
|
||||||
# Starting from the filepath root, work out how much of the filepath is
|
# Starting from the filepath root, work out how much of the filepath is
|
||||||
# shared by base and target.
|
# shared by base and target.
|
||||||
|
base_list = (base).split(os.sep)
|
||||||
|
target_list = (orig_name).split(os.sep)
|
||||||
|
# make sure '/home/person' and 'c:/home/person' both give
|
||||||
|
# list ['home', 'person']
|
||||||
|
base_list = [word for word in base_list if word]
|
||||||
|
target_list = [word for word in target_list if word]
|
||||||
|
i = -1
|
||||||
for i in range(min(len(base_list), len(target_list))):
|
for i in range(min(len(base_list), len(target_list))):
|
||||||
if base_list[i] <> target_list[i]: break
|
if base_list[i] <> target_list[i]: break
|
||||||
else:
|
else:
|
||||||
|
#if break did not happen we are here at end, and add 1.
|
||||||
i += 1
|
i += 1
|
||||||
rel_list = [os.pardir] * (len(base_list)-i) + target_list[i:]
|
rel_list = [os.pardir] * (len(base_list)-i) + target_list[i:]
|
||||||
return os.path.join(*rel_list)
|
return os.path.join(*rel_list)
|
||||||
|
|
||||||
|
def media_path(db):
|
||||||
|
"""
|
||||||
|
Given a database, return the mediapath to use as basedir for media
|
||||||
|
"""
|
||||||
|
mpath = db.get_mediapath()
|
||||||
|
if mpath is None:
|
||||||
|
#use home dir
|
||||||
|
mpath = USER_HOME
|
||||||
|
return mpath
|
||||||
|
|
||||||
|
def media_path_full(db, filename):
|
||||||
|
"""
|
||||||
|
Given a database and a filename of a media, return the media filename
|
||||||
|
is full form, eg 'graves/tomb.png' becomes '/home/me/genea/graves/tomb.png
|
||||||
|
"""
|
||||||
|
if os.path.isabs(filename):
|
||||||
|
return filename
|
||||||
|
mpath = media_path(db)
|
||||||
|
return os.path.join(mpath, filename)
|
||||||
|
|
||||||
|
|
||||||
class ProgressMeter:
|
class ProgressMeter:
|
||||||
"""
|
"""
|
||||||
Progress meter class for GRAMPS.
|
Progress meter class for GRAMPS.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
# Gramps - a GTK+/GNOME based genealogy program
|
# Gramps - a GTK+/GNOME based genealogy program
|
||||||
#
|
#
|
||||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||||
|
# Copyright (C) 2008 B. Malengier
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -51,6 +52,7 @@ import Errors
|
|||||||
from gen.lib import MediaObject
|
from gen.lib import MediaObject
|
||||||
from BasicUtils import UpdateCallback
|
from BasicUtils import UpdateCallback
|
||||||
from PluginUtils import Tool, register_tool
|
from PluginUtils import Tool, register_tool
|
||||||
|
from Utils import media_path_full, relative_path, media_path
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -483,8 +485,9 @@ class PathChange(BatchOp):
|
|||||||
class Convert2Abs(BatchOp):
|
class Convert2Abs(BatchOp):
|
||||||
title = _('Convert paths from relative to _absolute')
|
title = _('Convert paths from relative to _absolute')
|
||||||
description = _('This tool allows converting relative media paths '
|
description = _('This tool allows converting relative media paths '
|
||||||
'to the absolute ones. An absolute path allows to '
|
'to the absolute ones. It does this by prepending '
|
||||||
'fix the file location while moving the database.')
|
'the base path as given in the Preferences, or if '
|
||||||
|
'that is not set, it prepends your home directory.')
|
||||||
|
|
||||||
def _prepare(self):
|
def _prepare(self):
|
||||||
cursor = self.db.get_media_cursor()
|
cursor = self.db.get_media_cursor()
|
||||||
@ -508,7 +511,7 @@ class Convert2Abs(BatchOp):
|
|||||||
self.set_total(len(self.handle_list))
|
self.set_total(len(self.handle_list))
|
||||||
for handle in self.handle_list:
|
for handle in self.handle_list:
|
||||||
obj = self.db.get_object_from_handle(handle)
|
obj = self.db.get_object_from_handle(handle)
|
||||||
new_path = os.path.abspath(obj.path)
|
new_path = media_path_full(self.db, obj.path)
|
||||||
obj.set_path(new_path)
|
obj.set_path(new_path)
|
||||||
self.db.commit_media_object(obj,self.trans)
|
self.db.commit_media_object(obj,self.trans)
|
||||||
self.update()
|
self.update()
|
||||||
@ -520,8 +523,11 @@ class Convert2Abs(BatchOp):
|
|||||||
class Convert2Rel(BatchOp):
|
class Convert2Rel(BatchOp):
|
||||||
title = _('Convert paths from absolute to r_elative')
|
title = _('Convert paths from absolute to r_elative')
|
||||||
description = _('This tool allows converting absolute media paths '
|
description = _('This tool allows converting absolute media paths '
|
||||||
'to the relative ones. A relative path allows to '
|
'to the a relative path. The relative path is relative '
|
||||||
'tie the file location to that of the database.')
|
'viz-a-viz the base path as given in the Preferences, '
|
||||||
|
'or if that is not set, your home directory. '
|
||||||
|
'A relative path allows to tie the file location to a '
|
||||||
|
'base path that can change to your needs.')
|
||||||
|
|
||||||
def _prepare(self):
|
def _prepare(self):
|
||||||
cursor = self.db.get_media_cursor()
|
cursor = self.db.get_media_cursor()
|
||||||
@ -543,51 +549,15 @@ class Convert2Rel(BatchOp):
|
|||||||
if not self.prepared:
|
if not self.prepared:
|
||||||
self.prepare()
|
self.prepare()
|
||||||
self.set_total(len(self.handle_list))
|
self.set_total(len(self.handle_list))
|
||||||
db_dir = os.path.normpath(os.path.dirname(self.db.full_name))
|
base_dir = media_path(self.db)
|
||||||
for handle in self.handle_list:
|
for handle in self.handle_list:
|
||||||
obj = self.db.get_object_from_handle(handle)
|
obj = self.db.get_object_from_handle(handle)
|
||||||
new_path = get_rel_path(db_dir,obj.path)
|
new_path = relative_path(obj.path, base_dir)
|
||||||
obj.set_path(new_path)
|
obj.set_path(new_path)
|
||||||
self.db.commit_media_object(obj,self.trans)
|
self.db.commit_media_object(obj,self.trans)
|
||||||
self.update()
|
self.update()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Helper functions
|
|
||||||
#
|
|
||||||
#------------------------------------------------------------------------
|
|
||||||
def get_rel_path(db_dir,obj_path):
|
|
||||||
obj_dir = os.path.dirname(os.path.normpath(obj_path))
|
|
||||||
obj_name = os.path.basename(os.path.normpath(obj_path))
|
|
||||||
|
|
||||||
# If the db_dir and obj_dir are on different drives (win only)
|
|
||||||
# then there cannot be a relative path. Return original obj_path
|
|
||||||
(db_drive,db_dir) = os.path.splitdrive(db_dir)
|
|
||||||
(obj_drive,obj_dir) = os.path.splitdrive(obj_dir)
|
|
||||||
if db_drive.upper() != obj_drive.upper():
|
|
||||||
return obj_path
|
|
||||||
|
|
||||||
# Get the list of dirnames for each
|
|
||||||
db_dir_list = [word for word in db_dir.split(os.path.sep) if word]
|
|
||||||
obj_dir_list = [word for word in obj_dir.split(os.path.sep) if word]
|
|
||||||
|
|
||||||
# The worst case scenario: nothing in common:
|
|
||||||
# we would need to go ndirs up and then use the full obj path
|
|
||||||
ndirs = len(db_dir_list)
|
|
||||||
|
|
||||||
# Compare words in both lists
|
|
||||||
for word_ix in range(min(len(db_dir_list),len(obj_dir_list))):
|
|
||||||
# A common word reduces the trip by one '../' and one word
|
|
||||||
if db_dir_list[word_ix] == obj_dir_list[word_ix]:
|
|
||||||
ndirs -= 1
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
up_from_db = '../'*ndirs
|
|
||||||
obj_dir_rem = os.path.sep.join(obj_dir_list[len(db_dir_list)-ndirs:])
|
|
||||||
return os.path.join(up_from_db,obj_dir_rem,obj_name)
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user