Ejemplo n.º 1
0
 def _errordialog(self, title, errormessage):
     """
     Show the error. A title for the error and an errormessage
     Inherit for GUI action
     """
     print _('ERROR: %s') % errormessage
     sys.exit(1)
Ejemplo n.º 2
0
    def __handle_import_option(self, value, family_tree_format):
        """
        Handle the "-i" or "--import" option.
        Only Files supported by a plugin can be imported, so not Family Trees.
        """
        # Need to convert path/filename to unicode before openingh
		# For non latin characters in Windows path/file/user names
        value = Utils.get_unicode_path_from_env_var(value)
        fname = value
        fullpath = os.path.abspath(os.path.expanduser(fname))
        if not os.path.exists(fullpath):
            self.__error(_('Error: Import file %s not found.') % fname)
            sys.exit(0)
        
        if family_tree_format is None:
            # Guess the file format based on the file extension.
            # This will get the lower case extension without a period, 
            # or an empty string.
            family_tree_format = os.path.splitext(fname)[-1][1:].lower()

        pmgr = BasePluginManager.get_instance()
        plugin_found = False
        for plugin in pmgr.get_import_plugins():
            if family_tree_format == plugin.get_extension():
                plugin_found = True
                
        if plugin_found:
            self.imports.append((fname, family_tree_format))
        else:
            self.__error(_('Error: Unrecognized type: "%(format)s" for '
                    'import file: %(filename)s') \
                  % {'format' : family_tree_format, 
                     'filename' : fname})
            sys.exit(0)
Ejemplo n.º 3
0
 def _dberrordialog(self, msg):
     """
     Show a database error. 
     @param: msg : an error message
     @type: string
     @note: Inherit for GUI action
     """
     self._errordialog( '', _("Low level database corruption detected") 
         + '\n' +
         _("Gramps has detected a problem in the underlying "
           "Berkeley database. This can be repaired by from "
           "the Family Tree Manager. Select the database and "
           'click on the Repair button') + '\n\n' + str(msg))
Ejemplo n.º 4
0
 def check_db(self, dbpath, force_unlock = False):
     """
     Test a given family tree path if it can be opened.
     """
     # Test if not locked or problematic
     if force_unlock:
         self.dbman.break_lock(dbpath)
     if self.dbman.is_locked(dbpath):
         self.__error((_("Database is locked, cannot open it!") + '\n' +
                       _("  Info: %s")) % find_locker_name(dbpath))
         return False
     if self.dbman.needs_recovery(dbpath):
         self.__error( _("Database needs recovery, cannot open it!"))
         return False
     return True
Ejemplo n.º 5
0
    def import_new_db(self, filename, callback):
        """
        Attempt to import the provided file into a new database.
        A new database will only be created if an appropriate importer was 
        found.
        
        @return: A tuple of (new_path, name) for the new database
                 or (None, None) if no import was performed.
        """
        pmgr = BasePluginManager.get_instance()
        (name, ext) = os.path.splitext(os.path.basename(filename))
        format = ext[1:].lower()

        for plugin in pmgr.get_import_plugins():
            if format == plugin.get_extension():

                new_path, name = self._create_new_db(name)
    
                # Create a new database
                self.__start_cursor(_("Importing data..."))
                dbclass = gen.db.DbBsddb
                dbase = dbclass()
                dbase.load(new_path, callback)
    
                import_function = plugin.get_import_function()
                import_function(dbase, filename, callback)
    
                # finish up
                self.__end_cursor()
                dbase.close()
                
                return new_path, name
        return None, None
Ejemplo n.º 6
0
    def parse_args(self):
        """
        Fill in lists with open, exports, imports, and actions options.

        Any errors are added to self.errors
        
        Possible: 
        1/ Just the family tree (name or database dir)
        2/ -O, --open:   Open of a family tree
        3/ -i, --import: Import a family tree of any format understood by an importer, 
                 optionally provide-f to indicate format
        4/ -e, --export: export a family tree in required format, optionally provide
                 -f to indicate format
        5/ -f, --format=FORMAT : format after a -i or -e option
        6/ -a, --action: An action (possible: 'check', 'summary', 'report', 
                            'tool')
        7/ -u, --force-unlock: A locked database can be unlocked by giving this
                argument when opening it
                            
        """
        try:
            # Convert arguments to unicode, otherwise getopt will not work
            # if a non latin character is used as an option (by mistake).
            # getopt will try to treat the first char in an utf-8 sequence. Example:
            # -Ärik is '-\xc3\x84rik' and getopt will respond :
            # option -\xc3 not recognized
            for arg in range(len(self.args) - 1):
                self.args[arg+1] = Utils.get_unicode_path_from_env_var(self.args[arg + 1])
            options, leftargs = getopt.getopt(self.args[1:],
                                             const.SHORTOPTS, const.LONGOPTS)
        except getopt.GetoptError, msg:
            # Extract the arguments in the list.
            # The % operator replaces the list elements with repr() of the list elemements
            # which is OK for latin characters, but not for non latin characters in list elements
            cliargs = "[ "
            for arg in range(len(self.args) - 1):
                cliargs += self.args[arg + 1] + " "
            cliargs += "]"
            # Must first do str() of the msg object.
            msg = unicode(str(msg))
            self.errors += [(_('Error parsing the arguments'), 
                        msg + '\n' +
                        _("Error parsing the arguments: %s \n" 
                        "Type gramps --help for an overview of commands, or "
                        "read the manual pages.") % cliargs)]
            return
Ejemplo n.º 7
0
    def __handle_export_option(self, value, family_tree_format):
        """
        Handle the "-e" or "--export" option.  
        Note: this can only happen in the CLI version.                    
        """
        if self.gui:
            return
        # Need to covert path/filename to unicode before openingh
		# For non latin characters in Windows path/file/user names
        value = Utils.get_unicode_path_from_env_var(value)
        fname = value
        fullpath = os.path.abspath(os.path.expanduser(fname))
        if os.path.exists(fullpath):
            self.__error(_("WARNING: Output file already exists!\n"
                    "WARNING: It will be overwritten:\n   %(name)s") % \
                    {'name' : fullpath})
            answer = None
            while not answer:
                answer = raw_input(_('OK to overwrite? (yes/no) ') \
                                    .encode(sys.getfilesystemencoding()))
            if answer.upper() in ('Y', 'YES', _('YES').upper()):
                self.__error( _("Will overwrite the existing file: %s") 
                                % fullpath)
            else:
                sys.exit(0)

        if family_tree_format is None:
            # Guess the file format based on the file extension.
            # This will get the lower case extension without a period, 
            # or an empty string.
            family_tree_format = os.path.splitext(fname)[-1][1:].lower()

        pmgr = BasePluginManager.get_instance()
        plugin_found = False
        for plugin in pmgr.get_export_plugins():
            if family_tree_format == plugin.get_extension():
                plugin_found = True
                
        if plugin_found:
            self.exports.append((fullpath, family_tree_format))
        else:
            self.__error(_("ERROR: Unrecognized format for export file %s") 
                            % fname)
            sys.exit(0)
Ejemplo n.º 8
0
def make_dbdir(dbdir):
    """
    Create the default database directory, as defined by dbdir
    """
    try:
        if not os.path.isdir(dbdir):
            os.makedirs(dbdir)
    except (IOError, OSError), msg:
        msg = unicode(str(msg), sys.getfilesystemencoding())
        LOG.error(_("Could not make database directory: ") + msg)
Ejemplo n.º 9
0
    def draw_window(self):
        """Draw the bookmark dialog box."""
        title = _("%(title)s - Gramps") % {'title': _("Organize Bookmarks")}
        self.top = gtk.Dialog(title)
        self.top.set_default_size(400, 350)
        self.top.set_modal(True)
        self.top.set_transient_for(self.uistate.window)
        self.top.set_has_separator(False)
        self.top.vbox.set_spacing(5)
        label = gtk.Label('<span size="larger" weight="bold">%s</span>'
                          % _("Organize Bookmarks"))
        label.set_use_markup(True)
        self.top.vbox.pack_start(label, 0, 0, 5)
        box = gtk.HBox()
        self.top.vbox.pack_start(box, 1, 1, 5)
        
        name_titles = [(_('Name'), -1, 200), (_('ID'), -1, 50), ('', -1, 0)]
        self.namelist = gtk.TreeView()
        self.namemodel = ListModel.ListModel(self.namelist, name_titles)
        self.namemodel_cols = len(name_titles)

        slist = gtk.ScrolledWindow()
        slist.add_with_viewport(self.namelist)
        slist.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        box.pack_start(slist, 1, 1, 5)
        bbox = gtk.VButtonBox()
        bbox.set_layout(gtk.BUTTONBOX_START)
        bbox.set_spacing(6)
        up = gtk.Button(stock=gtk.STOCK_GO_UP)
        down = gtk.Button(stock=gtk.STOCK_GO_DOWN)
        delete = gtk.Button(stock=gtk.STOCK_REMOVE)
        up.connect('clicked', self.up_clicked)
        down.connect('clicked', self.down_clicked)
        delete.connect('clicked', self.delete_clicked)
        self.top.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
        self.top.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
        self.top.connect('delete-event', self.close)
        bbox.add(up)
        bbox.add(down)
        bbox.add(delete)
        box.pack_start(bbox, 0, 0, 5)
        self.top.show_all()
