def test_mediapath(self): """ Test media path variables. """ # Create database dbstate = DbState() db = dbstate.make_database("bsddb") path = get_empty_tempdir("utils_file_test") db.write_version(path) db.load(path) dbstate.change_database(db) # Test without db.mediapath set self.assertEqual(media_path(db), os.path.normcase(os.path.normpath(os.path.abspath(USER_HOME)))) self.assertTrue(os.path.exists(media_path(db))) # Test with absolute db.mediapath db.set_mediapath(os.path.abspath(USER_HOME) + "/test_abs") self.assertEqual(media_path(db), os.path.normcase(os.path.normpath(os.path.abspath(USER_HOME + "/test_abs")))) # Test with relative db.mediapath db.set_mediapath("test_rel") self.assertEqual( media_path(db), os.path.normcase(os.path.normpath(os.path.abspath(TEMP_DIR + "/utils_file_test/test_rel"))) ) # Test with environment variable db.set_mediapath("/test/{VERSION}/test_var") self.assertEqual( media_path(db), os.path.normcase(os.path.normpath(os.path.abspath("/test/" + VERSION + "/test_var"))) ) db.set_mediapath("{USER_PLUGINS}/test_var") self.assertEqual( media_path(db), os.path.normcase(os.path.normpath(os.path.abspath(USER_PLUGINS + "/test_var"))) ) db.set_mediapath("{VERSION}/test_var") self.assertEqual( media_path(db), os.path.normcase(os.path.normpath(os.path.abspath(TEMP_DIR + "/utils_file_test/" + VERSION + "/test_var"))), ) # Test with $GRAMPSHOME environment variable not set old_env = os.environ.copy() if "GRAMPSHOME" in os.environ: del os.environ["GRAMPSHOME"] db.set_mediapath("{GRAMPSHOME}/test_var") self.assertEqual(media_path(db), os.path.normcase(os.path.normpath(os.path.abspath(USER_HOME + "/test_var")))) # Test with $GRAMPSHOME environment variable set os.environ["GRAMPSHOME"] = "/this/is/a/test" db.set_mediapath("{GRAMPSHOME}/test_var") self.assertEqual( media_path(db), os.path.normcase(os.path.normpath(os.path.abspath("/this/is/a/test/test_var"))) ) # Restore environment os.environ = old_env
def drag_data_received(self, widget, context, x, y, sel_data, info, time): """ Handle the standard gtk interface for drag_data_received. If the selection data is define, extract the value from sel_data.data, and decide if this is a move or a reorder. The only data we accept on mediaview is dropping a file, so URI_LIST. We assume this is what we obtain """ if not sel_data: return files = sel_data.get_uris() for file in files: protocol, site, mfile, j, k, l = urlparse(file) if protocol == "file": name = url2pathname(mfile) mime = get_type(name) if not is_valid_type(mime): return photo = Media() self.uistate.set_busy_cursor(True) photo.set_checksum(create_checksum(name)) self.uistate.set_busy_cursor(False) base_dir = str(media_path(self.dbstate.db)) if os.path.exists(base_dir): name = relative_path(name, base_dir) photo.set_path(name) photo.set_mime_type(mime) basename = os.path.basename(name) (root, ext) = os.path.splitext(basename) photo.set_description(root) with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans: self.dbstate.db.add_media(photo, trans) widget.emit_stop_by_name('drag_data_received')
def drag_data_received(self, widget, context, x, y, sel_data, info, time): """ Handle the standard gtk interface for drag_data_received. If the selection data is define, extract the value from sel_data.data, and decide if this is a move or a reorder. The only data we accept on mediaview is dropping a file, so URI_LIST. We assume this is what we obtain """ if not sel_data: return files = sel_data.get_uris() for file in files: protocol, site, mfile, j, k, l = urlparse(file) if protocol == "file": name = url2pathname(mfile) mime = get_type(name) if not is_valid_type(mime): return photo = MediaObject() self.uistate.set_busy_cursor(True) photo.set_checksum(create_checksum(name)) self.uistate.set_busy_cursor(False) base_dir = str(media_path(self.dbstate.db)) if os.path.exists(base_dir): name = relative_path(name, base_dir) photo.set_path(name) photo.set_mime_type(mime) basename = os.path.basename(name) (root, ext) = os.path.splitext(basename) photo.set_description(root) with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans: self.dbstate.db.add_object(photo, trans) widget.emit_stop_by_name('drag_data_received')
def _photo(self, photo, level): """ Overloaded media-handling method to skip over media if not included. """ # LOG.debug("deb photo %d" % self.relativepath) if self.include_media: photo_obj_id = photo.get_reference_handle() photo_obj = self.dbase.get_media_from_handle(photo_obj_id) if photo_obj: mime = photo_obj.get_mime_type() form = MIME2GED.get(mime, mime) if self.relativepath: fullpath = media_path_full(self.dbase, photo_obj.get_path()) if not os.path.isfile(fullpath): return base = media_path(self.dbase) path = relative_path(fullpath, base) else: path = media_path_full(self.dbase, photo_obj.get_path()) if not os.path.isfile(path): return self._writeln(level, 'OBJE') if form: self._writeln(level + 1, 'FORM', form) self._writeln(level + 1, 'TITL', photo_obj.get_description()) self._writeln(level + 1, 'FILE', path, limit=255) self._note_references(photo_obj.get_note_list(), level + 1) if self.zip: self._packzip(path)
def _run(self): if not self.prepared: self.prepare() self.set_total(len(self.handle_list)) base_dir = media_path(self.db) for handle in self.handle_list: obj = self.db.get_media_from_handle(handle) new_path = relative_path(obj.path, base_dir) obj.set_path(new_path) self.db.commit_media(obj, self.trans) self.update() return True
def save(self, *obj): """ Callback function called when the save button is pressed. The media object is updated, and callback called. """ description = str(self.description.get_text()) if self.file_text.get_filename() is None: msgstr = _("Import failed") msgstr2 = _("The filename supplied could not be found.") ErrorDialog(msgstr, msgstr2, parent=self.window) return filename = self.file_text.get_filename() full_file = filename if self.relpath.get_active(): pname = str(media_path(self.dbase)) if not os.path.exists(pname): msgstr = _("Cannot import %s") msgstr2 = _("Directory specified in preferences: " "Base path for relative media paths: " "%s does not exist. Change preferences " "or do not use relative path when importing") ErrorDialog(msgstr % filename, msgstr2 % pname, parent=self.window) return filename = relative_path(filename, pname) mtype = get_type(full_file) description = description or os.path.basename(filename) self.obj.set_description(description) self.obj.set_mime_type(mtype) name = filename self.obj.set_path(name) self.last_directory = os.path.dirname(full_file) self.relative_path = self.relpath.get_active() self._cleanup_on_exit() if self.callback: self.callback(self.obj) self.close()
def drag_data_received(self, widget, context, x, y, sel_data, info, time): """ Handle the standard gtk interface for drag_data_received. If the selection data is define, extract the value from sel_data.data, and decide if this is a move or a reorder. """ if sel_data and sel_data.get_data(): try: (mytype, selfid, obj, row_from) = pickle.loads(sel_data.get_data()) # make sure this is the correct DND type for this object if mytype == self._DND_TYPE.drag_type: # determine the destination row data = self.iconlist.get_dest_item_at_pos(x, y) if data: (path, pos) = data row = path.get_indices()[0] if pos == Gtk.IconViewDropPosition.DROP_LEFT: row = max(row, 0) elif pos == Gtk.IconViewDropPosition.DROP_RIGHT: row = min(row, len(self.get_data())) elif pos == Gtk.IconViewDropPosition.DROP_INTO: row = min(row+1, len(self.get_data())) else: row = len(self.get_data()) # if the is same object, we have a move, otherwise, # it is a standard drag-n-drop if id(self) == selfid: self._move(row_from, row, obj) else: self._handle_drag(row, obj) self.rebuild() elif mytype == DdTargets.MEDIAOBJ.drag_type: oref = MediaRef() oref.set_reference_handle(obj) self.get_data().append(oref) self.changed = True self.rebuild() elif self._DND_EXTRA and mytype == self._DND_EXTRA.drag_type: self.handle_extra_type(mytype, obj) except pickle.UnpicklingError: files = sel_data.get_uris() for file in files: protocol, site, mfile, j, k, l = urlparse(file) if protocol == "file": name = url2pathname(mfile) mime = get_type(name) if not is_valid_type(mime): return photo = MediaObject() self.uistate.set_busy_cursor(True) photo.set_checksum(create_checksum(name)) self.uistate.set_busy_cursor(False) base_dir = str(media_path(self.dbstate.db)) if os.path.exists(base_dir): name = relative_path(name, base_dir) photo.set_path(name) photo.set_mime_type(mime) basename = os.path.basename(name) (root, ext) = os.path.splitext(basename) photo.set_description(root) with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans: self.dbstate.db.add_object(photo, trans) oref = MediaRef() oref.set_reference_handle(photo.get_handle()) self.get_data().append(oref) self.changed = True self.rebuild()
def drag_data_received(self, widget, context, x, y, sel_data, info, time): """ Handle the standard gtk interface for drag_data_received. If the selection data is define, extract the value from sel_data.data, and decide if this is a move or a reorder. """ if sel_data and sel_data.get_data(): try: (mytype, selfid, obj, row_from) = pickle.loads(sel_data.get_data()) # make sure this is the correct DND type for this object if mytype == self._DND_TYPE.drag_type: # determine the destination row data = self.iconlist.get_dest_item_at_pos(x, y) if data: (path, pos) = data row = path.get_indices()[0] if pos == Gtk.IconViewDropPosition.DROP_LEFT: row = max(row, 0) elif pos == Gtk.IconViewDropPosition.DROP_RIGHT: row = min(row, len(self.get_data())) elif pos == Gtk.IconViewDropPosition.DROP_INTO: row = min(row + 1, len(self.get_data())) else: row = len(self.get_data()) # if the is same object, we have a move, otherwise, # it is a standard drag-n-drop if id(self) == selfid: self._move(row_from, row, obj) else: self._handle_drag(row, obj) self.rebuild() elif mytype == DdTargets.MEDIAOBJ.drag_type: oref = MediaRef() oref.set_reference_handle(obj) self.get_data().append(oref) self.changed = True self.rebuild() elif self._DND_EXTRA and mytype == self._DND_EXTRA.drag_type: self.handle_extra_type(mytype, obj) except pickle.UnpicklingError: files = sel_data.get_uris() for file in files: protocol, site, mfile, j, k, l = urlparse(file) if protocol == "file": name = url2pathname(mfile) mime = get_type(name) if not is_valid_type(mime): return photo = MediaObject() self.uistate.set_busy_cursor(True) photo.set_checksum(create_checksum(name)) self.uistate.set_busy_cursor(False) base_dir = str(media_path(self.dbstate.db)) if os.path.exists(base_dir): name = relative_path(name, base_dir) photo.set_path(name) photo.set_mime_type(mime) basename = os.path.basename(name) (root, ext) = os.path.splitext(basename) photo.set_description(root) with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans: self.dbstate.db.add_object(photo, trans) oref = MediaRef() oref.set_reference_handle(photo.get_handle()) self.get_data().append(oref) self.changed = True self.rebuild()
def test_mediapath(self): """ Test media path variables. """ # Create database dbstate = DbState() db = dbstate.make_database("bsddb") path = get_empty_tempdir("utils_file_test") db.write_version(path) db.load(path) dbstate.change_database(db) # Test without db.mediapath set self.assertEqual( media_path(db), os.path.normcase(os.path.normpath(os.path.abspath(USER_HOME)))) self.assertTrue(os.path.exists(media_path(db))) # Test with absolute db.mediapath db.set_mediapath(os.path.abspath(USER_HOME) + "/test_abs") self.assertEqual( media_path(db), os.path.normcase( os.path.normpath(os.path.abspath(USER_HOME + "/test_abs")))) # Test with relative db.mediapath db.set_mediapath("test_rel") self.assertEqual( media_path(db), os.path.normcase( os.path.normpath( os.path.abspath(TEMP_DIR + "/utils_file_test/test_rel")))) # Test with environment variable db.set_mediapath("/test/{VERSION}/test_var") self.assertEqual( media_path(db), os.path.normcase( os.path.normpath( os.path.abspath("/test/" + VERSION + "/test_var")))) db.set_mediapath("{USER_PLUGINS}/test_var") self.assertEqual( media_path(db), os.path.normcase( os.path.normpath(os.path.abspath(USER_PLUGINS + "/test_var")))) db.set_mediapath("{VERSION}/test_var") self.assertEqual( media_path(db), os.path.normcase( os.path.normpath( os.path.abspath(TEMP_DIR + "/utils_file_test/" + VERSION + "/test_var")))) # Test with $GRAMPSHOME environment variable not set old_env = os.environ.copy() if 'GRAMPSHOME' in os.environ: del os.environ['GRAMPSHOME'] db.set_mediapath("{GRAMPSHOME}/test_var") self.assertEqual( media_path(db), os.path.normcase( os.path.normpath(os.path.abspath(USER_HOME + "/test_var")))) # Test with $GRAMPSHOME environment variable set os.environ['GRAMPSHOME'] = "/this/is/a/test" db.set_mediapath("{GRAMPSHOME}/test_var") self.assertEqual( media_path(db), os.path.normcase( os.path.normpath(os.path.abspath("/this/is/a/test/test_var")))) # Restore environment os.environ = old_env
def impData(database, name, user): # Create tempdir, if it does not exist, then check for writability # THE TEMP DIR is named as the filname.gpkg.media and is created # in the mediapath dir of the family tree we import to oldmediapath = database.get_mediapath() #use home dir if no media path my_media_path = media_path(database) media_dir = "%s.media" % os.path.basename(name) tmpdir_path = os.path.join(my_media_path, media_dir) if not os.path.isdir(tmpdir_path): try: os.mkdir(tmpdir_path, 0o700) except: user.notify_error( _("Could not create media directory %s") % tmpdir_path ) return elif not os.access(tmpdir_path, os.W_OK): user.notify_error(_("Media directory %s is not writable") % tmpdir_path) return else: # mediadir exists and writable -- User could have valuable stuff in # it, have him remove it! user.notify_error(_("Media directory %s exists. Delete it first, then" " restart the import process") % tmpdir_path) return try: archive = tarfile.open(name) for tarinfo in archive: archive.extract(tarinfo, tmpdir_path) archive.close() except: user.notify_error(_("Error extracting into %s") % tmpdir_path) return imp_db_name = os.path.join(tmpdir_path, XMLFILE) importer = importData database.prepare_import() info = importer(database, imp_db_name, user) database.commit_import() newmediapath = database.get_mediapath() #import of gpkg should not change media path as all media has new paths! if not oldmediapath == newmediapath : database.set_mediapath(oldmediapath) # Set correct media dir if possible, complain if problems if oldmediapath is None: database.set_mediapath(tmpdir_path) user.warn( _("Base path for relative media set"), _("The base media path of this Family Tree has been set to " "%s. Consider taking a simpler path. You can change this " "in the Preferences, while moving your media files to the " "new position, and using the media manager tool, option " "'Replace substring in the path' to set" " correct paths in your media objects." ) % tmpdir_path) else: user.warn( _("Cannot set base media path"), _("The Family Tree you imported into already has a base media " "path: %(orig_path)s. The imported media objects however " "are relative from the path %(path)s. You can change the " "media path in the Preferences or you can convert the " "imported files to the existing base media path. You can " "do that by moving your media files to the " "new position, and using the media manager tool, option " "'Replace substring in the path' to set" " correct paths in your media objects." ) % {'orig_path': oldmediapath, 'path': tmpdir_path} ) # Remove xml file extracted to media dir we imported from os.remove(imp_db_name) return info
def impData(database, name, user): # Create tempdir, if it does not exist, then check for writability # THE TEMP DIR is named as the filname.gpkg.media and is created # in the mediapath dir of the family tree we import to oldmediapath = database.get_mediapath() #use home dir if no media path my_media_path = media_path(database) media_dir = "%s.media" % os.path.basename(name) tmpdir_path = os.path.join(my_media_path, media_dir) if not os.path.isdir(tmpdir_path): try: os.mkdir(tmpdir_path, 0o700) except: user.notify_error( _("Could not create media directory %s") % tmpdir_path ) return elif not os.access(tmpdir_path, os.W_OK): user.notify_error(_("Media directory %s is not writable") % tmpdir_path) return else: # mediadir exists and writable -- User could have valuable stuff in # it, have him remove it! user.notify_error(_("Media directory %s exists. Delete it first, then" " restart the import process") % tmpdir_path) return try: archive = tarfile.open(name) for tarinfo in archive: archive.extract(tarinfo, tmpdir_path) archive.close() except: user.notify_error(_("Error extracting into %s") % tmpdir_path) return imp_db_name = os.path.join(tmpdir_path, XMLFILE) importer = importData info = importer(database, imp_db_name, user) newmediapath = database.get_mediapath() #import of gpkg should not change media path as all media has new paths! if not oldmediapath == newmediapath : database.set_mediapath(oldmediapath) # Set correct media dir if possible, complain if problems if oldmediapath is None: database.set_mediapath(tmpdir_path) user.warn( _("Base path for relative media set"), _("The base media path of this Family Tree has been set to " "%s. Consider taking a simpler path. You can change this " "in the Preferences, while moving your media files to the " "new position, and using the media manager tool, option " "'Replace substring in the path' to set" " correct paths in your media objects." ) % tmpdir_path) else: user.warn( _("Cannot set base media path"), _("The Family Tree you imported into already has a base media " "path: %(orig_path)s. The imported media objects however " "are relative from the path %(path)s. You can change the " "media path in the Preferences or you can convert the " "imported files to the existing base media path. You can " "do that by moving your media files to the " "new position, and using the media manager tool, option " "'Replace substring in the path' to set" " correct paths in your media objects." ) % {'orig_path': oldmediapath, 'path': tmpdir_path} ) # Remove xml file extracted to media dir we imported from os.remove(imp_db_name) return info