From 29620a31effe5c3a584dd7451d401fee34b9ae6f Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Wed, 2 Jan 2013 07:12:22 +0000 Subject: [PATCH] 6249: Please, add a tag when importing. Adds preference, and tag on import for CSV, XML, and GEDCOM. Cleaned up preferences, and added 'GEDCOM' to add source on import text. svn: r20939 --- gramps/gen/config.py | 2 + gramps/gui/configure.py | 71 ++++++++++++++++++------- gramps/plugins/importer/importcsv.py | 34 ++++++++++-- gramps/plugins/importer/importgedcom.py | 6 ++- gramps/plugins/importer/importgpkg.py | 1 + gramps/plugins/importer/importxml.py | 29 +++++++++- gramps/plugins/lib/libgedcom.py | 35 +++++++++++- 7 files changed, 151 insertions(+), 27 deletions(-) diff --git a/gramps/gen/config.py b/gramps/gen/config.py index c2fc94bea..3373c1fc0 100644 --- a/gramps/gen/config.py +++ b/gramps/gen/config.py @@ -279,6 +279,8 @@ register('preferences.date-format', 0) register('preferences.calendar-format-report', 0) register('preferences.cprefix', 'C%04d') register('preferences.default-source', False) +register('preferences.tag-on-import', False) +register('preferences.tag-on-import-format', _("Imported %Y/%m/%d %H:%M:%S")) register('preferences.eprefix', 'E%04d') register('preferences.family-warn', True) register('preferences.fprefix', 'F%04d') diff --git a/gramps/gui/configure.py b/gramps/gui/configure.py index ab3008640..406fe4e2c 100644 --- a/gramps/gui/configure.py +++ b/gramps/gui/configure.py @@ -327,13 +327,18 @@ class ConfigureDialog(ManagedWindow): config = self.__config if not callback: callback = self.update_entry - lwidget = BasicLabel("%s: " % label) + if label: + lwidget = BasicLabel("%s: " % label) entry = Gtk.Entry() entry.set_text(config.get(constant)) entry.connect('changed', callback, constant) - table.attach(lwidget, col_attach, col_attach+1, index, index+1, yoptions=0, - xoptions=Gtk.AttachOptions.FILL) - table.attach(entry, col_attach+1, col_attach+2, index, index+1, yoptions=0) + if label: + table.attach(lwidget, col_attach, col_attach+1, index, index+1, yoptions=0, + xoptions=Gtk.AttachOptions.FILL) + table.attach(entry, col_attach+1, col_attach+2, index, index+1, yoptions=0) + else: + table.attach(entry, col_attach, col_attach+1, index, index+1, yoptions=0) + return entry def add_pos_int_entry(self, table, label, index, constant, callback=None, config=None, col_attach=1): @@ -1101,6 +1106,11 @@ class GrampsPreferences(ConfigureDialog): config.set('behavior.do-not-show-previously-seen-updates', bool(active)) + def toggle_tag_on_import(self, obj): + active = obj.get_active() + config.set('preferences.tag-on-import', bool(active)) + self.tag_format_entry.set_sensitive(bool(active)) + def check_for_updates_changed(self, obj): active = obj.get_active() config.set('behavior.check-for-updates', active) @@ -1153,27 +1163,49 @@ class GrampsPreferences(ConfigureDialog): table.set_col_spacings(6) table.set_row_spacings(6) + current_line = 0 self.add_checkbox(table, - _('Add default source on import'), - 0, 'preferences.default-source') + _('Add default source on GEDCOM import'), + current_line, 'preferences.default-source') + + current_line += 1 + checkbutton = Gtk.CheckButton(_("Add tag on import")) + checkbutton.set_active(config.get('preferences.tag-on-import')) + checkbutton.connect("toggled", self.toggle_tag_on_import) + table.attach(checkbutton, 1, 2, current_line, current_line+1, yoptions=0) + self.tag_format_entry = self.add_entry(table, None, current_line, + 'preferences.tag-on-import-format', + col_attach=2) + self.tag_format_entry.set_sensitive(config.get('preferences.tag-on-import')) + + current_line += 1 self.add_checkbox(table, _('Enable spelling checker'), - 1, 'behavior.spellcheck') + current_line, 'behavior.spellcheck') + + current_line += 1 self.add_checkbox(table, _('Display Tip of the Day'), - 2, 'behavior.use-tips') + current_line, 'behavior.use-tips') + + current_line += 1 self.add_checkbox(table, _('Remember last view displayed'), - 3, 'preferences.use-last-view') + current_line, 'preferences.use-last-view') + + current_line += 1 self.add_spinner(table, _('Max generations for relationships'), - 4, 'behavior.generation-depth', (5, 50), self.update_gendepth) + current_line, 'behavior.generation-depth', (5, 50), self.update_gendepth) + + current_line += 1 self.path_entry = Gtk.Entry() self.add_path_box(table, _('Base path for relative media paths'), - 5, self.path_entry, self.dbstate.db.get_mediapath(), + current_line, self.path_entry, self.dbstate.db.get_mediapath(), self.set_mediapath, self.select_mediapath) + current_line += 1 # Check for updates: obox = Gtk.ComboBoxText() formats = [_("Never"), @@ -1186,9 +1218,10 @@ class GrampsPreferences(ConfigureDialog): obox.set_active(active) obox.connect('changed', self.check_for_updates_changed) lwidget = BasicLabel("%s: " % _('Check for updates')) - table.attach(lwidget, 1, 2, 6, 7, yoptions=0) - table.attach(obox, 2, 3, 6, 7, yoptions=0) + table.attach(lwidget, 1, 2, current_line, current_line+1, yoptions=0) + table.attach(obox, 2, 3, current_line, current_line+1, yoptions=0) + current_line += 1 self.whattype_box = Gtk.ComboBoxText() formats = [_("Updated addons only"), _("New addons only"), @@ -1203,21 +1236,23 @@ class GrampsPreferences(ConfigureDialog): self.whattype_box.set_active(0) self.whattype_box.connect('changed', self.check_for_type_changed) lwidget = BasicLabel("%s: " % _('What to check')) - table.attach(lwidget, 1, 2, 7, 8, yoptions=0) - table.attach(self.whattype_box, 2, 3, 7, 8, yoptions=0) + table.attach(lwidget, 1, 2, current_line, current_line+1, yoptions=0) + table.attach(self.whattype_box, 2, 3, current_line, current_line+1, yoptions=0) - self.add_entry(table, _('Where to check'), 8, 'behavior.addons-url', col_attach=1) + current_line += 1 + self.add_entry(table, _('Where to check'), current_line, 'behavior.addons-url', col_attach=1) + current_line += 1 checkbutton = Gtk.CheckButton( _("Do not ask about previously notified addons")) checkbutton.set_active(config.get('behavior.do-not-show-previously-seen-updates')) checkbutton.connect("toggled", self.toggle_hide_previous_addons) - table.attach(checkbutton, 0, 3, 9, 10, yoptions=0) + table.attach(checkbutton, 0, 3, current_line, current_line+1, yoptions=0) button = Gtk.Button(_("Check now")) button.connect("clicked", lambda obj: \ self.uistate.viewmanager.check_for_updates(force=True)) - table.attach(button, 3, 4, 9, 10, yoptions=0) + table.attach(button, 3, 4, current_line, current_line+1, yoptions=0) return _('General'), table diff --git a/gramps/plugins/importer/importcsv.py b/gramps/plugins/importer/importcsv.py index b3b2b6dee..e11fb14cd 100644 --- a/gramps/plugins/importer/importcsv.py +++ b/gramps/plugins/importer/importcsv.py @@ -50,7 +50,7 @@ LOG = logging.getLogger(".ImportCSV") #------------------------------------------------------------------------- from gramps.gen.ggettext import sgettext as _ from gramps.gen.ggettext import ngettext -from gramps.gen.lib import ChildRef, Citation, Event, EventRef, EventType, Family, FamilyRelType, Name, NameType, Note, NoteType, Person, Place, Source, Surname +from gramps.gen.lib import ChildRef, Citation, Event, EventRef, EventType, Family, FamilyRelType, Name, NameType, Note, NoteType, Person, Place, Source, Surname, Tag from gramps.gen.db import DbTxn from gramps.gen.plug.utils import OpenFileOrStdin from gramps.gen.datehandler import parser as _dp @@ -59,6 +59,7 @@ from gramps.gen.utils.id import create_id from gramps.gui.utils import ProgressMeter from gramps.gen.lib.eventroletype import EventRoleType from gramps.gen.constfunc import cuni, conv_to_unicode, STRTYPE +from gramps.gen.config import config #------------------------------------------------------------------------- # @@ -95,6 +96,8 @@ class UTF8Recoder(object): "Encode the next line of the file." return self.reader.next().encode("utf-8") + next = __next__ + class UnicodeReader(object): """ A CSV reader which will iterate over lines in the CSV file, @@ -120,6 +123,8 @@ class UnicodeReader(object): def __iter__(self): return self + next = __next__ + #------------------------------------------------------------------------- # # Support and main functions @@ -141,7 +146,8 @@ def rd(line_number, row, col, key, default = None): def importData(dbase, filename, user): """Function called by Gramps to import data on persons in CSV format.""" - parser = CSVParser(dbase, user) + parser = CSVParser(dbase, user, (config.get('preferences.tag-on-import-format') if + config.get('preferences.tag-on-import') else None)) try: with OpenFileOrStdin(filename, 'b') as filehandle: parser.parse(filehandle) @@ -157,7 +163,7 @@ def importData(dbase, filename, user): #------------------------------------------------------------------------- class CSVParser(object): """Class to read data in CSV format from a file object.""" - def __init__(self, dbase, user): + def __init__(self, dbase, user, default_tag_format=None): self.db = dbase self.user = user self.trans = None @@ -235,6 +241,16 @@ class CSVParser(object): for val in column2label[key]: lab2col_dict.append((val, key)) self.label2column = dict(lab2col_dict) + if default_tag_format: + name = time.strftime(default_tag_format) + tag = self.db.get_tag_from_name(name) + if tag: + self.default_tag = tag + else: + self.default_tag = Tag() + self.default_tag.set_name(name) + else: + self.default_tag = None def cleanup_column_name(self, column): """Handle column aliases for CSV spreadsheet import and SQL.""" @@ -313,6 +329,8 @@ class CSVParser(object): tym = time.time() self.db.disable_signals() with DbTxn(_("CSV import"), self.db, batch=True) as self.trans: + if self.default_tag and self.default_tag.handle is None: + self.db.add_tag(self.default_tag, self.trans) self._parse_csv_data(data, progress) self.db.enable_signals() self.db.request_rebuild() @@ -432,6 +450,8 @@ class CSVParser(object): new_note.handle = create_id() new_note.type.set(NoteType.EVENT) new_note.set(note) + if self.default_tag: + new_note.add_tag(self.default_tag.handle) self.db.add_note(new_note, self.trans) marriage.add_note(new_note.handle) self.db.commit_event(marriage, self.trans) @@ -506,6 +526,8 @@ class CSVParser(object): new_note.handle = create_id() new_note.type.set(NoteType.PERSON) new_note.set(note) + if self.default_tag: + new_note.add_tag(self.default_tag.handle) self.db.add_note(new_note, self.trans) child.add_note(new_note.handle) self.db.commit_person(child, self.trans) @@ -592,6 +614,8 @@ class CSVParser(object): new_note.handle = create_id() new_note.type.set(NoteType.PERSON) new_note.set(note) + if self.default_tag: + new_note.add_tag(self.default_tag.handle) self.db.add_note(new_note, self.trans) person.add_note(new_note.handle) if grampsid is not None: @@ -719,6 +743,8 @@ class CSVParser(object): family.set_gramps_id(id_) # add it: family.set_handle(self.db.create_id()) + if self.default_tag: + family.add_tag(self.default_tag.handle) if husband: family.set_father_handle(husband.get_handle()) husband.add_family_handle(family.get_handle()) @@ -775,6 +801,8 @@ class CSVParser(object): def create_person(self): """ Used to create a new person we know doesn't exist """ person = Person() + if self.default_tag: + person.add_tag(self.default_tag.handle) self.db.add_person(person, self.trans) self.indi_count += 1 return person diff --git a/gramps/plugins/importer/importgedcom.py b/gramps/plugins/importer/importgedcom.py index 7e2c9e8e4..cdcccd886 100644 --- a/gramps/plugins/importer/importgedcom.py +++ b/gramps/plugins/importer/importgedcom.py @@ -115,8 +115,10 @@ def importData(database, filename, user): stage_one.set_encoding(code_set) ifile.seek(0) gedparse = libgedcom.GedcomParser( - database, ifile, filename, user, stage_one, - config.get('preferences.default-source')) + database, ifile, filename, user, stage_one, + config.get('preferences.default-source'), + (config.get('preferences.tag-on-import-format') if + config.get('preferences.tag-on-import') else None)) except IOError as msg: user.notify_error(_("%s could not be opened\n") % filename, str(msg)) return diff --git a/gramps/plugins/importer/importgpkg.py b/gramps/plugins/importer/importgpkg.py index e8c6c88f0..7f6266530 100644 --- a/gramps/plugins/importer/importgpkg.py +++ b/gramps/plugins/importer/importgpkg.py @@ -94,6 +94,7 @@ def impData(database, name, user): 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 : diff --git a/gramps/plugins/importer/importxml.py b/gramps/plugins/importer/importxml.py index 904625d7c..fdaeaff36 100644 --- a/gramps/plugins/importer/importxml.py +++ b/gramps/plugins/importer/importxml.py @@ -67,6 +67,7 @@ from gramps.gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY, CITATION_KEY) from gramps.gen.updatecallback import UpdateCallback from gramps.gen.const import VERSION +from gramps.gen.config import config #import gramps.plugins.lib.libgrampsxml from gramps.plugins.lib import libgrampsxml @@ -123,7 +124,9 @@ def importData(database, filename, user): change = time.time() else: change = os.path.getmtime(filename) - parser = GrampsParser(database, user, change) + parser = GrampsParser(database, user, change, + (config.get('preferences.tag-on-import-format') if + config.get('preferences.tag-on-import') else None)) if filename != '-': linecounter = LineParser(filename) @@ -457,7 +460,7 @@ class ImportOpenFileContextManager: #------------------------------------------------------------------------- class GrampsParser(UpdateCallback): - def __init__(self, database, user, change): + def __init__(self, database, user, change, default_tag_format=None): UpdateCallback.__init__(self, user.callback) self.user = user self.__gramps_version = 'unknown' @@ -564,6 +567,17 @@ class GrampsParser(UpdateCallback): self.eidswap = {} self.import_handles = {} + if default_tag_format: + name = time.strftime(default_tag_format) + tag = self.db.get_tag_from_name(name) + if tag: + self.default_tag = tag + else: + self.default_tag = Tag() + self.default_tag.set_name(name) + else: + self.default_tag = None + self.func_map = { #name part "name": (self.start_name, self.stop_name), @@ -895,6 +909,9 @@ class GrampsParser(UpdateCallback): self.db.disable_signals() + if self.default_tag and self.default_tag.handle is None: + self.db.add_tag(self.default_tag, self.trans) + self.p = ParserCreate() self.p.StartElementHandler = self.startElement self.p.EndElementHandler = self.endElement @@ -1384,6 +1401,8 @@ class GrampsParser(UpdateCallback): self.person.change = int(attrs.get('change', self.change)) self.info.add('new-object', PERSON_KEY, self.person) self.convert_marker(attrs, self.person) + if self.default_tag: + self.person.add_tag(self.default_tag.handle) return self.person def start_people(self, attrs): @@ -1520,6 +1539,8 @@ class GrampsParser(UpdateCallback): if 'type' in attrs: self.family.type.set_from_xml_str(attrs["type"]) self.convert_marker(attrs, self.family) + if self.default_tag: + self.family.add_tag(self.default_tag.handle) return self.family def start_rel(self, attrs): @@ -1833,6 +1854,8 @@ class GrampsParser(UpdateCallback): #set correct change time self.db.commit_note(self.note, self.trans, self.change) self.info.add('new-object', NOTE_KEY, self.note) + if self.default_tag: + self.note.add_tag(self.default_tag.handle) return self.note def start_noteref(self, attrs): @@ -2088,6 +2111,8 @@ class GrampsParser(UpdateCallback): src = attrs.get("src", '') if src: self.object.path = src + if self.default_tag: + self.object.add_tag(self.default_tag.handle) return self.object def start_repo(self, attrs): diff --git a/gramps/plugins/lib/libgedcom.py b/gramps/plugins/lib/libgedcom.py index 62c4ce9f8..9fe68dfa4 100644 --- a/gramps/plugins/lib/libgedcom.py +++ b/gramps/plugins/lib/libgedcom.py @@ -127,7 +127,7 @@ from gramps.gen.lib import (Address, Attribute, AttributeType, ChildRef, ChildRefType, Citation, Date, Event, EventRef, EventRoleType, EventType, Family, FamilyRelType, LdsOrd, Location, MediaObject, MediaRef, Name, NameType, Note, NoteType, Person, PersonRef, Place, - RepoRef, Repository, RepositoryType, Researcher, Source, + RepoRef, Repository, RepositoryType, Researcher, Source, Tag, SourceMediaType, Surname, Url, UrlType) from gramps.gen.db import DbTxn from gramps.gen.updatecallback import UpdateCallback @@ -1807,7 +1807,7 @@ class GedcomParser(UpdateCallback): return name def __init__(self, dbase, ifile, filename, user, stage_one, - default_source): + default_source, default_tag_format=None): UpdateCallback.__init__(self, user.callback) self.user = user self.set_total(stage_one.get_line_count()) @@ -1835,6 +1835,16 @@ class GedcomParser(UpdateCallback): self.def_src = Source() fname = os.path.basename(filename).split('\\')[-1] self.def_src.set_title(_("Import from GEDCOM (%s)") % fname) + if default_tag_format: + name = time.strftime(default_tag_format) + tag = self.dbase.get_tag_from_name(name) + if tag: + self.default_tag = tag + else: + self.default_tag = Tag() + self.default_tag.set_name(name) + else: + self.default_tag = None self.dir_path = os.path.dirname(filename) self.is_ftw = False self.groups = None @@ -2594,6 +2604,8 @@ class GedcomParser(UpdateCallback): self.want_parse_warnings = True if self.use_def_src: self.dbase.add_source(self.def_src, self.trans) + if self.default_tag and self.default_tag.handle is None: + self.dbase.add_tag(self.default_tag, self.trans) self.__parse_record() self.__parse_trailer() for title, handle in self.inline_srcs.items(): @@ -3318,6 +3330,9 @@ class GedcomParser(UpdateCallback): # Add the default reference if no source has found self.__add_default_source(person) + # Add a default tag if provided + self.__add_default_tag(person) + self.__check_msgs(_("INDI (individual) Gramps ID %s") % person.get_gramps_id(), state, person) # commit the person to the database @@ -4579,6 +4594,9 @@ class GedcomParser(UpdateCallback): # add default reference if no reference exists self.__add_default_source(family) + # Add a default tag if provided + self.__add_default_tag(family) + self.__check_msgs(_("FAM (family) Gramps ID %s") % family.get_gramps_id(), state, family) # commit family to database @@ -6118,6 +6136,9 @@ class GedcomParser(UpdateCallback): # Add the default reference if no source has found self.__add_default_source(media) + # Add a default tag if provided + self.__add_default_tag(media) + self.__check_msgs(_("OBJE (multi-media object) Gramps ID %s") % media.get_gramps_id(), state, media) # commit the person to the database @@ -6931,6 +6952,9 @@ class GedcomParser(UpdateCallback): self.__undefined) state.msg += sub_state.msg + # Add a default tag if provided + self.__add_default_tag(new_note) + self.dbase.commit_note(new_note, self.trans, new_note.change) obj.add_note(new_note.get_handle()) @@ -7255,6 +7279,13 @@ class GedcomParser(UpdateCallback): self.dbase.add_citation(citation, self.trans) obj.add_citation(citation.handle) + def __add_default_tag(self, obj): + """ + Add the default tag to the object. + """ + if self.default_tag: + obj.add_tag(self.default_tag.handle) + def __subm_name(self, line, state): """ @param line: The current line in GedLine format