Ejemplo n.º 10
0
def startcli(errors, argparser):
    """
    Starts a cli session of GRAMPS. 
    errors    : errors already encountered 
    argparser : ArgParser instance
    """
    if errors:
        #already errors encountered. Show first one on terminal and exit
        # Convert error message to file system encoding before print
        errmsg = _('Error encountered: %s') % errors[0][0]
        errmsg = errmsg.encode(sys.getfilesystemencoding())
        print errmsg
        errmsg = _('  Details: %s') % errors[0][1]
        errmsg = errmsg.encode(sys.getfilesystemencoding())
        print errmsg
        sys.exit(1)
    
    if argparser.errors: 
        # Convert error message to file system encoding before print
        errmsg = _('Error encountered in argument parsing: %s') \
                                                    % argparser.errors[0][0]
        errmsg = errmsg.encode(sys.getfilesystemencoding())
        print errmsg
        errmsg = _('  Details: %s') % argparser.errors[0][1]
        errmsg = errmsg.encode(sys.getfilesystemencoding())
        print errmsg
        sys.exit(1)
    
    #we need to keep track of the db state
    dbstate = DbState.DbState()
    #we need a manager for the CLI session
    climanager = CLIManager(dbstate, True)
    #load the plugins
    climanager.do_reg_plugins()
    # handle the arguments
    from arghandler import ArgHandler
    handler = ArgHandler(dbstate, argparser, climanager)
    # create a manager to manage the database
    
    handler.handle_args_cli()
    
    sys.exit(0)
Ejemplo n.º 11
0
def find_locker_name(dirpath):
    """
    Opens the lock file if it exists, reads the contexts which is "USERNAME"
    and returns the contents, with correct string before "USERNAME",
    so the message can be printed with correct locale.
    If a file is encountered with errors, we return 'Unknown'
    This data can eg be displayed in the time column of the manager
    """
    try:
        fname = os.path.join(dirpath, "lock")
        ifile = open(fname)
        username = ifile.read().strip()
        # Convert username to unicode according to system encoding
        # Otherwise problems with non ASCII characters in
        # username in Windows
        username = unicode(username, sys.getfilesystemencoding())
        last = _("Locked by %s") % username
        ifile.close()
    except (OSError, IOError):
        last = _("Unknown")
    return last
Ejemplo n.º 12
0
    def read_file(self, filename):
        """
        This method takes care of changing database, and loading the data.
        In 3.0 we only allow reading of real databases of filetype 
        'x-directory/normal'
        
        This method should only return on success.
        Returning on failure makes no sense, because we cannot recover,
        since database has already beeen changed.
        Therefore, any errors should raise exceptions.

        On success, return with the disabled signals. The post-load routine
        should enable signals, as well as finish up with other UI goodies.
        """

        if os.path.exists(filename):
            if not os.access(filename, os.W_OK):
                mode = "r"
                self._warn(_('Read only database'), 
                                             _('You do not have write access '
                                               'to the selected file.'))
            else:
                mode = "w"
        else:
            mode = 'w'

        dbclass = DbBsddb
        
        self.dbstate.change_database(dbclass())
        self.dbstate.db.disable_signals()

        self._begin_progress()
        
        try:
            self.dbstate.db.load(filename, self._pulse_progress, mode)
            self.dbstate.db.set_save_path(filename)
        except gen.db.exceptions.DbUpgradeRequiredError, msg:
            self.dbstate.no_database()
            self._errordialog( _("Cannot open database"), str(msg))
Ejemplo n.º 13
0
    def _read_recent_file(self, filename):
        """
        Called when a file needs to be loaded
        """
        # A recent database should already have a directory If not, do nothing,
        #  just return. This can be handled better if family tree delete/rename
        #  also updated the recent file menu info in DisplayState.py
        if not  os.path.isdir(filename):
            self._errordialog(
                    _("Could not load a recent Family Tree."), 
                    _("Family Tree does not exist, as it has been deleted."))
            return

        if self.db_loader.read_file(filename):
            # Attempt to figure out the database title
            path = os.path.join(filename, "name.txt")
            try:
                ifile = open(path)
                title = ifile.readline().strip()
                ifile.close()
            except:
                title = filename

            self._post_load_newdb(filename, 'x-directory/normal', title)
Ejemplo n.º 14
0
 def __handle_open_option(self, value):
     """
     Handle the "-O" or "--open" option.
     Only Family trees or a dir with a family tree can be opened.                  
     """
     if value is None:
         return None
     value = Utils.get_unicode_path_from_env_var(value)
     db_path = self.__deduce_db_path(value)
     if db_path:
         # We have a potential database path.
         # Check if it is good.
         if not self.check_db(db_path, self.force_unlock):
             sys.exit(0)
         return db_path
     else:
         self.__error( _('Error: Input family tree "%s" does not exist.\n'
                 "If GEDCOM, Gramps-xml or grdb, use the -i option to "
                 "import into a family tree instead.") % value)
         sys.exit(0)
Ejemplo n.º 15
0
def time_val(dirpath):
    """
    Return the last modified time of the database. We do this by looking
    at the modification time of the meta db file. If this file does not 
    exist, we indicate that database as never modified.
    """
    meta = os.path.join(dirpath, META_NAME)
    if os.path.isfile(meta):
        tval = os.stat(meta)[9]
        # This gives creation date in Windows, but correct date in Linux
        if constfunc.win():
            # Try to use last modified date instead in Windows
            # and check that it is later than the creation date.
            tval_mod = os.stat(meta)[8]
            if tval_mod > tval:
                tval = tval_mod
        last = time.strftime('%x %X', time.localtime(tval))
    else:
        tval = 0
        last = _("Never")
    return (tval, last)
Ejemplo n.º 16
0
 def build_menu_names(self, source):
     return (_('Edit Source'), self.get_menu_title())
Ejemplo n.º 17
0
        "Getting started",
        "Welcome to Gramps, the Genealogical Research "
        "and Analysis Management Programming System.\n"
        "Several options and information need to be gathered "
        "before Gramps is ready to be used. Any of this "
        "information can be changed in the future in the "
        "Preferences dialog under the Settings menu.",
    )

    box = gtk.VBox()
    box.set_spacing(12)
    table = gtk.Table(8, 4)
    table.set_row_spacings(6)
    table.set_col_spacings(6)

    make_label(table, _("Name:"), 0, 0, 1, 1, 4)
    make_label(table, _("Address:"), 1, 0, 1, 1, 4)
    make_label(table, _("City:"), 2, 0, 1, 1, 2)
    make_label(table, _("State/Province:"), 2, 2, 3, 3, 4)
    make_label(table, _("Country:"), 3, 0, 1, 1, 2)
    make_label(table, _("ZIP/Postal code:"), 3, 2, 3, 3, 4)
    make_label(table, _("Phone:"), 4, 0, 1, 1, 4)
    make_label(table, _("Email:"), 5, 0, 1, 1, 4)
    box.add(table)
    a.add_page("Researcher information", box)

    a.add_text_page("Conclusion title", "Very long conclusion text here")
    a.show()

    gtk.main()
Ejemplo n.º 18
0
    def on_apply_clicked(self, obj):
        model, node = self.tree.get_selection().get_selected()
        if not node:
            return

        handle = model.get_value(node, PeopleBaseModel.COLUMN_INT_ID)
        other_person = self.db.get_person_from_handle(handle)
        if other_person is None:
            self.textbuffer.set_text("")
            return

        #now determine the relation, and print it out
        rel_strings, common_an = self.relationship.get_all_relationships(
            self.db, self.person, other_person)

        p1 = name_displayer.display(self.person)
        p2 = name_displayer.display(other_person)

        text = []
        if other_person is None:
            pass
        elif self.person.handle == other_person.handle:
            rstr = _(
                "%(person)s and %(active_person)s are the same person.") % {
                    'person': p1,
                    'active_person': p2
                }
            text.append((rstr, ""))
        elif len(rel_strings) == 0:
            rstr = _("%(person)s and %(active_person)s are not related.") % {
                'person': p2,
                'active_person': p1
            }
            text.append((rstr, ""))

        for rel_string, common in zip(rel_strings, common_an):
            rstr = _(
                "%(person)s is the %(relationship)s of %(active_person)s.") % {
                    'person': p2,
                    'relationship': rel_string,
                    'active_person': p1
                }
            length = len(common)
            if length == 1:
                person = self.db.get_person_from_handle(common[0])
                if common[0] in [other_person.handle, self.person.handle]:
                    commontext = ''
                else:
                    name = name_displayer.display(person)
                    commontext = " " + _("Their common ancestor is %s.") % name
            elif length == 2:
                p1c = self.db.get_person_from_handle(common[0])
                p2c = self.db.get_person_from_handle(common[1])
                p1str = name_displayer.display(p1c)
                p2str = name_displayer.display(p2c)
                commontext = " " + _(
                    "Their common ancestors are %(ancestor1)s and %(ancestor2)s."
                ) % {
                    'ancestor1': p1str,
                    'ancestor2': p2str
                }
            elif length > 2:
                index = 0
                commontext = " " + _("Their common ancestors are: ")
                for person_handle in common:
                    person = self.db.get_person_from_handle(person_handle)
                    if index:
                        commontext += ", "
                    commontext += name_displayer.display(person)
                    index += 1
                commontext += "."
            else:
                commontext = ""
            text.append((rstr, commontext))

        textval = ""
        for val in text:
            textval += "%s %s\n" % (val[0], val[1])
        self.textbuffer.set_text(textval)
