def login(self): global _ username = self.sign_in.username.get() password = self.sign_in.password.get() if not (username and password): messagebox.showinfo(message=_('Please enter your FamilySearch username and password.')) return self.btn_valid.config(state='disabled') self.info(_('Login to FamilySearch...')) self.logfile = open('download.log', 'w', encoding='utf-8') self.fs = Session(self.sign_in.username.get(), self.sign_in.password.get(), verbose=True, logfile=self.logfile, timeout=1) if not self.fs.logged: messagebox.showinfo(_('Error'), message=_('The username or password was incorrect')) self.btn_valid.config(state='normal') self.info('') return self.tree = Tree(self.fs) _ = self.fs._ self.title.config(text=_('Options')) cache.delete('lang') cache.add('lang', self.fs.lang) self.options = Options(self.form, True) self.info('') self.sign_in.destroy() self.options.pack() self.master.change_lang() self.btn_valid.config(command=self.command_in_thread(self.download), state='normal', text=_('Download')) self.options.start_indis.add_indi(self.fs.get_userid()) self.update_needed = False
def login(self): """ log in FamilySearch """ global _ username = self.sign_in.username.get() password = self.sign_in.password.get() if not (username and password): messagebox.showinfo(message=_( "Please enter your FamilySearch username and password.")) return self.btn_valid.config(state="disabled") self.info(_("Login to FamilySearch...")) self.logfile = open("download.log", "w", encoding="utf-8") self.fs = Session( self.sign_in.username.get(), self.sign_in.password.get(), verbose=True, logfile=self.logfile, timeout=1, ) if not self.fs.logged: messagebox.showinfo( _("Error"), message=_("The username or password was incorrect")) self.btn_valid.config(state="normal") self.info("") return self.tree = Tree(self.fs) _ = self.fs._ self.title.config(text=_("Options")) cache.delete("lang") cache.add("lang", self.fs.lang) cache.delete("username") cache.add("username", username) url = "/service/tree/tree-data/reservations/person/%s/ordinances" % self.fs.fid lds_account = self.fs.get_url(url, {}).get("status") == "OK" self.options = Options(self.form, lds_account) self.info("") self.sign_in.destroy() self.options.pack() self.master.change_lang() self.btn_valid.config(command=self.command_in_thread(self.download), state="normal", text=_("Download")) self.options.start_indis.add_indi(self.fs.fid) self.update_needed = False
def login(self): global _ username = self.sign_in.username.get() password = self.sign_in.password.get() if not (username and password): messagebox.showinfo(message=_( 'Please enter your FamilySearch username and password.')) return self.btn_valid.config(state='disabled') self.info(_('Login to FamilySearch...')) self.logfile = open('download.log', 'w', encoding='utf-8') self.fs = Session(self.sign_in.username.get(), self.sign_in.password.get(), verbose=True, logfile=self.logfile, timeout=1) if not self.fs.logged: messagebox.showinfo( _('Error'), message=_('The username or password was incorrect')) self.btn_valid.config(state='normal') self.info('') return self.tree = Tree(self.fs) _ = self.fs._ self.title.config(text=_('Options')) cache.delete('lang') cache.add('lang', self.fs.lang) lds_account = self.fs.get_url( '/platform/tree/persons/%s/ordinances.json' % self.fs.get_userid()) != 'error' self.options = Options(self.form, lds_account) self.info('') self.sign_in.destroy() self.options.pack() self.master.change_lang() self.btn_valid.config(command=self.command_in_thread(self.download), state='normal', text=_('Download')) self.options.start_indis.add_indi(self.fs.get_userid()) self.update_needed = False
parser.add_argument('-i', metavar = '<FILE>', nargs = '+', type = argparse.FileType('r', encoding='UTF-8'), default = sys.stdin, help = 'input GEDCOM files [stdin]') parser.add_argument('-o', metavar = '<FILE>', nargs = '?', type = argparse.FileType('w', encoding='UTF-8'), default = sys.stdout, help = 'output GEDCOM files [stdout]') except TypeError: sys.stderr.write('Python >= 3.4 is required to run this script\n') sys.stderr.write('(see https://docs.python.org/3/whatsnew/3.4.html#argparse)\n') exit(2) # extract arguments from the command line try: parser.error = parser.exit args = parser.parse_args() except SystemExit: parser.print_help() exit(2) tree = Tree() indi_counter = 0 fam_counter = 0 # read the GEDCOM data for file in args.i: ged = Gedcom(file) # add informations about individuals for num in ged.indi: fid = ged.indi[num].fid if fid not in tree.indi: indi_counter += 1 tree.indi[fid] = Indi(num = indi_counter) tree.indi[fid].fid = ged.indi[num].fid
help="output GEDCOM files [stdout]", ) except TypeError: sys.stderr.write("Python >= 3.4 is required to run this script\n") sys.stderr.write("(see https://docs.python.org/3/whatsnew/3.4.html#argparse)\n") exit(2) # extract arguments from the command line try: parser.error = parser.exit args = parser.parse_args() except SystemExit: parser.print_help() exit(2) tree = Tree() indi_counter = 0 fam_counter = 0 # read the GEDCOM data for file in args.i: ged = Gedcom(file) # add informations about individuals for num in ged.indi: fid = ged.indi[num].fid if fid not in tree.indi: indi_counter += 1 tree.indi[fid] = Indi(num=indi_counter) tree.indi[fid].fid = ged.indi[num].fid
class Download(Frame): def __init__(self, master, **kwargs): super(Download, self).__init__(master, borderwidth=20, **kwargs) self.fs = None self.tree = None self.logfile = None # User informations self.info_tree = False self.start_time = None info = Frame(self, borderwidth=10) self.info_label = Label(info, wraplength=350, borderwidth=20, justify='center', font=('a', 10, 'bold')) self.info_indis = Label(info) self.info_fams = Label(info) self.info_sources = Label(info) self.info_notes = Label(info) self.time = Label(info) self.info_label.grid(row=0, column=0, columnspan=2) self.info_indis.grid(row=1, column=0) self.info_fams.grid(row=1, column=1) self.info_sources.grid(row=2, column=0) self.info_notes.grid(row=2, column=1) self.time.grid(row=3, column=0, columnspan=2) self.form = Frame(self) self.sign_in = SignIn(self.form) self.options = None self.title = Label(self, text=_('Sign In to FamilySearch'), font=('a', 12, 'bold')) buttons = Frame(self) self.btn_quit = Button(buttons, text=_('Quit'), command=Thread(target=self.quit).start) self.btn_valid = Button(buttons, text=_('Sign In'), command=self.command_in_thread(self.login)) self.title.pack() self.sign_in.pack() self.form.pack() self.btn_quit.pack(side='left', padx=(0, 40)) self.btn_valid.pack(side='right', padx=(40, 0)) info.pack() buttons.pack(side='bottom') self.pack() self.update_needed = False def info(self, text): self.info_label.config(text=text) def save(self): filename = filedialog.asksaveasfilename(title=_('Save as'), defaultextension='.ged', filetypes=(('GEDCOM', '.ged'), (_('All files'), '*.*'))) if not filename: return with open(filename, 'w', encoding='utf-8') as file: self.tree.print(file) def login(self): global _ username = self.sign_in.username.get() password = self.sign_in.password.get() if not (username and password): messagebox.showinfo(message=_('Please enter your FamilySearch username and password.')) return self.btn_valid.config(state='disabled') self.info(_('Login to FamilySearch...')) self.logfile = open('download.log', 'w', encoding='utf-8') self.fs = Session(self.sign_in.username.get(), self.sign_in.password.get(), verbose=True, logfile=self.logfile, timeout=1) if not self.fs.logged: messagebox.showinfo(_('Error'), message=_('The username or password was incorrect')) self.btn_valid.config(state='normal') self.info('') return self.tree = Tree(self.fs) _ = self.fs._ self.title.config(text=_('Options')) cache.delete('lang') cache.add('lang', self.fs.lang) self.options = Options(self.form, True) self.info('') self.sign_in.destroy() self.options.pack() self.master.change_lang() self.btn_valid.config(command=self.command_in_thread(self.download), state='normal', text=_('Download')) self.options.start_indis.add_indi(self.fs.get_userid()) self.update_needed = False def quit(self): self.update_needed = False if self.logfile: self.logfile.close() super(Download, self).quit() # prevent exception during download os._exit(1) def download(self): todo = [self.options.start_indis.indis[key] for key in sorted(self.options.start_indis.indis)] for fid in todo: if not re.match(r'[A-Z0-9]{4}-[A-Z0-9]{3}', fid): messagebox.showinfo(_('Error'), message=_('Invalid FamilySearch ID: ') + fid) return self.start_time = time.time() self.options.destroy() self.form.destroy() self.title.config(text='FamilySearch to GEDCOM') self.btn_valid.config(state='disabled') self.info(_('Download starting individuals...')) self.info_tree = True self.tree.add_indis(todo) todo = set(todo) done = set() for i in range(self.options.ancestors.get()): if not todo: break done |= todo self.info(_('Download ') + str(i + 1) + _('th generation of ancestors...')) todo = self.tree.add_parents(todo) - done todo = set(self.tree.indi.keys()) done = set() for i in range(self.options.descendants.get()): if not todo: break done |= todo self.info(_('Download ') + str(i + 1) + _('th generation of descendants...')) todo = self.tree.add_children(todo) - done if self.options.spouses.get(): self.info(_('Download spouses and marriage information...')) todo = set(self.tree.indi.keys()) self.tree.add_spouses(todo) ordi = self.options.ordinances.get() cont = self.options.contributors.get() async def download_stuff(loop): futures = set() for fid, indi in self.tree.indi.items(): futures.add(loop.run_in_executor(None, indi.get_notes)) if ordi: futures.add(loop.run_in_executor(None, self.tree.add_ordinances, fid)) if cont: futures.add(loop.run_in_executor(None, indi.get_contributors)) for fam in self.tree.fam.values(): futures.add(loop.run_in_executor(None, fam.get_notes)) if cont: futures.add(loop.run_in_executor(None, fam.get_contributors)) for future in futures: await future loop = asyncio.get_event_loop() self.info(_('Download notes') + (((',' if cont else _(' and')) + _(' ordinances')) if ordi else '') + (_(' and contributors') if cont else '') + '...') loop.run_until_complete(download_stuff(loop)) self.tree.reset_num() self.btn_valid.config(command=self.save, state='normal', text=_('Save')) self.info(text=_('Success ! Click below to save your GEDCOM file')) self.update_info_tree() self.update_needed = False def command_in_thread(self, func): def res(): self.update_needed = True Thread(target=self.update_gui).start() Thread(target=func).start() return res def update_info_tree(self): if self.info_tree and self.start_time and self.tree: self.info_indis.config(text=_('Individuals: %s') % len(self.tree.indi)) self.info_fams.config(text=_('Families: %s') % len(self.tree.fam)) self.info_sources.config(text=_('Sources: %s') % len(self.tree.sources)) self.info_notes.config(text=_('Notes: %s') % len(self.tree.notes)) t = round(time.time() - self.start_time) minutes = t // 60 seconds = t % 60 self.time.config(text=_('Elapsed time: %s:%s') % (minutes, '00%s'[len(str(seconds)):] % seconds)) def update_gui(self): while self.update_needed: self.update_info_tree() self.master.update() time.sleep(0.1)
def save(self): if not self.files_to_merge.files: messagebox.showinfo(_('Error'), message=_('Please add GEDCOM files')) return filename = filedialog.asksaveasfilename(title=_('Save as'), defaultextension='.ged', filetypes=(('GEDCOM', '.ged'), (_('All files'), '*.*'))) tree = Tree() indi_counter = 0 fam_counter = 0 # read the GEDCOM data for file in self.files_to_merge.files.values(): ged = Gedcom(file, tree) # add informations about individuals for num in ged.indi: fid = ged.indi[num].fid if fid not in tree.indi: indi_counter += 1 tree.indi[fid] = Indi(tree=tree, num=indi_counter) tree.indi[fid].tree = tree tree.indi[fid].fid = ged.indi[num].fid tree.indi[fid].fams_fid |= ged.indi[num].fams_fid tree.indi[fid].famc_fid |= ged.indi[num].famc_fid tree.indi[fid].name = ged.indi[num].name tree.indi[fid].birthnames = ged.indi[num].birthnames tree.indi[fid].nicknames = ged.indi[num].nicknames tree.indi[fid].aka = ged.indi[num].aka tree.indi[fid].married = ged.indi[num].married tree.indi[fid].gender = ged.indi[num].gender tree.indi[fid].facts = ged.indi[num].facts tree.indi[fid].notes = ged.indi[num].notes tree.indi[fid].sources = ged.indi[num].sources tree.indi[fid].memories = ged.indi[num].memories tree.indi[fid].baptism = ged.indi[num].baptism tree.indi[fid].confirmation = ged.indi[num].confirmation tree.indi[fid].endowment = ged.indi[num].endowment if not (tree.indi[fid].sealing_child and tree.indi[fid].sealing_child.famc): tree.indi[fid].sealing_child = ged.indi[num].sealing_child # add informations about families for num in ged.fam: husb, wife = (ged.fam[num].husb_fid, ged.fam[num].wife_fid) if (husb, wife) not in tree.fam: fam_counter += 1 tree.fam[(husb, wife)] = Fam(husb, wife, tree, fam_counter) tree.fam[(husb, wife)].tree = tree tree.fam[(husb, wife)].chil_fid |= ged.fam[num].chil_fid tree.fam[(husb, wife)].fid = ged.fam[num].fid tree.fam[(husb, wife)].facts = ged.fam[num].facts tree.fam[(husb, wife)].notes = ged.fam[num].notes tree.fam[(husb, wife)].sources = ged.fam[num].sources tree.fam[(husb, wife)].sealing_spouse = ged.fam[num].sealing_spouse # merge notes by text tree.notes = sorted(tree.notes, key=lambda x: x.text) for i, n in enumerate(tree.notes): if i == 0: n.num = 1 continue if n.text == tree.notes[i - 1].text: n.num = tree.notes[i - 1].num else: n.num = tree.notes[i - 1].num + 1 # compute number for family relationships and print GEDCOM file tree.reset_num() with open(filename, 'w', encoding='utf-8') as file: tree.print(file) messagebox.showinfo(_('Info'), message=_('Files successfully merged'))
class Download(Frame): def __init__(self, master, **kwargs): super(Download, self).__init__(master, borderwidth=20, **kwargs) self.fs = None self.tree = None self.logfile = None # User informations self.info_tree = False self.start_time = None info = Frame(self, borderwidth=10) self.info_label = Label(info, wraplength=350, borderwidth=20, justify='center', font=('a', 10, 'bold')) self.info_indis = Label(info) self.info_fams = Label(info) self.info_sources = Label(info) self.info_notes = Label(info) self.time = Label(info) self.info_label.grid(row=0, column=0, columnspan=2) self.info_indis.grid(row=1, column=0) self.info_fams.grid(row=1, column=1) self.info_sources.grid(row=2, column=0) self.info_notes.grid(row=2, column=1) self.time.grid(row=3, column=0, columnspan=2) self.form = Frame(self) self.sign_in = SignIn(self.form) self.options = None self.title = Label(self, text=_('Sign In to FamilySearch'), font=('a', 12, 'bold')) buttons = Frame(self) self.btn_quit = Button(buttons, text=_('Quit'), command=Thread(target=self.quit).start) self.btn_valid = Button(buttons, text=_('Sign In'), command=self.command_in_thread(self.login)) self.title.pack() self.sign_in.pack() self.form.pack() self.btn_quit.pack(side='left', padx=(0, 40)) self.btn_valid.pack(side='right', padx=(40, 0)) info.pack() buttons.pack(side='bottom') self.pack() self.update_needed = False def info(self, text): self.info_label.config(text=text) def save(self): filename = filedialog.asksaveasfilename(title=_('Save as'), defaultextension='.ged', filetypes=(('GEDCOM', '.ged'), (_('All files'), '*.*'))) if not filename: return with open(filename, 'w', encoding='utf-8') as file: self.tree.print(file) def login(self): global _ username = self.sign_in.username.get() password = self.sign_in.password.get() if not (username and password): messagebox.showinfo(message=_( 'Please enter your FamilySearch username and password.')) return self.btn_valid.config(state='disabled') self.info(_('Login to FamilySearch...')) self.logfile = open('download.log', 'w', encoding='utf-8') self.fs = Session(self.sign_in.username.get(), self.sign_in.password.get(), verbose=True, logfile=self.logfile, timeout=1) if not self.fs.logged: messagebox.showinfo( _('Error'), message=_('The username or password was incorrect')) self.btn_valid.config(state='normal') self.info('') return self.tree = Tree(self.fs) _ = self.fs._ self.title.config(text=_('Options')) cache.delete('lang') cache.add('lang', self.fs.lang) lds_account = self.fs.get_url( '/platform/tree/persons/%s/ordinances.json' % self.fs.get_userid()) != 'error' self.options = Options(self.form, lds_account) self.info('') self.sign_in.destroy() self.options.pack() self.master.change_lang() self.btn_valid.config(command=self.command_in_thread(self.download), state='normal', text=_('Download')) self.options.start_indis.add_indi(self.fs.get_userid()) self.update_needed = False def quit(self): self.update_needed = False if self.logfile: self.logfile.close() super(Download, self).quit() # prevent exception during download os._exit(1) def download(self): todo = [ self.options.start_indis.indis[key] for key in sorted(self.options.start_indis.indis) ] for fid in todo: if not re.match(r'[A-Z0-9]{4}-[A-Z0-9]{3}', fid): messagebox.showinfo(_('Error'), message=_('Invalid FamilySearch ID: ') + fid) return self.start_time = time.time() self.options.destroy() self.form.destroy() self.title.config(text='FamilySearch to GEDCOM') self.btn_valid.config(state='disabled') self.info(_('Download starting individuals...')) self.info_tree = True self.tree.add_indis(todo) todo = set(todo) done = set() for i in range(self.options.ancestors.get()): if not todo: break done |= todo self.info( _('Download ') + str(i + 1) + _('th generation of ancestors...')) todo = self.tree.add_parents(todo) - done todo = set(self.tree.indi.keys()) done = set() for i in range(self.options.descendants.get()): if not todo: break done |= todo self.info( _('Download ') + str(i + 1) + _('th generation of descendants...')) todo = self.tree.add_children(todo) - done if self.options.spouses.get(): self.info(_('Download spouses and marriage information...')) todo = set(self.tree.indi.keys()) self.tree.add_spouses(todo) ordi = self.options.ordinances.get() cont = self.options.contributors.get() async def download_stuff(loop): futures = set() for fid, indi in self.tree.indi.items(): futures.add(loop.run_in_executor(None, indi.get_notes)) if ordi: futures.add( loop.run_in_executor(None, self.tree.add_ordinances, fid)) if cont: futures.add( loop.run_in_executor(None, indi.get_contributors)) for fam in self.tree.fam.values(): futures.add(loop.run_in_executor(None, fam.get_notes)) if cont: futures.add( loop.run_in_executor(None, fam.get_contributors)) for future in futures: await future loop = asyncio.get_event_loop() self.info( _('Download notes') + (((',' if cont else _(' and')) + _(' ordinances')) if ordi else '') + (_(' and contributors') if cont else '') + '...') loop.run_until_complete(download_stuff(loop)) self.tree.reset_num() self.btn_valid.config(command=self.save, state='normal', text=_('Save')) self.info(text=_('Success ! Click below to save your GEDCOM file')) self.update_info_tree() self.update_needed = False def command_in_thread(self, func): def res(): self.update_needed = True Thread(target=self.update_gui).start() Thread(target=func).start() return res def update_info_tree(self): if self.info_tree and self.start_time and self.tree: self.info_indis.config(text=_('Individuals: %s') % len(self.tree.indi)) self.info_fams.config(text=_('Families: %s') % len(self.tree.fam)) self.info_sources.config(text=_('Sources: %s') % len(self.tree.sources)) self.info_notes.config(text=_('Notes: %s') % len(self.tree.notes)) t = round(time.time() - self.start_time) minutes = t // 60 seconds = t % 60 self.time.config(text=_('Elapsed time: %s:%s') % (minutes, '00%s'[len(str(seconds)):] % seconds)) def update_gui(self): while self.update_needed: self.update_info_tree() self.master.update() time.sleep(0.1)
class Download(Frame): """ Main widget """ def __init__(self, master, **kwargs): super(Download, self).__init__(master, borderwidth=20, **kwargs) self.fs = None self.tree = None self.logfile = None # User informations self.info_tree = False self.start_time = None info = Frame(self, borderwidth=10) self.info_label = Label(info, wraplength=350, borderwidth=20, justify="center", font=("a", 10, "bold")) self.info_indis = Label(info) self.info_fams = Label(info) self.info_sources = Label(info) self.info_notes = Label(info) self.time = Label(info) self.info_label.grid(row=0, column=0, columnspan=2) self.info_indis.grid(row=1, column=0) self.info_fams.grid(row=1, column=1) self.info_sources.grid(row=2, column=0) self.info_notes.grid(row=2, column=1) self.time.grid(row=3, column=0, columnspan=2) self.form = Frame(self) self.sign_in = SignIn(self.form) self.options = None self.title = Label(self, text=_("Sign In to FamilySearch"), font=("a", 12, "bold")) buttons = Frame(self) self.btn_quit = Button(buttons, text=_("Quit"), command=Thread(target=self.quit).start) self.btn_valid = Button(buttons, text=_("Sign In"), command=self.command_in_thread(self.login)) self.title.pack() self.sign_in.pack() self.form.pack() self.btn_quit.pack(side="left", padx=(0, 40)) self.btn_valid.pack(side="right", padx=(40, 0)) info.pack() buttons.pack(side="bottom") self.pack() self.update_needed = False def info(self, text): """ dislay informations """ self.info_label.config(text=text) def save(self): """ save the GEDCOM file """ filename = filedialog.asksaveasfilename( title=_("Save as"), defaultextension=".ged", filetypes=(("GEDCOM", ".ged"), (_("All files"), "*.*")), ) if not filename: return with open(filename, "w", encoding="utf-8") as file: self.tree.print(file) def login(self): """ log in FamilySearch """ global _ username = self.sign_in.username.get() password = self.sign_in.password.get() if not (username and password): messagebox.showinfo(message=_( "Please enter your FamilySearch username and password.")) return self.btn_valid.config(state="disabled") self.info(_("Login to FamilySearch...")) self.logfile = open("download.log", "w", encoding="utf-8") self.fs = Session( self.sign_in.username.get(), self.sign_in.password.get(), verbose=True, logfile=self.logfile, timeout=1, ) if not self.fs.logged: messagebox.showinfo( _("Error"), message=_("The username or password was incorrect")) self.btn_valid.config(state="normal") self.info("") return self.tree = Tree(self.fs) _ = self.fs._ self.title.config(text=_("Options")) cache.delete("lang") cache.add("lang", self.fs.lang) cache.delete("username") cache.add("username", username) url = "/service/tree/tree-data/reservations/person/%s/ordinances" % self.fs.fid lds_account = self.fs.get_url(url, {}).get("status") == "OK" self.options = Options(self.form, lds_account) self.info("") self.sign_in.destroy() self.options.pack() self.master.change_lang() self.btn_valid.config(command=self.command_in_thread(self.download), state="normal", text=_("Download")) self.options.start_indis.add_indi(self.fs.fid) self.update_needed = False def quit(self): """ prevent exception during download """ self.update_needed = False if self.logfile: self.logfile.close() super(Download, self).quit() os._exit(1) def download(self): """ download family tree """ todo = [ self.options.start_indis.indis[key] for key in sorted(self.options.start_indis.indis) ] for fid in todo: if not re.match(r"[A-Z0-9]{4}-[A-Z0-9]{3}", fid): messagebox.showinfo(_("Error"), message=_("Invalid FamilySearch ID: ") + fid) return self.start_time = time.time() self.options.destroy() self.form.destroy() self.title.config(text="FamilySearch to GEDCOM") self.btn_valid.config(state="disabled") self.info(_("Downloading starting individuals...")) self.info_tree = True self.tree.add_indis(todo) todo = set(todo) done = set() for i in range(self.options.ancestors.get()): if not todo: break done |= todo self.info( _("Downloading %s. of generations of ancestors...") % (i + 1)) todo = self.tree.add_parents(todo) - done todo = set(self.tree.indi.keys()) done = set() for i in range(self.options.descendants.get()): if not todo: break done |= todo self.info( _("Downloading %s. of generations of descendants...") % (i + 1)) todo = self.tree.add_children(todo) - done if self.options.spouses.get(): self.info(_("Downloading spouses and marriage information...")) todo = set(self.tree.indi.keys()) self.tree.add_spouses(todo) ordi = self.options.ordinances.get() cont = self.options.contributors.get() async def download_stuff(loop): futures = set() for fid, indi in self.tree.indi.items(): futures.add(loop.run_in_executor(None, indi.get_notes)) if ordi: futures.add( loop.run_in_executor(None, self.tree.add_ordinances, fid)) if cont: futures.add( loop.run_in_executor(None, indi.get_contributors)) for fam in self.tree.fam.values(): futures.add(loop.run_in_executor(None, fam.get_notes)) if cont: futures.add( loop.run_in_executor(None, fam.get_contributors)) for future in futures: await future loop = asyncio.get_event_loop() self.info( _("Downloading notes") + ((("," if cont else _(" and")) + _(" ordinances")) if ordi else "") + (_(" and contributors") if cont else "") + "...") loop.run_until_complete(download_stuff(loop)) self.tree.reset_num() self.btn_valid.config(command=self.save, state="normal", text=_("Save")) self.info(text=_("Success ! Click below to save your GEDCOM file")) self.update_info_tree() self.update_needed = False def command_in_thread(self, func): """ command to update widget in a new Thread """ def res(): self.update_needed = True Thread(target=self.update_gui).start() Thread(target=func).start() return res def update_info_tree(self): """ update informations """ if self.info_tree and self.start_time and self.tree: self.info_indis.config(text=_("Individuals: %s") % len(self.tree.indi)) self.info_fams.config(text=_("Families: %s") % len(self.tree.fam)) self.info_sources.config(text=_("Sources: %s") % len(self.tree.sources)) self.info_notes.config(text=_("Notes: %s") % len(self.tree.notes)) t = round(time.time() - self.start_time) minutes = t // 60 seconds = t % 60 self.time.config(text=_("Elapsed time: %s:%s") % (minutes, str(seconds).zfill(2))) def update_gui(self): """ update widget """ while self.update_needed: self.update_info_tree() self.master.update() time.sleep(0.1)
parser.add_argument('-i', metavar='<FILE>', nargs='+', type=argparse.FileType('r', encoding='UTF-8'), default=sys.stdin, help='input GEDCOM files [stdin]') parser.add_argument('-o', metavar='<FILE>', nargs='?', type=argparse.FileType('w', encoding='UTF-8'), default=sys.stdout, help='output GEDCOM files [stdout]') except TypeError: sys.stderr.write('Python >= 3.4 is required to run this script\n') sys.stderr.write('(see https://docs.python.org/3/whatsnew/3.4.html#argparse)\n') exit(2) # extract arguments from the command line try: parser.error = parser.exit args = parser.parse_args() except SystemExit: parser.print_help() exit(2) tree = Tree() indi_counter = 0 fam_counter = 0 note_counter = 0 temp_note = None # read the GEDCOM data for file in args.i: ged = Gedcom(file, tree) # add informations about individuals for num in ged.indi: fid = ged.indi[num].fid if fid not in tree.indi: indi_counter += 1