示例#1
0
    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
示例#2
0
    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')
示例#3
0
    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')
示例#4
0
 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)
示例#5
0
 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
示例#6
0
 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
示例#7
0
    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()
示例#8
0
    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()
示例#9
0
    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()
示例#10
0
    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()
示例#11
0
    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
示例#12
0
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
示例#13
0
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