Ejemplo n.º 19
0
 def __start_cursor(self, msg):
     """
     Do needed things to start import visually, eg busy cursor
     """
     print _('Starting Import, %s') % msg
Ejemplo n.º 20
0
register('paths.report-directory', const.USER_HOME)
register('paths.website-directory', const.USER_HOME)

register('preferences.complete-color', '#008b00')
register('preferences.custom-marker-color', '#8b008b')
register('preferences.date-format', 0)
register('preferences.calendar-format-report', 0)
register('preferences.default-source', False)
register('preferences.eprefix', 'E%04d')
register('preferences.family-warn', True)
register('preferences.fprefix', 'F%04d')
register('preferences.hide-ep-msg', False)
register('preferences.invalid-date-format', "<b>%s</b>")
register('preferences.iprefix', 'I%04d')
register('preferences.name-format', 1)
register('preferences.no-given-text', "[%s]" % _("Missing Given Name"))
register('preferences.no-record-text', "[%s]" % _("Missing Record"))
register('preferences.no-surname-text', "[%s]" % _("Missing Surname"))
register('preferences.nprefix', 'N%04d')
register('preferences.online-maps', False)
register('preferences.oprefix', 'O%04d')
register('preferences.paper-metric', 0)
register('preferences.paper-preference', 'Letter')
register('preferences.pprefix', 'P%04d')
register('preferences.private-given-text', "[%s]" % _("Living"))
register('preferences.private-record-text', "[%s]" % _("Private Record"))
register('preferences.private-surname-text', "[%s]" % _("Living"))
register('preferences.rprefix', 'R%04d')
register('preferences.sprefix', 'S%04d')
register('preferences.todo-color', '#ff0000')
register('preferences.use-last-view', True)
Ejemplo n.º 21
0
 def get_title(self):
     """
     Return the window title.
     """
     return _("Sort Events")
Ejemplo n.º 22
0
    def make_default_style(self, default_style):
        """Make the default output style for the Statistics report."""
        # Paragraph Styles
        f = FontStyle()
        f.set_size(10)
        f.set_type_face(FONT_SERIF)
        p = ParagraphStyle()
        p.set_font(f)
        p.set_alignment(PARA_ALIGN_LEFT)
        p.set_description(_("The style used for the items and values."))
        default_style.add_paragraph_style("SC-Text", p)

        f = FontStyle()
        f.set_size(14)
        f.set_type_face(FONT_SANS_SERIF)
        p = ParagraphStyle()
        p.set_font(f)
        p.set_alignment(PARA_ALIGN_CENTER)
        p.set_description(_("The style used for the title of the page."))
        default_style.add_paragraph_style("SC-Title", p)
        """
        Graphic Styles:
            SC-title - Contains the SC-Title paragraph style used for
                       the title of the document
            SC-text  - Contains the SC-Name paragraph style used for
                       the individual's name
            SC-color-N - The colors for drawing pies.
            SC-bar - A red bar with 0.5pt black line.
        """
        g = GraphicsStyle()
        g.set_paragraph_style("SC-Title")
        g.set_color((0, 0, 0))
        g.set_fill_color((255, 255, 255))
        g.set_line_width(0)
        default_style.add_draw_style("SC-title", g)

        g = GraphicsStyle()
        g.set_paragraph_style("SC-Text")
        g.set_color((0, 0, 0))
        g.set_fill_color((255, 255, 255))
        g.set_line_width(0)
        default_style.add_draw_style("SC-text", g)

        width = 0.8
        # red
        g = GraphicsStyle()
        g.set_paragraph_style('SC-Text')
        g.set_color((0, 0, 0))
        g.set_fill_color((255, 0, 0))
        g.set_line_width(width)
        default_style.add_draw_style("SC-color-0", g)
        # orange
        g = GraphicsStyle()
        g.set_paragraph_style('SC-Text')
        g.set_color((0, 0, 0))
        g.set_fill_color((255, 158, 33))
        g.set_line_width(width)
        default_style.add_draw_style("SC-color-1", g)
        # green
        g = GraphicsStyle()
        g.set_paragraph_style('SC-Text')
        g.set_color((0, 0, 0))
        g.set_fill_color((0, 178, 0))
        g.set_line_width(width)
        default_style.add_draw_style("SC-color-2", g)
        # violet
        g = GraphicsStyle()
        g.set_paragraph_style('SC-Text')
        g.set_color((0, 0, 0))
        g.set_fill_color((123, 0, 123))
        g.set_line_width(width)
        default_style.add_draw_style("SC-color-3", g)
        # yellow
        g = GraphicsStyle()
        g.set_paragraph_style('SC-Text')
        g.set_color((0, 0, 0))
        g.set_fill_color((255, 255, 0))
        g.set_line_width(width)
        default_style.add_draw_style("SC-color-4", g)
        # blue
        g = GraphicsStyle()
        g.set_paragraph_style('SC-Text')
        g.set_color((0, 0, 0))
        g.set_fill_color((0, 105, 214))
        g.set_line_width(width)
        default_style.add_draw_style("SC-color-5", g)
        # gray
        g = GraphicsStyle()
        g.set_paragraph_style('SC-Text')
        g.set_color((0, 0, 0))
        g.set_fill_color((210, 204, 210))
        g.set_line_width(width)
        default_style.add_draw_style("SC-color-6", g)

        g = GraphicsStyle()
        g.set_color((0, 0, 0))
        g.set_fill_color((255, 0, 0))
        g.set_line_width(width)
        default_style.add_draw_style("SC-bar", g)

        # legend
        g = GraphicsStyle()
        g.set_paragraph_style('SC-Text')
        g.set_color((0, 0, 0))
        g.set_fill_color((255, 255, 255))
        g.set_line_width(0)
        default_style.add_draw_style("SC-legend", g)
Ejemplo n.º 23
0
class AllEvents(Everything):
    """Matches Everyone"""

    name = _('Every event')
    description = _('Matches every event in the database')
Ejemplo n.º 24
0
class ChangedSinceBase(Rule):
    """
    Rule that checks for primary objects changed since a specific time.
    """

    labels      = [ _('Changed after:'), _('but before:') ]
    name        = _('Objects changed after <date time>')
    description = _("Matches object records changed after a specified "
                    "date/time (yyyy-mm-dd hh:mm:ss) or in range, if a second "
                    "date/time is given.")
    category    = _('General filters')

    def add_time(self, date):
        if re.search("\d.*\s+\d{1,2}:\d{2}:\d{2}", date):
            return date
        elif re.search("\d.*\s+\d{1,2}:\d{2}", date):
            return date + ":00"
        elif re.search("\d.*\s+\d{1,2}", date):
            return date + ":00:00"
        elif re.search("\d{4}-\d{1,2}-\d{1,2}", date):
            return date + " 00:00:00"
        elif re.search("\d{4}-\d{1,2}", date):
            return date + "-01 00:00:00"
        elif re.search("\d{4}", date):
            return date + "-01-01 00:00:00"
        else:
            return date

    def time_str_to_sec(self, time_str):
        time_sec = None
        iso_date_time = self.add_time(time_str)
        try:
            time_tup = time.strptime(iso_date_time, "%Y-%m-%d %H:%M:%S")
            time_sec = time.mktime(time_tup)
        except ValueError:
            from QuestionDialog import WarningDialog
            WarningDialog(_("Wrong format of date-time"),
                _("Only date-times in the iso format of yyyy-mm-dd "
                  "hh:mm:ss, where the time part is optional, are "
                  "accepted. %s does not satisfy.") % iso_date_time)
        return time_sec

    def prepare(self, db):
        self.since = None
        self.before = None
        if self.list[0]:
            self.since = self.time_str_to_sec(self.list[0])
        if self.list[1]:
            self.before = self.time_str_to_sec(self.list[1])

    def apply(self, db, obj):
        obj_time = obj.get_change_time()
        if self.since:
            if obj_time < self.since:
                return False
            if self.before:
                return obj_time < self.before
            return True
        if self.before:
            return obj_time < self.before
        return False
Ejemplo n.º 25
0
 def get_window_title(self):
     return _("Select Source or Citation")
