def from_struct(struct): """ Given a struct with metadata, create a Gramps object. """ from gramps.gen.lib import (Person, Family, Event, Source, Place, Citation, Repository, MediaObject, Note, Tag) if isinstance(struct, dict): if "_class" in struct.keys(): if struct["_class"] == "Person": return Person.create(Person.from_struct(struct)) elif struct["_class"] == "Family": return Family.create(Family.from_struct(struct)) elif struct["_class"] == "Event": return Event.create(Event.from_struct(struct)) elif struct["_class"] == "Source": return Source.create(Source.from_struct(struct)) elif struct["_class"] == "Place": return Place.create(Place.from_struct(struct)) elif struct["_class"] == "Citation": return Citation.create(Citation.from_struct(struct)) elif struct["_class"] == "Repository": return Repository.create(Repository.from_struct(struct)) elif struct["_class"] == "MediaObject": return MediaObject.create(MediaObject.from_struct(struct)) elif struct["_class"] == "Note": return Note.create(Note.from_struct(struct)) elif struct["_class"] == "Tag": return Tag.create(Tag.from_struct(struct)) raise AttributeError("invalid struct: %s" % struct)
def instance_from_struct(cls, struct): """ Given a struct with metadata, create a Gramps object. self is class when called as a classmethod. """ from gramps.gen.lib import (Person, Family, Event, Source, Place, Citation, Repository, Media, Note, Tag, Date) if isinstance(struct, dict): if "_class" in struct.keys(): if struct["_class"] == "Person": return Person.create(Person.from_struct(struct)) elif struct["_class"] == "Family": return Family.create(Family.from_struct(struct)) elif struct["_class"] == "Event": return Event.create(Event.from_struct(struct)) elif struct["_class"] == "Source": return Source.create(Source.from_struct(struct)) elif struct["_class"] == "Place": return Place.create(Place.from_struct(struct)) elif struct["_class"] == "Citation": return Citation.create(Citation.from_struct(struct)) elif struct["_class"] == "Repository": return Repository.create(Repository.from_struct(struct)) elif struct["_class"] == "Media": return Media.create(Media.from_struct(struct)) elif struct["_class"] == "Note": return Note.create(Note.from_struct(struct)) elif struct["_class"] == "Tag": return Tag.create(Tag.from_struct(struct)) elif struct["_class"] == "Date": return Date().unserialize(Date.from_struct(struct, full=True)) raise AttributeError("invalid struct: %s" % struct)
def add(self, obj): person = Person() # attempt to get the current surname (model, pathlist) = self.selection.get_selected_rows() name = Name() #the editor requires a surname name.add_surname(Surname()) name.set_primary_surname(0) basepers = None if len(pathlist) == 1: path = pathlist[0] pathids = path.get_indices() if len(pathids) == 1: path = Gtk.TreePath((pathids[0], 0)) iter_ = model.get_iter(path) handle = model.get_handle_from_iter(iter_) basepers = self.dbstate.db.get_person_from_handle(handle) if basepers: preset_name(basepers, name) person.set_primary_name(name) try: EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass
def add(self, *obj): person = Person() # attempt to get the current surname (model, pathlist) = self.selection.get_selected_rows() name = Name() #the editor requires a surname name.add_surname(Surname()) name.set_primary_surname(0) basepers = None if len(pathlist) == 1: path = pathlist[0] pathids = path.get_indices() if len(pathids) == 1: path = Gtk.TreePath((pathids[0], 0)) iter_ = model.get_iter(path) handle = model.get_handle_from_iter(iter_) basepers = self.dbstate.db.get_person_from_handle(handle) if basepers: preset_name(basepers, name) person.set_primary_name(name) try: EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass
def instance_from_struct(cls, struct): """ Given a struct with metadata, create a Gramps object. self is class when called as a classmethod. """ from gramps.gen.lib import (Person, Family, Event, Source, Place, Citation, Repository, Media, Note, Tag, Date) if isinstance(struct, dict): if "_class" in struct.keys(): if struct["_class"] == "Person": return Person.create(Person.from_struct(struct)) elif struct["_class"] == "Family": return Family.create(Family.from_struct(struct)) elif struct["_class"] == "Event": return Event.create(Event.from_struct(struct)) elif struct["_class"] == "Source": return Source.create(Source.from_struct(struct)) elif struct["_class"] == "Place": return Place.create(Place.from_struct(struct)) elif struct["_class"] == "Citation": return Citation.create(Citation.from_struct(struct)) elif struct["_class"] == "Repository": return Repository.create(Repository.from_struct(struct)) elif struct["_class"] == "Media": return Media.create(Media.from_struct(struct)) elif struct["_class"] == "Note": return Note.create(Note.from_struct(struct)) elif struct["_class"] == "Tag": return Tag.create(Tag.from_struct(struct)) elif struct["_class"] == "Date": return Date().unserialize( Date.from_struct(struct, full=True)) raise AttributeError("invalid struct: %s" % struct)
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
def next_person(self): """A VCard for another person is started.""" if self.person is not None: self.finish_person() LOG.warn("BEGIN property not properly closed by END property, " "Gramps can't cope with nested VCards.") self.person = Person() self.formatted_name = '' self.name_parts = ''
def add_participant(self, *obj): person = Person() ref = EventRef() ref.ref = self.handle person.add_event_ref(ref) try: EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass
def __add_person(self, gender, first_name, surname, trans): person = Person() person.gender = gender name = person.primary_name name.first_name = first_name surname1 = Surname() surname1.surname = surname name.set_surname_list([surname1]) self.all_surnames.append(surname) self.db.add_person(person, trans)
def _add_person(gender, first_name, surname, trans, db): person = Person() person.gender = gender _name = person.primary_name _name.first_name = first_name surname1 = Surname() surname1.surname = surname _name.set_surname_list([surname1]) person.gramps_id = "person001" db.add_person(person, trans)
def next_person(self): """A VCard for another person is started.""" if self.person is not None: self.finish_person() self.__add_msg(_("BEGIN property not properly closed by END " "property, Gramps can't cope with nested VCards."), self.line_num - 1) self.person = Person() self.formatted_name = '' self.name_parts = ''
def get_or_create_person(self, firstname, lastname): person = None mykey = firstname + lastname if mykey in self.ikeys and firstname != "?" and lastname != "?": person = self.db.get_person_from_handle(self.ikeys[mykey]) else: person = Person() self.db.add_person(person, self.trans) self.db.commit_person(person, self.trans) self.ikeys[mykey] = person.get_handle() return person
def get_or_create_person(self,firstname,lastname): person = None mykey = firstname+lastname if mykey in self.ikeys and firstname != "?" and lastname != "?": person = self.db.get_person_from_handle(self.ikeys[mykey]) else: person = Person() self.db.add_person(person,self.trans) self.db.commit_person(person,self.trans) self.ikeys[mykey] = person.get_handle() return person
def add_mother_clicked(self, obj): person = Person() person.set_gender(Person.FEMALE) autoname = config.get("behavior.surname-guessing") # _("Father's surname"), # _("None"), # _("Combination of mother's and father's surname"), # _("Icelandic style"), if autoname == 2: name = self.latin_american_child("mother") else: name = self.no_name() person.set_primary_name(name) EditPerson(self.dbstate, self.uistate, self.track, person, self.new_mother_added)
def log(self, ltype, action, handles): for handle in set(handles): if self.last_log == (ltype, action, handle): continue self.last_log = (ltype, action, handle) self.timestamp() # Translators: needed for French, ignore otherwise self.append_text(_("%s: ") % _(action)) if action == 'Deleted': transaction = self.dbstate.db.transaction if ltype == 'Person': name = 'a person' if transaction is not None: for i in transaction.get_recnos(reverse=True): (obj_type, trans_type, hndl, old_data, dummy) = \ transaction.get_record(i) if isinstance(hndl, bytes): hndl = str(hndl, "utf-8") if (obj_type == PERSON_KEY and trans_type == TXNDEL and hndl == handle): person = Person() person.unserialize(old_data) name = name_displayer.display(person) break elif ltype == 'Family': name = 'a family' if transaction is not None: for i in transaction.get_recnos(reverse=True): (obj_type, trans_type, hndl, old_data, dummy) = \ transaction.get_record(i) if isinstance(hndl, bytes): hndl = str(hndl, "utf-8") if (obj_type == FAMILY_KEY and trans_type == TXNDEL and hndl == handle): family = Family() family.unserialize(old_data) name = family_name(family, self.dbstate.db, name) break self.append_text(name) else: if ltype == 'Person': person = self.dbstate.db.get_person_from_handle(handle) name = name_displayer.display(person) elif ltype == 'Family': family = self.dbstate.db.get_family_from_handle(handle) name = family_name(family, self.dbstate.db, 'a family') self.link(name, ltype, handle) self.append_text("\n")
def log(self, ltype, action, handles): for handle in set(handles): if self.last_log == (ltype, action, handle): continue self.last_log = (ltype, action, handle) self.timestamp() # translators: needed for French, ignore otherwise self.append_text(_("%s: ") % _(action)) if action == 'Deleted': transaction = self.dbstate.db.transaction if ltype == 'Person': name = 'a person' if transaction is not None: for i in transaction.get_recnos(reverse=True): (obj_type, trans_type, hndl, old_data, dummy) = \ transaction.get_record(i) if isinstance(hndl, bytes): hndl = str(hndl, "utf-8") if (obj_type == PERSON_KEY and trans_type == TXNDEL and hndl == handle): person = Person() person.unserialize(old_data) name = name_displayer.display(person) break elif ltype == 'Family': name = 'a family' if transaction is not None: for i in transaction.get_recnos(reverse=True): (obj_type, trans_type, hndl, old_data, dummy) = \ transaction.get_record(i) if isinstance(hndl, bytes): hndl = str(hndl, "utf-8") if (obj_type == FAMILY_KEY and trans_type == TXNDEL and hndl == handle): family = Family() family.unserialize(old_data) name = family_name(family, self.dbstate.db, name) break self.append_text(name) else: if ltype == 'Person': person = self.dbstate.db.get_person_from_handle(handle) name = name_displayer.display(person) elif ltype == 'Family': family = self.dbstate.db.get_family_from_handle(handle) name = family_name(family, self.dbstate.db, 'a family') self.link(name, ltype, handle) self.append_text("\n")
def __add_person(self, button): """ Create a new person and add them to the form. """ person = Person() EditPerson(self.dbstate, self.uistate, self.track, person, self.__person_added)
def get_person_profile_for_object( db_handle: DbReadBase, person: Person, with_family: bool = True, with_events: bool = True, ) -> Person: """Get person profile given a Person.""" profile = { "handle": person.handle, "sex": get_sex_profile(person), "birth": get_birth_profile(db_handle, person), "death": get_death_profile(db_handle, person), "name_given": nd.display_given(person), "name_surname": person.primary_name.get_surname(), } if with_family: primary_parent_family_handle = person.get_main_parents_family_handle() profile["primary_parent_family"] = get_family_profile_for_handle( db_handle, primary_parent_family_handle) profile["other_parent_families"] = [] for handle in person.parent_family_list: if handle != primary_parent_family_handle: profile["other_parent_families"].append( get_family_profile_for_handle(db_handle, handle)) profile["families"] = [ get_family_profile_for_handle(db_handle, handle) for handle in person.family_list ] if with_events: profile["events"] = [ get_event_profile_for_handle(db_handle, event_ref.ref) for event_ref in person.event_ref_list ] return profile
def add_button_clicked(self, obj=None): person = Person() autoname = config.get("behavior.surname-guessing") # _("Father's surname"), # _("None"), # _("Combination of mother's and father's surname"), # _("Icelandic style"), if autoname == 0: name = self.north_american() elif autoname == 2: name = self.latin_american() else: name = self.no_name() person.set_primary_name(name) EditPerson(self.dbstate, self.uistate, self.track, person, self.new_child_added)
def get_deathdate(db: DbReadBase, person: Person) -> Optional[str]: """Return the formatted death date.""" death_ref = person.get_death_ref() try: return get_event_date_from_handle(db, death_ref.ref) except (AttributeError, HandleError): return None
def get_birthdate(db: DbReadBase, person: Person) -> Optional[str]: """Return the formatted birth date of a person.""" birth_handle = person.get_birth_ref() try: return get_event_date_from_handle(db, birth_handle.ref) except (AttributeError, HandleError): return None
def importData(db, filename, user): """Function called by Gramps to import data on persons in CSV format.""" db.disable_signals() try: with DbTxn(_("JSON import"), db, batch=True) as trans: with OpenFileOrStdin(filename, encoding="utf-8") as fp: line = fp.readline() while line: data = json.loads(line) if data["_class"] == "Person": obj = Person.create(Person.from_struct(data)) db.add_person(obj, trans) elif data["_class"] == "Family": obj = Family.create(Family.from_struct(data)) db.add_family(obj, trans) elif data["_class"] == "Event": obj = Event.create(Event.from_struct(data)) db.add_event(obj, trans) elif data["_class"] == "Media": obj = Media.create(Media.from_struct(data)) db.add_media(obj, trans) elif data["_class"] == "Repository": obj = Repository.create(Repository.from_struct(data)) db.add_repository(obj, trans) elif data["_class"] == "Tag": obj = Tag.create(Tag.from_struct(data)) db.add_tag(obj, trans) elif data["_class"] == "Source": obj = Source.create(Source.from_struct(data)) db.add_source(obj, trans) elif data["_class"] == "Citation": obj = Citation.create(Citation.from_struct(data)) db.add_citation(obj, trans) elif data["_class"] == "Note": obj = Note.create(Note.from_struct(data)) db.add_note(obj, trans) elif data["_class"] == "Place": obj = Place.create(Place.from_struct(data)) db.add_place(obj, trans) else: LOG.warn("ignored: " + data) line = fp.readline() except EnvironmentError as err: user.notify_error(_("%s could not be opened\n") % filename, str(err)) db.enable_signals() db.request_rebuild()
def get_deathplace_grampsid(db: DbReadBase, person: Person) -> Optional[GrampsId]: """Return the name of the death place.""" death_ref = person.get_death_ref() try: return get_event_place_from_handle(db, death_ref.ref) except (AttributeError, HandleError): return None
def add_button_clicked(self, obj=None): person = Person() autoname = config.get('behavior.surname-guessing') #_("Father's surname"), #_("None"), #_("Combination of mother's and father's surname"), #_("Icelandic style"), if autoname == 0: name = self.north_american() elif autoname == 2: name = self.latin_american() else: name = self.no_name() person.set_primary_name(name) EditPerson(self.dbstate, self.uistate, self.track, person, self.new_child_added)
def get_parents_grampsids(db: DbReadBase, person: Person) -> Optional[GrampsId]: """Get the Gramps IDs of the family's parents.""" handle = person.get_main_parents_family_handle() try: return db.get_family_from_handle(handle).gramps_id except HandleError: return None
def get(self, path=""): """ HANDLE HANDLE/edit|delete /add b2cfa6ca1e174b1f63d/remove/eventref/1 """ page = int(self.get_argument("page", 1)) search = self.get_argument("search", "") if "/" in path: handle, action = path.split("/", 1) else: handle, action = path, "view" if handle: if handle == "add": person = Person() person.primary_name.surname_list.append(Surname()) action = "edit" else: person = self.database.get_person_from_handle(handle) if person: person.probably_alive = True self.render( "person.html", **self.get_template_dict(tview=_("person detail"), action=action, page=page, search=search, form=PersonForm(self.database, _, instance=person), logform=None)) return else: self.clear() self.set_status(404) self.finish("<html><body>No such person</body></html>") return self.render( "page_view.html", **self.get_template_dict( tview=_("person view"), page=page, search=search, form=PersonForm(self.database, _, table="Person"), ))
def next_person(self): """A VCard for another person is started.""" if self.person is not None: self.finish_person() LOG.warning("BEGIN property not properly closed by END property, " "Gramps can't cope with nested VCards.") self.person = Person() self.formatted_name = '' self.name_parts = ''
def add_child_to_fam(self, obj, event, handle): if button_activated(event, _LEFT_BUTTON): callback = lambda x: self.callback_add_child(x, handle) person = Person() name = Name() #the editor requires a surname name.add_surname(Surname()) name.set_primary_surname(0) family = self.dbstate.db.get_family_from_handle(handle) father = self.dbstate.db.get_person_from_handle( family.get_father_handle()) if father: preset_name(father, name) person.set_primary_name(name) try: EditPerson(self.dbstate, self.uistate, [], person, callback=callback) except WindowActiveError: pass
def get(self, path=""): """ HANDLE HANDLE/edit|delete /add b2cfa6ca1e174b1f63d/remove/eventref/1 """ page = int(self.get_argument("page", 1)) search = self.get_argument("search", "") if "/" in path: handle, action= path.split("/", 1) else: handle, action = path, "view" if handle: if handle == "add": person = Person() person.primary_name.surname_list.append(Surname()) action = "edit" else: person = self.database.get_person_from_handle(handle) if person: person.probably_alive = True self.render("person.html", **self.get_template_dict(tview=_("person detail"), action=action, page=page, search=search, form=PersonForm(self.database, _, instance=person), logform=None)) return else: self.clear() self.set_status(404) self.finish("<html><body>No such person</body></html>") return self.render("page_view.html", **self.get_template_dict(tview=_("person view"), page=page, search=search, form=PersonForm(self.database, _, table="Person"), ) )
def empty_object(self): """ Return an empty Person object for comparison for changes. This is used by the base class (EditPrimary). """ person = Person() #the editor requires a surname person.primary_name.add_surname(Surname()) person.primary_name.set_primary_surname(0) return person
def object_extend(self, obj: Person, args: Dict) -> Person: """Extend person attributes as needed.""" db_handle = self.db_handle if "profile" in args: obj.profile = get_person_profile_for_object(db_handle, obj, with_family=True, with_events=True) if "extend" in args: obj.extended = get_extended_attributes(db_handle, obj, args) if "all" in args["extend"] or "families" in args["extend"]: obj.extended["families"] = [ get_family_by_handle(db_handle, handle) for handle in obj.family_list ] if "all" in args["extend"] or "parent_families" in args["extend"]: obj.extended["parent_families"] = [ get_family_by_handle(db_handle, handle) for handle in obj.parent_family_list ] if "all" in args["extend"] or "primary_parent_family" in args[ "extend"]: obj.extended["primary_parent_family"] = get_family_by_handle( db_handle, obj.get_main_parents_family_handle()) return obj
def add(self, obj): """ Add a new person to the database. """ person = Person() #the editor requires a surname person.primary_name.add_surname(Surname()) person.primary_name.set_primary_surname(0) try: EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass
def post(self, path): if "/" in path: handle, action = path.split("/") else: handle, action = path, "view" if handle == "add": person = Person() person.primary_name.surname_list.append(Surname()) person.handle = handle = create_id() else: person = self.database.get_person_from_handle(handle) form = PersonForm(self.database, _, instance=person) form.save(handler=self) self.redirect("/person/%(handle)s" % {"handle": handle})
def add_mother_clicked(self, obj): person = Person() person.set_gender(Person.FEMALE) autoname = config.get('behavior.surname-guessing') #_("Father's surname"), #_("None"), #_("Combination of mother's and father's surname"), #_("Icelandic style"), if autoname == 2: name = self.latin_american_child("mother") else: name = self.no_name() person.set_primary_name(name) EditPerson(self.dbstate, self.uistate, self.track, person, self.new_mother_added)
def run_tool(self): self.progress = ProgressMeter(_('Running Date Test'),'', parent=self.parent_window) self.progress.set_pass(_('Generating dates'), 4) dates = [] # first some valid dates calendar = Date.CAL_GREGORIAN for quality in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, Date.QUAL_CALCULATED): for modifier in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER, Date.MOD_ABOUT): for slash1 in (False,True): for month in range(0,13): for day in (0,5,27): if not month and day: continue d = Date() d.set(quality,modifier,calendar,(day,month,1789,slash1),"Text comment") dates.append( d) for modifier in (Date.MOD_RANGE, Date.MOD_SPAN): for slash1 in (False,True): for slash2 in (False,True): for month in range(0,13): for day in (0,5,27): if not month and day: continue d = Date() d.set(quality,modifier,calendar,(day,month,1789,slash1,day,month,1876,slash2),"Text comment") dates.append( d) if not month: continue d = Date() d.set(quality,modifier,calendar,(day,month,1789,slash1,day,13-month,1876,slash2),"Text comment") dates.append( d) if not day: continue d = Date() d.set(quality,modifier,calendar,(day,month,1789,slash1,32-day,month,1876,slash2),"Text comment") dates.append( d) d = Date() d.set(quality,modifier,calendar,(day,month,1789,slash1,32-day,13-month,1876,slash2),"Text comment") dates.append( d) modifier = Date.MOD_TEXTONLY d = Date() d.set(quality,modifier,calendar,Date.EMPTY, "This is a textual date") dates.append( d) self.progress.step() # test invalid dates #dateval = (4,7,1789,False,5,8,1876,False) #for l in range(1,len(dateval)): # d = Date() # try: # d.set(Date.QUAL_NONE,Date.MOD_NONE, # Date.CAL_GREGORIAN,dateval[:l],"Text comment") # dates.append( d) # except DateError, e: # d.set_as_text("Date identified value correctly as invalid.\n%s" % e) # dates.append( d) # except: # d = Date() # d.set_as_text("Date.set Exception %s" % ("".join(traceback.format_exception(*sys.exc_info())),)) # dates.append( d) #for l in range(1,len(dateval)): # d = Date() # try: # d.set(Date.QUAL_NONE,Date.MOD_SPAN,Date.CAL_GREGORIAN,dateval[:l],"Text comment") # dates.append( d) # except DateError, e: # d.set_as_text("Date identified value correctly as invalid.\n%s" % e) # dates.append( d) # except: # d = Date() # d.set_as_text("Date.set Exception %s" % ("".join(traceback.format_exception(*sys.exc_info())),)) # dates.append( d) #self.progress.step() #d = Date() #d.set(Date.QUAL_NONE,Date.MOD_NONE, # Date.CAL_GREGORIAN,(44,7,1789,False),"Text comment") #dates.append( d) #d = Date() #d.set(Date.QUAL_NONE,Date.MOD_NONE, # Date.CAL_GREGORIAN,(4,77,1789,False),"Text comment") #dates.append( d) #d = Date() #d.set(Date.QUAL_NONE,Date.MOD_SPAN, # Date.CAL_GREGORIAN, # (4,7,1789,False,55,8,1876,False),"Text comment") #dates.append( d) #d = Date() #d.set(Date.QUAL_NONE,Date.MOD_SPAN, # Date.CAL_GREGORIAN, # (4,7,1789,False,5,88,1876,False),"Text comment") #dates.append( d) with DbTxn(_("Date Test Plugin"), self.db, batch=True) as self.trans: self.db.disable_signals() self.progress.set_pass(_('Generating dates'), len(dates)) # create pass and fail tags pass_handle = self.create_tag(_('Pass'), '#0000FFFF0000') fail_handle = self.create_tag(_('Fail'), '#FFFF00000000') # now add them as birth to new persons i = 1 for dateval in dates: person = Person() surname = Surname() surname.set_surname("DateTest") name = Name() name.add_surname(surname) name.set_first_name("Test %d" % i) person.set_primary_name(name) self.db.add_person(person, self.trans) bevent = Event() bevent.set_type(EventType.BIRTH) bevent.set_date_object(dateval) bevent.set_description("Date Test %d (source)" % i) bevent_h = self.db.add_event(bevent, self.trans) bevent_ref = EventRef() bevent_ref.set_reference_handle(bevent_h) # for the death event display the date as text and parse it back to a new date ndate = None try: datestr = _dd.display( dateval) try: ndate = _dp.parse( datestr) if not ndate: ndate = Date() ndate.set_as_text("DateParser None") person.add_tag(fail_handle) else: person.add_tag(pass_handle) except: ndate = Date() ndate.set_as_text("DateParser Exception %s" % ("".join(traceback.format_exception(*sys.exc_info())),)) person.add_tag(fail_handle) else: person.add_tag(pass_handle) except: ndate = Date() ndate.set_as_text("DateDisplay Exception: %s" % ("".join(traceback.format_exception(*sys.exc_info())),)) person.add_tag(fail_handle) if dateval.get_modifier() != Date.MOD_TEXTONLY \ and ndate.get_modifier() == Date.MOD_TEXTONLY: # parser was unable to correctly parse the string ndate.set_as_text( "TEXTONLY: "+ndate.get_text()) person.add_tag(fail_handle) if dateval.get_modifier() == Date.MOD_TEXTONLY \ and dateval.get_text().count("Traceback") \ and pass_handle in person.get_tag_list(): person.add_tag(fail_handle) devent = Event() devent.set_type(EventType.DEATH) devent.set_date_object(ndate) devent.set_description("Date Test %d (result)" % i) devent_h = self.db.add_event(devent, self.trans) devent_ref = EventRef() devent_ref.set_reference_handle(devent_h) person.set_birth_ref(bevent_ref) person.set_death_ref(devent_ref) self.db.commit_person(person, self.trans) i = i + 1 self.progress.step() self.db.enable_signals() self.db.request_rebuild() self.progress.close()
def exportData(database, filename, error_dialog=None, option_box=None, callback=None): if not callable(callback): callback = lambda percent: None # dummy with OpenFileOrStdout(filename) as fp: total = (len(database.note_map) + len(database.person_map) + len(database.event_map) + len(database.family_map) + len(database.repository_map) + len(database.place_map) + len(database.media_map) + len(database.source_map)) count = 0.0 # GProlog ISO directives: # /number must match the number of arguments to functions: fp.write(":- discontiguous(data/2).\n") fp.write(":- discontiguous(is_alive/2).\n") fp.write(":- discontiguous(parent/2).\n") # Rules: fp.write("grandparent(X, Y) :- parent(X, Z), parent(Z, Y).\n") fp.write("ancestor(X, Y) :- parent(X, Y).\n") fp.write("ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).\n") fp.write("sibling(X, Y) :- parent(Z, X), parent(Z, Y), X \= Y.\n") # --------------------------------- # Notes # --------------------------------- for note_handle in database.note_map.keys(): note = database.note_map[note_handle] #write_line(fp, "note_details(%s, %s)" % (note_handle, note)) count += 1 callback(100 * count/total) # --------------------------------- # Event # --------------------------------- for event_handle in database.event_map.keys(): event = database.event_map[event_handle] #write_line(fp, "event:", event_handle, event) count += 1 callback(100 * count/total) # --------------------------------- # Person # --------------------------------- for person_handle in database.person_map.keys(): data = database.person_map[person_handle] person = Person.create(data) gid = person.gramps_id.lower() fp.write("data(%s, '%s').\n" % (gid, escape(name_displayer.display(person)))) fp.write("is_alive(%s, '%s').\n" % (gid, probably_alive(person, database))) count += 1 callback(100 * count/total) # --------------------------------- # Family # --------------------------------- for family_handle in database.family_map.keys(): data = database.family_map[family_handle] family = Family.create(data) father_handle = family.get_father_handle() mother_handle = family.get_mother_handle() parents = [] if mother_handle: mother = database.get_person_from_handle(mother_handle) if mother: parents.append(mother.gramps_id.lower()) if father_handle: father = database.get_person_from_handle(father_handle) if father: parents.append(father.gramps_id.lower()) children = [] for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = database.get_person_from_handle(child_handle) if child: children.append(child.gramps_id.lower()) for pid in parents: for cid in children: fp.write("parent(%s, %s).\n" % (pid, cid)) count += 1 callback(100 * count/total) # --------------------------------- # Repository # --------------------------------- for repository_handle in database.repository_map.keys(): repository = database.repository_map[repository_handle] #write_line(fp, "repository:", repository_handle, repository) count += 1 callback(100 * count/total) # --------------------------------- # Place # --------------------------------- for place_handle in database.place_map.keys(): place = database.place_map[place_handle] #write_line(fp, "place:", place_handle, place) count += 1 callback(100 * count/total) # --------------------------------- # Source # --------------------------------- for source_handle in database.source_map.keys(): source = database.source_map[source_handle] #write_line(fp, "source:", source_handle, source) count += 1 callback(100 * count/total) # --------------------------------- # Media # --------------------------------- for media_handle in database.media_map.keys(): media = database.media_map[media_handle] #write_line(fp, "media:", media_handle, media) count += 1 callback(100 * count/total) return True
def get_families_grampsids(db: DbReadBase, person: Person) -> List[GrampsId]: """Get the Gramps IDs of all the person's families.""" handles = person.get_family_handle_list() or [] return [db.get_family_from_handle(handle).gramps_id for handle in handles]
def dump_parent(self,title,person_handle): if not person_handle and not self.missingInfo: return elif not person_handle: person = Person() else: person = self.database.get_person_from_handle(person_handle) name = self._name_display.display(person) self.doc.start_table(title,'FGR-ParentTable') self.doc.start_row() self.doc.start_cell('FGR-ParentHead',3) self.doc.start_paragraph('FGR-ParentName') mark = ReportUtils.get_person_mark(self.database,person) # translators: needed for French, ignore otherwise self.doc.write_text(self._("%(str1)s: %(str2)s") % { 'str1' : title, 'str2' : name }, mark) if self.gramps_ids: gid = person.get_gramps_id() if gid: self.doc.write_text(" (%s)" % gid) self.doc.end_paragraph() self.doc.end_cell() self.doc.end_row() birth_ref = person.get_birth_ref() birth = None evtName = self._("Birth") if birth_ref: birth = self.database.get_event_from_handle(birth_ref.ref) if birth or self.missingInfo: self.dump_parent_event(evtName,birth) death_ref = person.get_death_ref() death = None evtName = self._("Death") if death_ref: death = self.database.get_event_from_handle(death_ref.ref) if death or self.missingInfo: self.dump_parent_event(evtName,death) self.dump_parent_parents(person) if self.incParEvents: for event_ref in person.get_primary_event_ref_list(): if event_ref != birth_ref and event_ref != death_ref: event = self.database.get_event_from_handle(event_ref.ref) event_type = self._get_type(event.get_type()) self.dump_parent_event(self._(event_type),event) if self.incParAddr: addrlist = person.get_address_list()[:] for addr in addrlist: location = ReportUtils.get_address_str(addr) date = self._get_date(addr.get_date_object()) self.doc.start_row() self.doc.start_cell("FGR-TextContents") self.doc.start_paragraph('FGR-Normal') self.doc.write_text(self._("Address")) self.doc.end_paragraph() self.doc.end_cell() self.doc.start_cell("FGR-TextContents") self.doc.start_paragraph('FGR-Normal') self.doc.write_text(date) self.doc.end_paragraph() self.doc.end_cell() self.doc.start_cell("FGR-TextContentsEnd") self.doc.start_paragraph('FGR-Normal') self.doc.write_text(location) self.doc.end_paragraph() self.doc.end_cell() self.doc.end_row() if self.incParNotes: for notehandle in person.get_note_list(): note = self.database.get_note_from_handle(notehandle) self.dump_parent_noteline(self._("Note"), note) if self.includeAttrs: for attr in person.get_attribute_list(): attr_type = self._get_type(attr.get_type()) self.dump_parent_line(self._(attr_type),attr.get_value()) if self.incParNames: for alt_name in person.get_alternate_names(): name_type = self._get_type(alt_name.get_type()) name = self._name_display.display_name(alt_name) self.dump_parent_line(self._(name_type), name) self.doc.end_table()
def exportData(database, filename, error_dialog=None, option_box=None, callback=None): if not callable(callback): callback = lambda percent: None # dummy with OpenFileOrStdout(filename, encoding="utf-8") as fp: total = (len(database.note_map) + len(database.person_map) + len(database.event_map) + len(database.family_map) + len(database.repository_map) + len(database.place_map) + len(database.media_map) + len(database.citation_map) + len(database.source_map) + len(database.tag_map)) count = 0.0 # --------------------------------- # Notes # --------------------------------- for handle in database.note_map.keys(): serial = database.note_map[handle] write_line(fp, Note.create(serial)) count += 1 callback(100 * count / total) # --------------------------------- # Event # --------------------------------- for handle in database.event_map.keys(): serial = database.event_map[handle] write_line(fp, Event.create(serial)) count += 1 callback(100 * count / total) # --------------------------------- # Person # --------------------------------- for handle in database.person_map.keys(): serial = database.person_map[handle] write_line(fp, Person.create(serial)) count += 1 callback(100 * count / total) # --------------------------------- # Family # --------------------------------- for handle in database.family_map.keys(): serial = database.family_map[handle] write_line(fp, Family.create(serial)) count += 1 callback(100 * count / total) # --------------------------------- # Repository # --------------------------------- for handle in database.repository_map.keys(): serial = database.repository_map[handle] write_line(fp, Repository.create(serial)) count += 1 callback(100 * count / total) # --------------------------------- # Place # --------------------------------- for handle in database.place_map.keys(): serial = database.place_map[handle] write_line(fp, Place.create(serial)) count += 1 callback(100 * count / total) # --------------------------------- # Source # --------------------------------- for handle in database.source_map.keys(): serial = database.source_map[handle] write_line(fp, Source.create(serial)) count += 1 callback(100 * count / total) # --------------------------------- # Citation # --------------------------------- for handle in database.citation_map.keys(): serial = database.citation_map[handle] write_line(fp, Citation.create(serial)) count += 1 callback(100 * count / total) # --------------------------------- # Media # --------------------------------- for handle in database.media_map.keys(): serial = database.media_map[handle] write_line(fp, MediaObject.create(serial)) count += 1 callback(100 * count / total) # --------------------------------- # Tag # --------------------------------- for handle in database.tag_map.keys(): serial = database.tag_map[handle] write_line(fp, Tag.create(serial)) count += 1 callback(100 * count / total) return True
def exportData(database, filename, error_dialog=None, option_box=None, callback=None): if not callable(callback): callback = lambda percent: None # dummy with OpenFileOrStdout(filename, encoding="utf-8") as fp: total = (len(database.note_map) + len(database.person_map) + len(database.event_map) + len(database.family_map) + len(database.repository_map) + len(database.place_map) + len(database.media_map) + len(database.citation_map) + len(database.source_map) + len(database.tag_map)) count = 0.0 # --------------------------------- # Notes # --------------------------------- for handle in database.note_map.keys(): serial = database.note_map[handle] write_line(fp, Note.create(serial)) count += 1 callback(100 * count/total) # --------------------------------- # Event # --------------------------------- for handle in database.event_map.keys(): serial = database.event_map[handle] write_line(fp, Event.create(serial)) count += 1 callback(100 * count/total) # --------------------------------- # Person # --------------------------------- for handle in database.person_map.keys(): serial = database.person_map[handle] write_line(fp, Person.create(serial)) count += 1 callback(100 * count/total) # --------------------------------- # Family # --------------------------------- for handle in database.family_map.keys(): serial = database.family_map[handle] write_line(fp, Family.create(serial)) count += 1 callback(100 * count/total) # --------------------------------- # Repository # --------------------------------- for handle in database.repository_map.keys(): serial = database.repository_map[handle] write_line(fp, Repository.create(serial)) count += 1 callback(100 * count/total) # --------------------------------- # Place # --------------------------------- for handle in database.place_map.keys(): serial = database.place_map[handle] write_line(fp, Place.create(serial)) count += 1 callback(100 * count/total) # --------------------------------- # Source # --------------------------------- for handle in database.source_map.keys(): serial = database.source_map[handle] write_line(fp, Source.create(serial)) count += 1 callback(100 * count/total) # --------------------------------- # Citation # --------------------------------- for handle in database.citation_map.keys(): serial = database.citation_map[handle] write_line(fp, Citation.create(serial)) count += 1 callback(100 * count/total) # --------------------------------- # Media # --------------------------------- for handle in database.media_map.keys(): serial = database.media_map[handle] write_line(fp, Media.create(serial)) count += 1 callback(100 * count/total) # --------------------------------- # Tag # --------------------------------- for handle in database.tag_map.keys(): serial = database.tag_map[handle] write_line(fp, Tag.create(serial)) count += 1 callback(100 * count/total) return True
def add_person_clicked(self, event): if self.selection_widget.get_current(): person = Person() EditPerson(self.dbstate, self.uistate, self.track, person, self.new_person_added)
def dump_parent(self, title, person_handle): if not person_handle and not self.missingInfo: return elif not person_handle: person = Person() else: person = self.database.get_person_from_handle(person_handle) name = self._name_display.display(person) self.doc.start_table(title, 'FGR-ParentTable') self.doc.start_row() self.doc.start_cell('FGR-ParentHead', 3) self.doc.start_paragraph('FGR-ParentName') self.doc.write_text(title + ': ') mark = ReportUtils.get_person_mark(self.database, person) self.doc.write_text(name, mark) self.doc.end_paragraph() self.doc.end_cell() self.doc.end_row() birth_ref = person.get_birth_ref() birth = None evtName = self._("Birth") if birth_ref: birth = self.database.get_event_from_handle(birth_ref.ref) if birth or self.missingInfo: self.dump_parent_event(evtName, birth) death_ref = person.get_death_ref() death = None evtName = self._("Death") if death_ref: death = self.database.get_event_from_handle(death_ref.ref) if death or self.missingInfo: self.dump_parent_event(evtName, death) self.dump_parent_parents(person) if self.incParEvents: for event_ref in person.get_primary_event_ref_list(): if event_ref != birth_ref and event_ref != death_ref: event = self.database.get_event_from_handle(event_ref.ref) event_type = self._get_type(event.get_type()) self.dump_parent_event(self._(event_type), event) if self.incParAddr: addrlist = person.get_address_list()[:] for addr in addrlist: location = ReportUtils.get_address_str(addr) date = self._get_date(addr.get_date_object()) self.doc.start_row() self.doc.start_cell("FGR-TextContents") self.doc.start_paragraph('FGR-Normal') self.doc.write_text(self._("Address")) self.doc.end_paragraph() self.doc.end_cell() self.doc.start_cell("FGR-TextContents") self.doc.start_paragraph('FGR-Normal') self.doc.write_text(date) self.doc.end_paragraph() self.doc.end_cell() self.doc.start_cell("FGR-TextContentsEnd") self.doc.start_paragraph('FGR-Normal') self.doc.write_text(location) self.doc.end_paragraph() self.doc.end_cell() self.doc.end_row() if self.incParNotes: for notehandle in person.get_note_list(): note = self.database.get_note_from_handle(notehandle) self.dump_parent_noteline(self._("Note"), note) if self.includeAttrs: for attr in person.get_attribute_list(): attr_type = self._get_type(attr.get_type()) self.dump_parent_line(self._(attr_type), attr.get_value()) if self.incParNames: for alt_name in person.get_alternate_names(): name_type = self._get_type(alt_name.get_type()) name = self._name_display.display_name(alt_name) self.dump_parent_line(self._(name_type), name) self.doc.end_table()
class VCardParser: """Class to read data in VCard format from a file.""" DATE_RE = re.compile(r'^(\d{4}-\d{1,2}-\d{1,2})|(?:(\d{4})-?(\d\d)-?(\d\d))') GROUP_RE = re.compile(r'^(?:[-0-9A-Za-z]+\.)?(.+)$') # see RFC 2425 sec5.8.2 ESCAPE_CHAR = '\\' TOBE_ESCAPED = ['\\', ',', ';'] # order is important LINE_CONTINUATION = [' ', '\t'] @staticmethod def name_value_split(data): """Property group.name:value split is on first unquoted colon.""" colon_idx = data.find(':') if colon_idx < 1: return () quote_count = data.count('"', 0, colon_idx) while quote_count % 2 == 1: colon_idx = data.find(':', colon_idx + 1) quote_count = data.count('"', 0, colon_idx) group_name, value = data[:colon_idx], data[colon_idx + 1:] name_parts = VCardParser.GROUP_RE.match(group_name) return (name_parts.group(1), value) @staticmethod def unesc(data): """Remove VCard escape sequences.""" if type(data) == type('string'): for char in reversed(VCardParser.TOBE_ESCAPED): data = data.replace(VCardParser.ESCAPE_CHAR + char, char) return data elif type(data) == type([]): return list(map(VCardParser.unesc, data)) else: raise TypeError("VCard unescaping is not implemented for " "data type %s." % str(type(data))) @staticmethod def count_escapes(strng): """Count the number of escape characters at the end of a string.""" count = 0 for char in reversed(strng): if char != VCardParser.ESCAPE_CHAR: return count count += 1 return count @staticmethod def split_unescaped(strng, sep): """Split on sep if sep is unescaped.""" strng_parts = strng.split(sep) for i in reversed(range(len(strng_parts[:]))): if VCardParser.count_escapes(strng_parts[i]) % 2 == 1: # the sep was escaped so undo split appendix = strng_parts.pop(i + 1) strng_parts[i] += sep + appendix return strng_parts def __init__(self, dbase): self.database = dbase self.formatted_name = '' self.name_parts = '' self.next_line = None self.trans = None self.version = None self.person = None self.errors = [] self.number_of_errors = 0 def __get_next_line(self, filehandle): """ Read and return the line with the next property of the VCard. Also if it spans multiple lines (RFC 2425 sec.5.8.1). """ line = self.next_line self.next_line = filehandle.readline() self.line_num = self.line_num + 1 while self.next_line and self.next_line[0] in self.LINE_CONTINUATION: line = line.rstrip("\n") # TODO perhaps next lines superflous because of rU open parameter? if len(line) > 0 and line[-1] == "\r": line = line[:-1] line += self.next_line[1:] self.next_line = filehandle.readline() self.line_num = self.line_num + 1 if line: line = line.strip() else: line = None return line def __add_msg(self, problem, line=None): if problem != "": self.number_of_errors += 1 if line: message = _("Line %(line)5d: %(prob)s\n") % {"line": line, "prob": problem} else: message = problem + "\n" self.errors.append(message) def parse(self, filehandle, user): """ Prepare the database and parse the input file. :param filehandle: open file handle positioned at start of the file """ tym = time.time() self.person = None self.database.disable_signals() with DbTxn(_("vCard import"), self.database, batch=True) as self.trans: self._parse_vCard_file(filehandle) self.database.enable_signals() self.database.request_rebuild() tym = time.time() - tym # translators: leave all/any {...} untranslated msg = ngettext('Import Complete: {number_of} second', 'Import Complete: {number_of} seconds', tym ).format(number_of=tym) LOG.debug(msg) if self.number_of_errors == 0: message = _("VCARD import report: No errors detected") else: message = _("VCARD import report: %s errors detected\n") % \ self.number_of_errors if hasattr(user.uistate, 'window'): parent_window = user.uistate.window else: parent_window = None user.info(message, "".join(self.errors), parent=parent_window, monospaced=True) def _parse_vCard_file(self, filehandle): """Read each line of the input file and act accordingly.""" self.next_line = filehandle.readline() self.line_num = 1 while True: line = self.__get_next_line(filehandle) if line is None: break if line == "": continue if line.find(":") == -1: continue line_parts = self.name_value_split(line) if not line_parts: continue # No check for escaped ; because only fields[0] is used. fields = line_parts[0].split(";") property_name = fields[0].upper() if property_name == "BEGIN": self.next_person() elif property_name == "END": self.finish_person() elif property_name == "VERSION": self.check_version(fields, line_parts[1]) elif property_name == "FN": self.add_formatted_name(fields, line_parts[1]) elif property_name == "N": self.add_name_parts(fields, line_parts[1]) elif property_name == "NICKNAME": self.add_nicknames(fields, line_parts[1]) elif property_name == "SORT-STRING": self.add_sortas(fields, line_parts[1]) elif property_name == "ADR": self.add_address(fields, line_parts[1]) elif property_name == "TEL": self.add_phone(fields, line_parts[1]) elif property_name == "BDAY": self.add_birthday(fields, line_parts[1]) elif property_name == "ROLE": self.add_occupation(fields, line_parts[1]) elif property_name == "URL": self.add_url(fields, line_parts[1]) elif property_name == "EMAIL": self.add_email(fields, line_parts[1]) elif property_name == "X-GENDER" or property_name == "GENDER": # VCard 3.0 only has X-GENDER, GENDER is 4.0 syntax, # but we want to be robust here. self.add_gender(fields, line_parts[1]) elif property_name == "PRODID": # Included cause VCards made by Gramps have this prop. pass else: self.__add_msg(_("Token >%(token)s< unknown. line skipped: %(line)s") % {"token": (fields[0], line), "line": self.line_num - 1}) def finish_person(self): """All info has been collected, write to database.""" if self.person is not None: if self.add_name(): self.database.add_person(self.person, self.trans) self.person = None def next_person(self): """A VCard for another person is started.""" if self.person is not None: self.finish_person() self.__add_msg(_("BEGIN property not properly closed by END " "property, Gramps can't cope with nested VCards."), self.line_num - 1) self.person = Person() self.formatted_name = '' self.name_parts = '' def check_version(self, fields, data): """Check the version of the VCard, only version 3.0 is supported.""" self.version = data if self.version != "3.0": raise GrampsImportError(_("Import of VCards version %s is " "not supported by Gramps.") % self.version) def add_formatted_name(self, fields, data): """Read the FN property of a VCard.""" if not self.formatted_name: self.formatted_name = self.unesc(str(data)).strip() def add_name_parts(self, fields, data): """Read the N property of a VCard.""" if not self.name_parts: self.name_parts = data.strip() def add_name(self): """ Add the name to the person. Returns True on success, False on failure. """ if not self.name_parts.strip(): self.__add_msg(_("VCard is malformed missing the compulsory N " "property, so there is no name; skip it."), self.line_num - 1) return False if not self.formatted_name: self.__add_msg(_("VCard is malformed missing the compulsory FN " "property, get name from N alone."), self.line_num - 1) data_fields = self.split_unescaped(self.name_parts, ';') if len(data_fields) != 5: self.__add_msg(_("VCard is malformed wrong number of name " "components."), self.line_num - 1) name = Name() name.set_type(NameType(NameType.BIRTH)) if data_fields[0].strip(): # assume first surname is primary for surname_str in self.split_unescaped(data_fields[0], ','): surname = Surname() prefix, sname = splitof_nameprefix(self.unesc(surname_str)) surname.set_surname(sname.strip()) surname.set_prefix(prefix.strip()) name.add_surname(surname) name.set_primary_surname() if len(data_fields) > 1 and data_fields[1].strip(): given_name = ' '.join(self.unesc( self.split_unescaped(data_fields[1], ','))) else: given_name = '' if len(data_fields) > 2 and data_fields[2].strip(): additional_names = ' '.join(self.unesc( self.split_unescaped(data_fields[2], ','))) else: additional_names = '' self.add_firstname(given_name.strip(), additional_names.strip(), name) if len(data_fields) > 3 and data_fields[3].strip(): name.set_title(' '.join(self.unesc( self.split_unescaped(data_fields[3], ',')))) if len(data_fields) > 4 and data_fields[4].strip(): name.set_suffix(' '.join(self.unesc( self.split_unescaped(data_fields[4], ',')))) self.person.set_primary_name(name) return True def add_firstname(self, given_name, additional_names, name): """ Combine given_name and additional_names and add as firstname to name. If possible try to add given_name as call name. """ default = "%s %s" % (given_name, additional_names) if self.formatted_name: if given_name: if additional_names: given_name_pos = self.formatted_name.find(given_name) if given_name_pos != -1: add_names_pos = self.formatted_name.find(additional_names) if add_names_pos != -1: if given_name_pos <= add_names_pos: firstname = default # Uncertain if given name is used as callname else: firstname = "%s %s" % (additional_names, given_name) name.set_call_name(given_name) else: idx = fitin(self.formatted_name, additional_names, given_name) if idx == -1: # Additional names is not in formatted name firstname = default else: # Given name in middle of additional names firstname = "%s%s %s" % (additional_names[:idx], given_name, additional_names[idx:]) name.set_call_name(given_name) else: # Given name is not in formatted name firstname = default else: # There are no additional_names firstname = given_name else: # There is no given_name firstname = additional_names else: # There is no formatted name firstname = default name.set_first_name(firstname.strip()) return def add_nicknames(self, fields, data): """Read the NICKNAME property of a VCard.""" for nick in self.split_unescaped(data, ','): nickname = nick.strip() if nickname: name = Name() name.set_nick_name(self.unesc(nickname)) self.person.add_alternate_name(name) def add_sortas(self, fields, data): """Read the SORT-STRING property of a VCard.""" # TODO pass def add_address(self, fields, data): """Read the ADR property of a VCard.""" data_fields = self.split_unescaped(data, ';') data_fields = [x.strip() for x in self.unesc(data_fields)] if ''.join(data_fields): addr = Address() def add_street(strng): if strng: already = addr.get_street() if already: addr.set_street("%s %s" % (already, strng)) else: addr.set_street(strng) addr.add_street = add_street set_func = ['add_street', 'add_street', 'add_street', 'set_city', 'set_state', 'set_postal_code', 'set_country'] for i, data in enumerate(data_fields): if i >= len(set_func): break getattr(addr, set_func[i])(data) self.person.add_address(addr) def add_phone(self, fields, data): """Read the TEL property of a VCard.""" tel = data.strip() if tel: addr = Address() addr.set_phone(self.unesc(tel)) self.person.add_address(addr) def add_birthday(self, fields, data): """Read the BDAY property of a VCard.""" date_str = data.strip() date_match = VCardParser.DATE_RE.match(date_str) date = Date() if date_match: if date_match.group(2): date_str = "%s-%s-%s" % (date_match.group(2), date_match.group(3), date_match.group(4)) else: date_str = date_match.group(1) y, m, d = [int(x, 10) for x in date_str.split('-')] try: date.set(value=(d, m, y, False)) except DateError: # TRANSLATORS: leave the {vcard_snippet} untranslated # in the format string, but you may re-order it if needed. self.__add_msg(_( "Invalid date in BDAY {vcard_snippet}, " "preserving date as text." ).format(vcard_snippet=data), self.line_num - 1) date.set(modifier=Date.MOD_TEXTONLY, text=data) else: if date_str: # TRANSLATORS: leave the {vcard_snippet} untranslated. self.__add_msg(_( "Date {vcard_snippet} not in appropriate format " "yyyy-mm-dd, preserving date as text." ).format(vcard_snippet=date_str), self.line_num - 1) date.set(modifier=Date.MOD_TEXTONLY, text=date_str) else: # silently ignore an empty BDAY record return event = Event() event.set_type(EventType(EventType.BIRTH)) event.set_date_object(date) self.database.add_event(event, self.trans) event_ref = EventRef() event_ref.set_reference_handle(event.get_handle()) self.person.set_birth_ref(event_ref) def add_occupation(self, fields, data): """Read the ROLE property of a VCard.""" occupation = data.strip() if occupation: event = Event() event.set_type(EventType(EventType.OCCUPATION)) event.set_description(self.unesc(occupation)) self.database.add_event(event, self.trans) event_ref = EventRef() event_ref.set_reference_handle(event.get_handle()) self.person.add_event_ref(event_ref) def add_url(self, fields, data): """Read the URL property of a VCard.""" href = data.strip() if href: url = Url() url.set_path(self.unesc(href)) self.person.add_url(url) def add_email(self, fields, data): """Read the EMAIL property of a VCard.""" email = data.strip() if email: url = Url() url.set_type(UrlType(UrlType.EMAIL)) url.set_path(self.unesc(email)) self.person.add_url(url) def add_gender(self, fields, data): """Read the GENDER property of a VCard.""" gender_value = data.strip() if gender_value: gender_value = gender_value.upper() gender_value = gender_value[0] if gender_value == 'M': gender = Person.MALE elif gender_value == 'F': gender = Person.FEMALE else: return self.person.set_gender(gender)
def __add_clicked(self, obj): person = Person() EditPerson(self.dbstate, self.uistate, self.track, person, self.__added)