Ejemplo n.º 26
0
class HasNameOf(Rule):
    """Rule that checks for full or partial name matches"""

    labels      =  [_('Given name:'),
                    _('Full Family name:'),
                    _('person|Title:'),
                    _('Suffix:'),
                    _('Call Name:'),
                    _('Nick Name:'),
                    _('Prefix:'),
                    _('Single Surname:'),
                    _('Connector'),
                    _('Patronymic:'),
                    _('Family Nick Name:')]
    name        = _('People with the <name>')
    description = _("Matches people with a specified (partial) name")
    category    = _('General filters')
    allow_regex = True

    def apply(self, db, person):
        for name in [person.get_primary_name()] + person.get_alternate_names():
            if self.match_name(name):
                return True
        return False

    def match_name(self, name):
        if self.list[0] and not self.match_substring(0, name.get_first_name()):
            return False
        elif self.list[1] and not self.match_substring(1, name.get_surname()):
            return False
        elif self.list[2] and not self.match_substring(2, name.get_title()):
            return False
        elif self.list[3] and not self.match_substring(3, name.get_suffix()):
            return False
        elif self.list[4] and not self.match_substring(4, name.get_call_name()):
            return False
        elif self.list[5] and not self.match_substring(5, name.get_nick_name()):
            return False
        elif self.list[10] and not self.match_substring(10, name.get_family_nick_name()):
            return False
        else:
            for surn in name.get_surname_list():
                if self.match_surname(surn):
                    return True
        return False

    def match_surname(self, surn):
        if self.list[6] and not self.match_substring(6, surn.get_prefix()):
            return False
        if self.list[7] and not self.match_substring(7, surn.get_surname()):
            return False
        if self.list[8] and not self.match_substring(8, surn.get_connector()):
            return False
        if surn.get_origintype().value == NameOriginType.PATRONYMIC:
            if self.list[9] and not self.match_substring(9, surn.get_surname()):
                return False
        return True
Ejemplo n.º 27
0
class MediaPrivate(IsPrivate):
    """Media marked private"""

    name = _('Media objects marked private')
    description = _("Matches Media objects that are indicated as private")
Ejemplo n.º 28
0
def sanitize_person(db, person):
    """
    Create a new Person instance based off the passed Person
    instance. The returned instance has all private records
    removed from it.
    
    @param db: GRAMPS database to which the Person object belongs
    @type db: DbBase
    @param person: source Person object that will be copied with
    privacy records removed
    @type person: Person
    @returns: 'cleansed' Person object
    @rtype: Person
    """
    new_person = Person()

    # copy gender
    new_person.set_gender(person.get_gender())
    new_person.set_gramps_id(person.get_gramps_id())
    new_person.set_handle(person.get_handle())
    new_person.set_change_time(person.get_change_time())
    new_person.set_tag_list(person.get_tag_list())

    # copy names if not private
    name = person.get_primary_name()
    if (name and name.get_privacy()) or (person and person.get_privacy()):
        # Do this so a person always has a primary name of some sort.
        name = Name()
        surn = Surname()
        surn.set_surname(_('Private'))
        name.set_surname_list([surn])
        name.set_primary_surname()
    else:
        name = sanitize_name(db, name)
    new_person.set_primary_name(name)

    # copy Family reference list
    for handle in person.get_family_handle_list():
        family = db.get_family_from_handle(handle)
        if family and not family.get_privacy():
            new_person.add_family_handle(handle)

    # copy Family reference list
    for handle in person.get_parent_family_handle_list():
        family = db.get_family_from_handle(handle)
        if not family:
            continue
        elif family.get_privacy():
            continue
        child_ref_list = family.get_child_ref_list()
        for child_ref in child_ref_list:
            if child_ref.get_reference_handle() == person.get_handle():
                if child_ref and not child_ref.get_privacy():
                    new_person.add_parent_family_handle(handle)
                break

    for name in person.get_alternate_names():
        if name and not name.get_privacy():
            new_person.add_alternate_name(sanitize_name(db, name))

    # copy event list
    for event_ref in person.get_event_ref_list():
        if event_ref and not event_ref.get_privacy():
            event = db.get_event_from_handle(event_ref.ref)
            if event and not event.get_privacy():
                new_person.add_event_ref(sanitize_event_ref(db, event_ref))

    # Copy birth and death after event list to maintain the order.
    # copy birth event
    event_ref = person.get_birth_ref()
    if event_ref and not event_ref.get_privacy():
        event = db.get_event_from_handle(event_ref.ref)
        if event and not event.get_privacy():
            new_person.set_birth_ref(sanitize_event_ref(db, event_ref))

    # copy death event
    event_ref = person.get_death_ref()
    if event_ref and not event_ref.get_privacy():
        event = db.get_event_from_handle(event_ref.ref)
        if event and not event.get_privacy():
            new_person.set_death_ref(sanitize_event_ref(db, event_ref))

    copy_addresses(db, person, new_person)
    copy_attributes(db, person, new_person)
    copy_citation_ref_list(db, person, new_person)
    copy_urls(db, person, new_person)
    copy_media_ref_list(db, person, new_person)
    copy_lds_ords(db, person, new_person)
    copy_notes(db, person, new_person)
    copy_associations(db, person, new_person)

    return new_person
Ejemplo n.º 29
0
 def initial_frame(self):
     """
     The name of the initial menu tab.
     """
     return _("Options")
Ejemplo n.º 30
0
 def __init__(self):
     """Methods for extracting statistical data from the database"""
     # key, non-localized name, localized name, type method, data method
     self.extractors = {
         'data_title':
         ("Title", _("person|Title"), self.get_person, self.get_title),
         'data_sname':
         ("Surname", _("Surname"), self.get_person, self.get_surname),
         'data_fname':
         ("Forename", _("Forename"), self.get_person, self.get_forename),
         'data_gender':
         ("Gender", _("Gender"), self.get_person, self.get_gender),
         'data_byear': ("Birth year", _("Birth year"), self.get_birth,
                        self.get_year),
         'data_dyear': ("Death year", _("Death year"), self.get_death,
                        self.get_year),
         'data_bmonth': ("Birth month", _("Birth month"), self.get_birth,
                         self.get_month),
         'data_dmonth': ("Death month", _("Death month"), self.get_death,
                         self.get_month),
         'data_bplace': ("Birth place", _("Birth place"), self.get_birth,
                         self.get_place),
         'data_dplace': ("Death place", _("Death place"), self.get_death,
                         self.get_place),
         'data_mplace': ("Marriage place", _("Marriage place"),
                         self.get_marriage_handles, self.get_places),
         'data_mcount': ("Number of relationships",
                         _("Number of relationships"),
                         self.get_family_handles, self.get_handle_count),
         'data_fchild': ("Age when first child born",
                         _("Age when first child born"),
                         self.get_child_handles, self.get_first_child_age),
         'data_lchild': ("Age when last child born",
                         _("Age when last child born"),
                         self.get_child_handles, self.get_last_child_age),
         'data_ccount': ("Number of children", _("Number of children"),
                         self.get_child_handles, self.get_handle_count),
         'data_mage': ("Age at marriage", _("Age at marriage"),
                       self.get_marriage_handles, self.get_event_ages),
         'data_dage': ("Age at death", _("Age at death"), self.get_person,
                       self.get_death_age),
         'data_age': ("Age", _("Age"), self.get_person,
                      self.get_person_age),
         'data_etypes': ("Event type", _("Event type"),
                         self.get_event_handles, self.get_event_type)
     }
Ejemplo n.º 31
0
class FamilyPrivate(IsPrivate):
    """Family marked private"""

    name = _('Families marked private')
    description = _("Matches families that are indicated as private")
Ejemplo n.º 32
0
 def get_person_age(self, person):
     "return age for given person, if alive"
     death_ref = person.get_death_ref()
     if not death_ref:
         return [self.estimate_age(person)]
     return [_("Already dead")]
Ejemplo n.º 33
0
#
# gramps modules
#
#-------------------------------------------------------------------------
import gen.db
from gen.plug import BasePluginManager
import config
import constfunc

#-------------------------------------------------------------------------
#
# constants
#
#-------------------------------------------------------------------------

DEFAULT_TITLE = _("Family Tree")
NAME_FILE     = "name.txt"
META_NAME     = "meta_data.db"

#-------------------------------------------------------------------------
#
# CLIDbManager
#
#-------------------------------------------------------------------------
class CLIDbManager(object):
    """
    Database manager without GTK functionality, allows users to create and
    open databases
    """
    ICON_NONE     = 0
    ICON_RECOVERY = 1
Ejemplo n.º 34
0
 def get_death_age(self, person):
     "return age at death for given person, if dead"
     death_ref = person.get_death_ref()
     if death_ref:
         return [self.estimate_age(person, death_ref.ref)]
     return [_("Still alive")]
Ejemplo n.º 35
0
 def __end_cursor(self):
     """
     Set end of a busy cursor
     """
     print _('Import finished...')
Ejemplo n.º 36
0
    def __init__(self, database, options, user):
        """
        Create the Statistics object that produces the report.
        Uses the Extractor class to extract the data from the database.

        The arguments are:

        database        - the GRAMPS database instance
        options         - instance of the Options class for this report
        user            - a gen.user.User() instance

        To see what the options are, check the options help in the options class.
        """
        Report.__init__(self, database, options, user)
        menu = options.menu
        self._user = user
        get_option_by_name = menu.get_option_by_name
        get_value = lambda name: get_option_by_name(name).get_value()

        self.filter_option = get_option_by_name('filter')
        self.filter = self.filter_option.get_filter()

        self.bar_items = get_value('bar_items')
        year_from = get_value('year_from')
        year_to = get_value('year_to')
        gender = get_value('gender')

        # title needs both data extraction method name + gender name
        if gender == Person.MALE:
            genders = _("Men")
        elif gender == Person.FEMALE:
            genders = _("Women")
        else:
            genders = None

        # needed for keyword based localization
        mapping = {
            'genders': genders,
            'year_from': year_from,
            'year_to': year_to
        }

        # extract requested items from the database and count them
        self._user.begin_progress(_('Statistics Charts'),
                                  _('Collecting data...'), 0)
        tables = _Extract.collect_data(database, self.filter, menu,
                                       gender, year_from, year_to,
                                       get_value('no_years'),
                                       self._user.step_progress)
        self._user.end_progress()

        self._user.begin_progress(_('Statistics Charts'), _('Sorting data...'),
                                  len(tables))
        self.data = []
        sortby = get_value('sortby')
        reverse = get_value('reverse')
        for table in tables:
            # generate sorted item lookup index index
            lookup = self.index_items(table[1], sortby, reverse)
            # document heading
            mapping['chart_title'] = table[0]
            if genders:
                heading = _(
                    "%(genders)s born %(year_from)04d-%(year_to)04d: %(chart_title)s"
                ) % mapping
            else:
                heading = _(
                    "Persons born %(year_from)04d-%(year_to)04d: %(chart_title)s"
                ) % mapping
            self.data.append((heading, table[0], table[1], lookup))
            self._user.step_progress()
        self._user.end_progress()
Ejemplo n.º 37
0
 def build_menu_names(self, obj):
     return (_("Relationship Calculator tool"), None)
Ejemplo n.º 38
0
class AllPlaces(Everything):
    """Matches Everyone"""

    name = _('Every place')
    description = _('Matches every place in the database')
Ejemplo n.º 39
0
    def query_response(self):
        with DbTxn(_("Delete Source (%s)") % self.source.get_title(),
                   self.db) as trans:
            self.db.disable_signals()

            # we can have:
            # object(CitationBase) -> Citation(source_handle) -> Source
            # We first have to remove the CitationBase references to the
            # Citation. Then we remove the Citations. (We don't need to
            # remove the source_handle references to the Source, because we are
            # removing the whole Citation). Then we can remove the Source

            (citation_list, citation_referents_list) = self.the_lists
            # citation_list is a tuple of lists. Only the first, for Citations,
            # exists.
            citation_list = citation_list[0]

            # (1) delete the references to the citation
            for (citation_handle, refs) in citation_referents_list:
                LOG.debug('delete citation %s references %s' %
                          (citation_handle, refs))
                (person_list, family_list, event_list, place_list, source_list,
                 media_list, repo_list) = refs

                ctn_handle_list = [citation_handle]

                for handle in person_list:
                    person = self.db.get_person_from_handle(handle)
                    person.remove_citation_references(ctn_handle_list)
                    self.db.commit_person(person, trans)

                for handle in family_list:
                    family = self.db.get_family_from_handle(handle)
                    family.remove_citation_references(ctn_handle_list)
                    self.db.commit_family(family, trans)

                for handle in event_list:
                    event = self.db.get_event_from_handle(handle)
                    event.remove_citation_references(ctn_handle_list)
                    self.db.commit_event(event, trans)

                for handle in place_list:
                    place = self.db.get_place_from_handle(handle)
                    place.remove_citation_references(ctn_handle_list)
                    self.db.commit_place(place, trans)

                for handle in source_list:
                    source = self.db.get_source_from_handle(handle)
                    source.remove_citation_references(ctn_handle_list)
                    self.db.commit_source(source, trans)

                for handle in media_list:
                    media = self.db.get_object_from_handle(handle)
                    media.remove_citation_references(ctn_handle_list)
                    self.db.commit_media_object(media, trans)

                for handle in repo_list:
                    repo = self.db.get_repository_from_handle(handle)
                    repo.remove_citation_references(ctn_handle_list)
                    self.db.commit_repository(repo, trans)

            # (2) delete the actual citations
            LOG.debug('remove the actual citations %s' % citation_list)
            for citation_handle in citation_list:
                LOG.debug("remove_citation %s" % citation_handle)
                self.db.remove_citation(citation_handle, trans)

            # (3) delete the source
            self.db.enable_signals()
            self.db.remove_source(self.source.get_handle(), trans)
Ejemplo n.º 40
0
 def build_menu_names(self, obj):
     etitle = _('Internet Address Editor')
     return (etitle, etitle)
Ejemplo n.º 41
0
#-------------------------------------------------------------------------
import const
import Utils


# Note: Make sure to edit const.py POPT_TABLE too!
_HELP = _("""
Usage: gramps.py [OPTION...]
  --load-modules=MODULE1,MODULE2,...     Dynamic modules to load

Help options
  -?, --help                             Show this help message
  --usage                                Display brief usage message

Application options
  -O, --open=FAMILY_TREE                 Open family tree
  -i, --import=FILENAME                  Import file
  -e, --export=FILENAME                  Export file
  -f, --format=FORMAT                    Specify family tree format
  -a, --action=ACTION                    Specify action
  -p, --options=OPTIONS_STRING           Specify options
  -d, --debug=LOGGER_NAME                Enable debug logs
  -l                                     List Family Trees
  -L                                     List Family Trees in Detail
  -u, --force-unlock                     Force unlock of family tree
""")

_USAGE = _("""
Example of usage of Gramps command line interface

1. To import four databases (whose formats can be determined from their names)
and then check the resulting database for errors, one may type:
Ejemplo n.º 42
0
    def __init__(self, dbstate, uistate, options_class, name, callback=None):
        """
        Relationship calculator class.
        """

        tool.Tool.__init__(self, dbstate, options_class, name)
        ManagedWindow.ManagedWindow.__init__(self, uistate, [], self.__class__)

        #set the columns to see
        for data in BasePersonView.CONFIGSETTINGS:
            if data[0] == 'columns.rank':
                colord = data[1]
            elif data[0] == 'columns.visible':
                colvis = data[1]
            elif data[0] == 'columns.size':
                colsize = data[1]
        self.colord = []
        for col, size in zip(colord, colsize):
            if col in colvis:
                self.colord.append((1, col, size))
            else:
                self.colord.append((0, col, size))

        self.dbstate = dbstate
        self.relationship = Relationship.get_relationship_calculator()
        self.relationship.connect_db_signals(dbstate)

        self.glade = Glade()
        self.person = self.db.get_person_from_handle(
            uistate.get_active('Person'))
        name = ''
        if self.person:
            name = name_displayer.display(self.person)
        self.title = _('Relationship calculator: %(person_name)s') % {
            'person_name': name
        }
        window = self.glade.toplevel
        self.titlelabel = self.glade.get_object('title')
        self.set_window(
            window, self.titlelabel,
            _('Relationship to %(person_name)s') % {'person_name': name},
            self.title)

        self.tree = self.glade.get_object("peopleList")
        self.text = self.glade.get_object("text1")
        self.textbuffer = gtk.TextBuffer()
        self.text.set_buffer(self.textbuffer)

        self.model = PersonTreeModel(self.db)
        self.tree.set_model(self.model)

        self.tree.connect('key-press-event', self._key_press)
        self.selection = self.tree.get_selection()
        self.selection.set_mode(gtk.SELECTION_SINGLE)

        #keep reference of column so garbage collection works
        self.columns = []
        for pair in self.colord:
            if not pair[0]:
                continue
            name = column_names[pair[1]]
            column = gtk.TreeViewColumn(name,
                                        gtk.CellRendererText(),
                                        markup=pair[1])
            column.set_resizable(True)
            column.set_min_width(60)
            column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY)
            self.tree.append_column(column)
            #keep reference of column so garbage collection works
            self.columns.append(column)

        self.sel = self.tree.get_selection()
        self.changedkey = self.sel.connect('changed', self.on_apply_clicked)
        self.closebtn = self.glade.get_object("button5")
        self.closebtn.connect('clicked', self.close)

        if not self.person:
            self.window.hide()
            ErrorDialog(
                _('Active person has not been set'),
                _('You must select an active person for this '
                  'tool to work properly.'))
            self.close()
            return

        self.show()
Ejemplo n.º 43
0
class HasNoteRegexp(HasNoteRegexBase):

    name = _('Places having notes containing <text>')
    description = _("Matches places whose notes contain text "
                    "matching a regular expression")
Ejemplo n.º 44
0
 def get_window_title(self):
     return _("Select Note")
Ejemplo n.º 45
0
class HasReferenceCountOf(HasReferenceCountBase):
    """Events with a reference count of <count>"""

    name = _('Events with a reference count of <count>')
    description = _("Matches events with a certain reference count")
Ejemplo n.º 46
0
def gramps_upgrade_16(self):
    """Upgrade database from version 15 to 16. This upgrade converts all
       SourceRef child objects to Citation Primary objects.
       
       For each primary object that has a sourceref, what we have to do is: 
       
             (1) create each citation
             (2) update the object to reference the Citations
             (3) remove backlinks for references from object to Source
             (4) add backlinks for references from object to Citations
             (5) add backlinks for references from Citation to Source
            
        the backlinks are all updated on return to write.py gramps_upgrade by
        calling reindex_reference_map

    """
    # Only People, Families, Events, Media Objects, Places, Sources and
    # Repositories need to be updated, because these are the only primary
    # objects that can have source citations.
    length = (len(self.person_map) + len(self.event_map) +
              len(self.family_map) + len(self.repository_map) +
              len(self.media_map) + len(self.place_map) + len(self.source_map))
    self.set_total(length)

    # Setup data for upgrade statistics information dialogue
    keyorder = [
        PERSON_KEY, FAMILY_KEY, EVENT_KEY, MEDIA_KEY, PLACE_KEY,
        REPOSITORY_KEY, SOURCE_KEY
    ]
    key2data = {
        PERSON_KEY: 0,
        FAMILY_KEY: 1,
        EVENT_KEY: 2,
        MEDIA_KEY: 3,
        PLACE_KEY: 4,
        REPOSITORY_KEY: 5,
        SOURCE_KEY: 6,
    }
    key2string = {
        PERSON_KEY:
        _('%6d  People        upgraded with %6d citations in %6d secs\n'),
        FAMILY_KEY:
        _('%6d  Families      upgraded with %6d citations in %6d secs\n'),
        EVENT_KEY:
        _('%6d  Events        upgraded with %6d citations in %6d secs\n'),
        MEDIA_KEY:
        _('%6d  Media Objects upgraded with %6d citations in %6d secs\n'),
        PLACE_KEY:
        _('%6d  Places        upgraded with %6d citations in %6d secs\n'),
        REPOSITORY_KEY:
        _('%6d  Repositories  upgraded with %6d citations in %6d secs\n'),
        SOURCE_KEY:
        _('%6d  Sources       upgraded with %6d citations in %6d secs\n'),
    }
    data_upgradeobject = [0] * 7

    # Initialise the citation gramps ID number
    self.cmap_index = 0

    # ---------------------------------
    # Modify Person
    # ---------------------------------
    start_num_citations = self.cmap_index
    start_time = time.time()
    for person_handle in self.person_map.keys():
        person = self.person_map[person_handle]
        try:
            # The parameters are evaluated before deciding whether logging is on
            # or not. Since the retrieval of names is so complex, I think it is
            # safer to protect this with a try except block, even though it
            # seems to work for names being present and not.
            LOG.debug(
                "upgrade person %s %s" %
                (person[3][4], " ".join([name[0] for name in person[3][5]])))
        except:
            pass
        (handle, gramps_id, gender, primary_name, alternate_names,
         death_ref_index, birth_ref_index, event_ref_list, family_list,
         parent_family_list, media_list, address_list, attribute_list, urls,
         lds_seal_list, source_list, note_list, change, tag_list, private,
         person_ref_list) = person
        if primary_name:
            primary_name = upgrade_name_16(self, primary_name)
        if alternate_names:
            alternate_names = upgrade_name_list_16(self, alternate_names)
        if address_list:
            address_list = upgrade_address_list_16(self, address_list)
        if media_list:
            media_list = upgrade_media_list_16(self, media_list)
        if attribute_list:
            attribute_list = upgrade_attribute_list_16(self, attribute_list)
        if lds_seal_list:
            lds_seal_list = upgrade_lds_seal_list_16(self, lds_seal_list)
        if source_list:
            new_citation_list = convert_source_list_to_citation_list_16(
                self, source_list)
        else:
            new_citation_list = []
        if person_ref_list:
            person_ref_list = upgrade_person_ref_list_16(self, person_ref_list)
        if event_ref_list:
            event_ref_list = upgrade_event_ref_list_16(self, event_ref_list)
        if primary_name or alternate_names  or address_list or \
           media_list or attribute_list or lds_seal_list or source_list or \
           person_ref_list or event_ref_list:
            new_person = (handle, gramps_id, gender, primary_name,
                          alternate_names, death_ref_index, birth_ref_index,
                          event_ref_list, family_list, parent_family_list,
                          media_list, address_list, attribute_list, urls,
                          lds_seal_list, new_citation_list, note_list, change,
                          tag_list, private, person_ref_list)
            LOG.debug("      upgrade new_person %s" % [new_person])
            with BSDDBTxn(self.env, self.person_map) as txn:
                txn.put(str(handle), new_person)
        self.update()

    LOG.debug("%d persons upgraded with %d citations in %d seconds. " %
              (len(self.person_map.keys()), self.cmap_index -
               start_num_citations, time.time() - start_time))
    data_upgradeobject[key2data[PERSON_KEY]] = (len(
        self.person_map.keys()), self.cmap_index - start_num_citations,
                                                time.time() - start_time)

    # ---------------------------------
    # Modify Media
    # ---------------------------------
    start_num_citations = self.cmap_index
    start_time = time.time()
    for media_handle in self.media_map.keys():
        media = self.media_map[media_handle]
        LOG.debug("upgrade media object %s" % media[4])
        (handle, gramps_id, path, mime, desc, attribute_list, source_list,
         note_list, change, date, tag_list, private) = media
        new_citation_list = convert_source_list_to_citation_list_16(
            self, source_list)
        new_attribute_list = upgrade_attribute_list_16(self, attribute_list)

        new_media = (handle, gramps_id, path, mime, desc, new_attribute_list,
                     new_citation_list, note_list, change, date, tag_list,
                     private)
        LOG.debug("      upgrade new_media %s" % [new_media])
        with BSDDBTxn(self.env, self.media_map) as txn:
            txn.put(str(handle), new_media)
        self.update()

    LOG.debug("%d media objects upgraded with %d citations in %d seconds" %
              (len(self.media_map.keys()), self.cmap_index -
               start_num_citations, int(time.time() - start_time)))
    data_upgradeobject[key2data[MEDIA_KEY]] = (len(
        self.media_map.keys()), self.cmap_index - start_num_citations,
                                               time.time() - start_time)

    # ---------------------------------
    # Modify Places
    # ---------------------------------
    start_num_citations = self.cmap_index
    start_time = time.time()
    for place_handle in self.place_map.keys():
        place = self.place_map[place_handle]
        LOG.debug("upgrade place %s" % place[2])
        (handle, gramps_id, title, long, lat, main_loc, alt_loc, urls,
         media_list, source_list, note_list, change, private) = place
        if source_list:
            new_citation_list = convert_source_list_to_citation_list_16(
                self, source_list)
        else:
            new_citation_list = []
        if media_list:
            media_list = upgrade_media_list_16(self, media_list)
        if source_list or media_list:
            new_place = (handle, gramps_id, title, long, lat, main_loc,
                         alt_loc, urls, media_list, new_citation_list,
                         note_list, change, private)
            LOG.debug("      upgrade new_place %s" % [new_place])
            with BSDDBTxn(self.env, self.place_map) as txn:
                txn.put(str(handle), new_place)
        self.update()

    LOG.debug("%d places upgraded with %d citations in %d seconds. " %
              (len(self.place_map.keys()), self.cmap_index -
               start_num_citations, time.time() - start_time))
    data_upgradeobject[key2data[PLACE_KEY]] = (len(
        self.place_map.keys()), self.cmap_index - start_num_citations,
                                               time.time() - start_time)

    # ---------------------------------
    # Modify Families
    # ---------------------------------
    start_num_citations = self.cmap_index
    start_time = time.time()
    for family_handle in self.family_map.keys():
        family = self.family_map[family_handle]
        LOG.debug("upgrade family (gramps_id) %s" % family[1])
        (handle, gramps_id, father_handle, mother_handle, child_ref_list,
         the_type, event_ref_list, media_list, attribute_list, lds_seal_list,
         source_list, note_list, change, tag_list, private) = family
        if source_list:
            new_citation_list = convert_source_list_to_citation_list_16(
                self, source_list)
        else:
            new_citation_list = []
        if child_ref_list:
            child_ref_list = upgrade_child_ref_list_16(self, child_ref_list)
        if lds_seal_list:
            lds_seal_list = upgrade_lds_seal_list_16(self, lds_seal_list)
        if media_list:
            media_list = upgrade_media_list_16(self, media_list)
        if attribute_list:
            attribute_list = upgrade_attribute_list_16(self, attribute_list)
        if event_ref_list:
            event_ref_list = upgrade_event_ref_list_16(self, event_ref_list)
        if source_list or media_list or child_ref_list or \
            attribute_list or lds_seal_list or event_ref_list:
            new_family = (handle, gramps_id, father_handle, mother_handle,
                          child_ref_list, the_type, event_ref_list, media_list,
                          attribute_list, lds_seal_list, new_citation_list,
                          note_list, change, tag_list, private)
            LOG.debug("      upgrade new_family %s" % [new_family])
            with BSDDBTxn(self.env, self.family_map) as txn:
                txn.put(str(handle), new_family)
        self.update()

    LOG.debug("%d families upgraded with %d citations in %d seconds. " %
              (len(self.family_map.keys()), self.cmap_index -
               start_num_citations, time.time() - start_time))
    data_upgradeobject[key2data[FAMILY_KEY]] = (len(
        self.family_map.keys()), self.cmap_index - start_num_citations,
                                                time.time() - start_time)
    # ---------------------------------
    # Modify Events
    # ---------------------------------
    start_num_citations = self.cmap_index
    start_time = time.time()
    for event_handle in self.event_map.keys():
        event = self.event_map[event_handle]
        LOG.debug("upgrade event %s" % event[4])
        (handle, gramps_id, the_type, date, description, place, source_list,
         note_list, media_list, attribute_list, change, private) = event
        if source_list:
            new_citation_list = convert_source_list_to_citation_list_16(
                self, source_list)
        else:
            new_citation_list = []
        if attribute_list:
            attribute_list = upgrade_attribute_list_16(self, attribute_list)
        if media_list:
            media_list = upgrade_media_list_16(self, media_list)
        if source_list or attribute_list or media_list:
            new_event = (handle, gramps_id, the_type, date, description, place,
                         new_citation_list, note_list, media_list,
                         attribute_list, change, private)
            LOG.debug("      upgrade new_event %s" % [new_event])
            with BSDDBTxn(self.env, self.event_map) as txn:
                txn.put(str(handle), new_event)
        self.update()

    LOG.debug("%d events upgraded with %d citations in %d seconds. " %
              (len(self.event_map.keys()), self.cmap_index -
               start_num_citations, time.time() - start_time))
    data_upgradeobject[key2data[EVENT_KEY]] = (len(
        self.event_map.keys()), self.cmap_index - start_num_citations,
                                               time.time() - start_time)

    # ---------------------------------
    # Modify Repositories
    # ---------------------------------
    start_num_citations = self.cmap_index
    start_time = time.time()
    for repository_handle in self.repository_map.keys():
        repository = self.repository_map[repository_handle]
        LOG.debug("upgrade repository %s" % repository[3])
        (handle, gramps_id, the_type, name, note_list, address_list, urls,
         change, private) = repository
        if address_list:
            address_list = upgrade_address_list_16(self, address_list)
        if address_list:
            new_repository = (handle, gramps_id, the_type, name, note_list,
                              address_list, urls, change, private)
            LOG.debug("      upgrade new_repository %s" % [new_repository])
            with BSDDBTxn(self.env, self.repository_map) as txn:
                txn.put(str(handle), new_repository)
        self.update()

    LOG.debug("%d repositories upgraded with %d citations in %d seconds. " %
              (len(self.repository_map.keys()), self.cmap_index -
               start_num_citations, time.time() - start_time))
    data_upgradeobject[key2data[REPOSITORY_KEY]] = (len(
        self.repository_map.keys()), self.cmap_index - start_num_citations,
                                                    time.time() - start_time)

    # ---------------------------------
    # Modify Source
    # ---------------------------------
    start_num_citations = self.cmap_index
    start_time = time.time()
    for source_handle in self.source_map.keys():
        source = self.source_map[source_handle]
        LOG.debug("upgrade source %s" % source[2])
        (handle, gramps_id, title, author, pubinfo, note_list, media_list,
         abbrev, change, datamap, reporef_list, private) = source
        if media_list:
            media_list = upgrade_media_list_16(self, media_list)

        new_source = (handle, gramps_id, title, author, pubinfo, note_list,
                      media_list, abbrev, change, datamap, reporef_list,
                      private)
        LOG.debug("      upgrade new_source %s" % [new_source])
        with BSDDBTxn(self.env, self.source_map) as txn:
            txn.put(str(handle), new_source)
        self.update()

    LOG.debug("%d sources upgraded with %d citations in %d seconds" %
              (len(self.source_map.keys()), self.cmap_index -
               start_num_citations, int(time.time() - start_time)))
    data_upgradeobject[key2data[SOURCE_KEY]] = (len(
        self.source_map.keys()), self.cmap_index - start_num_citations,
                                                time.time() - start_time)

    # ---------------------------------

    # ---------------------------------
    # Example database from repository took:
    # 3403 events upgraded with 8 citations in 23 seconds. Backlinks took 1071 seconds
    # actually 4 of these citations were from:
    # Media upgrade 4 citations upgraded in 4 seconds
    # by only doing the backlinks when there might be something to do,
    # improved to:
    # 3403 events upgraded with 8 citations in 19 seconds. Backlinks took 1348 seconds
    # further improved by skipping debug logging:
    # 3403 events upgraded with 8 citations in 2 seconds. Backlinks took 167 seconds

    #Number of new objects upgraded:
    #  2090  People        upgraded with   2092 citations in 2148 secs
    #   734  Families      upgraded with    735 citations in 768 secs
    #  3403  Events        upgraded with      4 citations in 212 secs
    #     7  Media Objects upgraded with      4 citations in 3 secs
    #   852  Places        upgraded with      0 citations in 39 secs

    # with reduced diagnostics
    #Number of new objects upgraded:
    #    73  People        upgraded with     76 citations in     74 secs
    #    35  Families      upgraded with     36 citations in     31 secs
    #  3403  Events        upgraded with      4 citations in      7 secs
    #     7  Media Objects upgraded with      4 citations in      3 secs
    #   852  Places        upgraded with      0 citations in      1 secs

    # without doing any backlinks
    #Number of new objects upgraded:
    #    73  People        upgraded with     76 citations in     43 secs
    #    35  Families      upgraded with     36 citations in     24 secs
    #  3403  Events        upgraded with      4 citations in      6 secs
    #     7  Media Objects upgraded with      4 citations in      2 secs
    #   852  Places        upgraded with      0 citations in      1 secs

    # another run about the same code:
    #Number of new objects upgraded:
    #    73  People        upgraded with     76 citations in     48 secs
    #    35  Families      upgraded with     36 citations in     21 secs
    #  3403  Events        upgraded with      4 citations in      9 secs
    #     7  Media Objects upgraded with      4 citations in      4 secs
    #   852  Places        upgraded with      0 citations in      1 secs

    # another run
    #Number of new objects upgraded:
    #    73  People        upgraded with     76 citations in     36 secs
    #    35  Families      upgraded with     36 citations in     18 secs
    #  3403  Events        upgraded with      4 citations in      9 secs
    #     7  Media Objects upgraded with      4 citations in      2 secs
    #   852  Places        upgraded with      0 citations in      1 secs

    # without incorrect nestetd tranaction structure:
    #Number of new objects upgraded:
    #    73  People        upgraded with     76 citations in      0 secs
    #    35  Families      upgraded with     36 citations in      0 secs
    #  3403  Events        upgraded with      4 citations in      0 secs
    #     7  Media Objects upgraded with      4 citations in      0 secs
    #   852  Places        upgraded with      0 citations in      0 secs

    #[[(73, 76, 0.12430405616760254), (35, 36, 0.042523860931396484), (3403, 4, 0.52303886413574219), (7, 4, 0.058229923248291016), (852, 0, 0.14816904067993164)]]

    # Bump up database version. Separate transaction to save metadata.
    with BSDDBTxn(self.env, self.metadata) as txn:
        txn.put('version', 16)

    LOG.debug([data_upgradeobject])
    txt = _("Number of new objects upgraded:\n")
    for key in keyorder:
        try:
            txt += key2string[key] % data_upgradeobject[key2data[key]]
        except:
            txt += key2string[key]
    txt += _("\n\nYou may want to run\n"
             "Tools -> Family Tree Processing -> Merge\n"
             "in order to merge citations that contain similar\n"
             "information")
    InfoDialog(_('Upgrade Statistics'), txt, monospaced=True)
Ejemplo n.º 47
0
        self._begin_progress()
        
        try:
            self.dbstate.db.load(filename, self._pulse_progress, mode)
            self.dbstate.db.set_save_path(filename)
        except gen.db.exceptions.DbUpgradeRequiredError, msg:
            self.dbstate.no_database()
            self._errordialog( _("Cannot open database"), str(msg))
        except gen.db.exceptions.DbVersionError, msg:
            self.dbstate.no_database()
            self._errordialog( _("Cannot open database"), str(msg))
        except OSError, msg:
            self.dbstate.no_database()
            self._errordialog(
                _("Could not open file: %s") % filename, str(msg))
        except Errors.DbError, msg:
            self.dbstate.no_database()
            self._dberrordialog(msg)
        except Exception:
            self.dbstate.no_database()
            LOG.error("Failed to open database.", exc_info=True)
        return True

#-------------------------------------------------------------------------
#
# CLIManager class
#
#-------------------------------------------------------------------------

class CLIManager(object):
Ejemplo n.º 48
0
class MatchesFilter(MatchesFilterBase):
    """Rule that checks against another filter."""

    name = _('Events matching the <filter>')
    description = _("Matches events matched by the specified filter name")
    namespace = 'Event'
Ejemplo n.º 49
0
    def add_menu_options(self, menu):
        """
        Add options to the menu for the statistics report.
        """

        ################################
        add_option = partial(menu.add_option, _("Report Options"))
        ################################

        self.__filter = FilterOption(_("Filter"), 0)
        self.__filter.set_help(
            _("Determines what people are included in the report."))
        add_option("filter", self.__filter)
        self.__filter.connect('value-changed', self.__filter_changed)

        self.__pid = PersonOption(_("Filter Person"))
        self.__pid.set_help(_("The center person for the filter."))
        add_option("pid", self.__pid)
        self.__pid.connect('value-changed', self.__update_filters)

        self.__update_filters()

        sortby = EnumeratedListOption(_('Sort chart items by'),
                                      _options.SORT_VALUE)
        for item_idx in range(len(_options.sorts)):
            item = _options.sorts[item_idx]
            sortby.add_item(item_idx, item[2])
        sortby.set_help(_("Select how the statistical data is sorted."))
        add_option("sortby", sortby)

        reverse = BooleanOption(_("Sort in reverse order"), False)
        reverse.set_help(_("Check to reverse the sorting order."))
        add_option("reverse", reverse)

        this_year = time.localtime()[0]
        year_from = NumberOption(_("People Born After"), 1700, 1, this_year)
        year_from.set_help(_("Birth year from which to include people."))
        add_option("year_from", year_from)

        year_to = NumberOption(_("People Born Before"), this_year, 1,
                               this_year)
        year_to.set_help(_("Birth year until which to include people"))
        add_option("year_to", year_to)

        no_years = BooleanOption(_("Include people without known birth years"),
                                 False)
        no_years.set_help(
            _("Whether to include people without "
              "known birth years."))
        add_option("no_years", no_years)

        gender = EnumeratedListOption(_('Genders included'), Person.UNKNOWN)
        for item_idx in range(len(_options.genders)):
            item = _options.genders[item_idx]
            gender.add_item(item[0], item[2])
        gender.set_help(
            _("Select which genders are included into "
              "statistics."))
        add_option("gender", gender)

        bar_items = NumberOption(_("Max. items for a pie"), 8, 0, 20)
        bar_items.set_help(
            _("With fewer items pie chart and legend will be "
              "used instead of a bar chart."))
        add_option("bar_items", bar_items)

        # -------------------------------------------------
        # List of available charts on separate option tabs
        idx = 0
        half = (len(_Extract.extractors)) / 2
        self.charts = {}
        for key in _Extract.extractors:
            if idx < half:
                category_name = _("Charts 1")
            else:
                category_name = _("Charts 2")

            opt = BooleanOption(_Extract.extractors[key][1], False)
            opt.set_help(_("Include charts with indicated data."))
            menu.add_option(category_name, key, opt)
            idx += 1

        # Enable a couple of charts by default
        menu.get_option_by_name("data_gender").set_value(True)
        menu.get_option_by_name("data_ccount").set_value(True)
        menu.get_option_by_name("data_bmonth").set_value(True)
Ejemplo n.º 50
0
 def columnpage(configdialog):
     return _('Columns'), ColumnOrder(self._config,
                                      self.COLUMN_NAMES,
                                      self.get_column_widths(),
                                      self.set_column_order,
                                      tree=self.type_list() == LISTTREE)
Ejemplo n.º 51
0
 def _warn(self, title, warnmessage):
     """
     Issue a warning message. Inherit for GUI action
     """
     print _('WARNING: %s') % warnmessage
Ejemplo n.º 52
0
 def __init__(self,
              uistate,
              dbstate,
              map,
              layer,
              places,
              lat,
              lon,
              function,
              oldvalue=None):
     """
     We show a selection box for possible places in a region of the map.
     We can select the diameter of the region which is a circle.
     Depending of this region, we can show the possible choice.
     We select the value depending of our need which open the EditPlace box.
     """
     try:
         ManagedWindow.ManagedWindow.__init__(self, uistate, [],
                                              PlaceSelection)
     except Errors.WindowActiveError:
         return
     self.uistate = uistate
     self.dbstate = dbstate
     self.lat = lat
     self.lon = lon
     self.osm = map
     self.radius = 1.0
     self.circle = None
     self.oldvalue = oldvalue
     self.place_list = places
     self.function = function
     self.selection_layer = layer
     self.layer = layer
     alignment = gtk.Alignment(0, 1, 0, 0)
     self.set_window(
         gtk.Dialog(_('Place Selection in a region'),
                    flags=gtk.DIALOG_NO_SEPARATOR,
                    buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)), None,
         _('Place Selection in a region'), None)
     label = gtk.Label(
         _('Choose the radius of the selection.\n'
           'On the map you should see a circle or an oval depending on the latitude.'
           ))
     alignment.add(label)
     self.window.vbox.pack_start(alignment, expand=False)
     adj = gtk.Adjustment(
         1.0, 0.1, 3.0, 0.1, 0,
         0)  # default value is 1.0, minimum is 0.1 and max is 3.0
     slider = gtk.HScale(adj)
     slider.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
     slider.set_digits(1)
     slider.set_value_pos(gtk.POS_BOTTOM)
     slider.connect('value-changed', self.slider_change, self.lat, self.lon)
     self.window.vbox.pack_start(slider, expand=False)
     self.vadjust = gtk.Adjustment(page_size=15)
     self.scroll = gtk.ScrolledWindow(self.vadjust)
     self.scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
     self.scroll.set_shadow_type(gtk.SHADOW_IN)
     self.plist = gtk.ListStore(str, str, str)
     self.choices = gtk.TreeView(self.plist)
     self.scroll.add(self.choices)
     self.renderer = gtk.CellRendererText()
     self.tvcol1 = gtk.TreeViewColumn(_('Country'), self.renderer, markup=0)
     self.tvcol2 = gtk.TreeViewColumn(_('State'), self.renderer, markup=1)
     self.tvcol3 = gtk.TreeViewColumn(_('County'), self.renderer, markup=2)
     self.tvcol1.set_sort_column_id(0)
     self.tvcol2.set_sort_column_id(1)
     self.tvcol3.set_sort_column_id(2)
     self.choices.append_column(self.tvcol1)
     self.choices.append_column(self.tvcol2)
     self.choices.append_column(self.tvcol3)
     self.window.vbox.pack_start(self.scroll, expand=True)
     self.label2 = gtk.Label()
     self.label2.set_markup(
         '<span background="green" foreground="black">%s</span>' %
         _('The green values in the row correspond to the current place values.'
           ))
     alignment = gtk.Alignment(0, 1, 0, 0)
     alignment.add(self.label2)
     self.window.vbox.pack_start(alignment, expand=False)
     self.window.set_default_size(400, 300)
     self.choices.connect('row-activated', self.selection, function)
     self.window.connect('response', self.close)
     self.window.show_all()
     self.show()
     self.label2.hide()
     self.slider_change(None, lat, lon)
Ejemplo n.º 53
0
    def build_nav_menu(self, obj, event, lat, lon):
        """Builds the menu for actions on the map."""
        menu = gtk.Menu()
        menu.set_title(_('Map Menu'))

        if config.get("geography.show_cross"):
            title = _('Remove cross hair')
        else:
            title = _('Add cross hair')
        add_item = gtk.MenuItem(title)
        add_item.connect("activate", self.config_crosshair, event, lat, lon)
        add_item.show()
        menu.append(add_item)

        if config.get("geography.lock"):
            title = _('Unlock zoom and position')
        else:
            title = _('Lock zoom and position')
        add_item = gtk.MenuItem(title)
        add_item.connect("activate", self.config_zoom_and_position, event, lat,
                         lon)
        add_item.show()
        menu.append(add_item)

        add_item = gtk.MenuItem(_("Add place"))
        add_item.connect("activate", self.add_place, event, lat, lon)
        add_item.show()
        menu.append(add_item)

        add_item = gtk.MenuItem(_("Link place"))
        add_item.connect("activate", self.link_place, event, lat, lon)
        add_item.show()
        menu.append(add_item)

        add_item = gtk.MenuItem(_("Center here"))
        add_item.connect("activate", self.set_center, event, lat, lon)
        add_item.show()
        menu.append(add_item)

        # Add specific module menu
        self.add_specific_menu(menu, event, lat, lon)
        # Add a separator line
        add_item = gtk.MenuItem(None)
        add_item.show()
        menu.append(add_item)

        map_name = constants.map_title[config.get("geography.map_service")]
        title = _("Replace '%(map)s' by =>") % {'map': map_name}
        add_item = gtk.MenuItem(title)
        add_item.show()
        menu.append(add_item)

        changemap = gtk.Menu()
        changemap.set_title(title)
        changemap.show()
        add_item.set_submenu(changemap)
        # show in the map menu all available providers
        for map in constants.map_type:
            changemapitem = gtk.MenuItem(constants.map_title[map])
            changemapitem.show()
            changemapitem.connect("activate", self.change_map, map)
            changemap.append(changemapitem)
        menu.popup(None, None, None, 0, event.time)
        return 1
Ejemplo n.º 54
0
# gramps modules
#
#-------------------------------------------------------------------------
import GrampsDisplay
import ListModel
import Utils
import const
from gen.ggettext import sgettext as _

#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
WIKI_HELP_PAGE = '%s_-_Navigation' % const.URL_MANUAL_PAGE
WIKI_HELP_SEC = _('manual|Bookmarks')

#-------------------------------------------------------------------------
#
# Bookmarks
#
#-------------------------------------------------------------------------

TOP = '''<ui><menubar name="MenuBar"><menu action="BookMenu">'''
BTM = '''</menu></menubar></ui>'''

DISABLED = -1

class Bookmarks :
    "Handle the bookmarks interface for Gramps."