Exemplo n.º 1
0
    def read(self):
        fname = 'config.pkl'
        """ Read config file  """
        self.logger.debug(f'config read {self.cache_dir} {fname}')
        # Verify main directory exists
        if not os.path.exists(self.cache_dir):
            self.logger.warning(f"{self.cache_dir} folder not found.")
            TKHelper.fatal_error(
                f"{self.cache_dir} folder not found.  Please use Config button to correct"
            )

        self.config_cd = CachedDictionary.CachedDictionary(
            self.cache_dir, fname)
        self.config_cd.read()

        if self.config_cd.error:
            self.logger.error(
                f'Config {os.path.join(self.cache_dir, fname)} not found')

            # Create empty config file
            path = os.path.join(self.cache_dir, "config.pkl")
            self.set("gedcom_path", "GEDCOM filename: <empty>")
            with open(path, 'wb') as file:
                pickle.dump(self.config_cd.dict, file)
            return True
        else:
            return False
Exemplo n.º 2
0
    def load_handler(self):
        """
        User pressed LOAD button to load an Ancestry file. Switch app display to the Review Widgets
        Load in file name and
        loop through  file and find every PLACE entry and verify the entry against the geoname data
        """
        self.w.original_entry.set_text("")
        self.w.remove_initialization_widgets()  # Remove old widgets
        self.w.create_review_widgets(
        )  # Switch display from Initial widgets to main review widgets

        self.load_data()

        ged_path = self.cfg.get(
            "gedcom_path")  # Get saved config setting for  file

        # Load appropriate handler based on file type
        if ged_path is not None:
            if '.ged' in ged_path:
                self.out_suffix = "import.ged"
                self.ancestry_file_handler = Gedcom.Gedcom(
                    in_path=ged_path,
                    out_suffix=temp_suffix,
                    cache_d=self.cache_dir,
                    progress=None,
                    geodata=self.geodata
                )  # Routines to open and parse GEDCOM file
            elif '.gramps' in ged_path:
                self.out_suffix = "import.gramps"
                # self.out_suffix = "csv"
                self.ancestry_file_handler = GrampsXml.GrampsXml(
                    in_path=ged_path,
                    out_suffix=temp_suffix,
                    cache_d=self.cache_dir,
                    progress=None,
                    geodata=self.geodata
                )  # Routines to open and parse Gramps file
        else:
            self.out_suffix = 'unk.new.ged'
            messagebox.showwarning(
                f'UNKNOWN File type. Not .gramps and not .ged. \n\n{ged_path}')

        self.out_diag_file = open(ged_path + '.output.txt', 'w')
        self.in_diag_file = open(ged_path + '.input.txt', 'w')

        if self.ancestry_file_handler.error:
            TKHelper.fatal_error(f"File {ged_path} not found.")

        self.w.root.update()

        self.place: Loc.Loc = Loc.Loc(
        )  # Create an object to store info for the current Place

        # Add  filename to Title
        path_parts = os.path.split(ged_path)  # Extract filename from full path
        self.w.title.set_text(f'GEO FINDER - {path_parts[1]}')

        # Read  file, find each place entry and handle it.
        self.w.user_entry.set_text("Scanning to previous position...")
        self.handle_place_entry()
Exemplo n.º 3
0
    def end_of_file_shutdown(self):
        # End of file reached
        TKHelper.disable_buttons(button_list=self.w.review_buttons)
        # self.start_time = time.time()
        #self.logger.debug(f'COMPLETED time={int((time.time() - self.start_time) / 60)} minutes')
        self.w.status.set_text("Done.  Shutting Down...")
        self.w.original_entry.set_text(" ")
        path = self.cfg.get("gedcom_path")
        self.ancestry_file_handler.close()

        self.update_statistics()
        self.w.root.update_idletasks()  # Let GUI update

        if 'ramp' in self.out_suffix:
            # Gramps file is .csv
            messagebox.showinfo(
                "Info",
                f"Finished.  Created file for Import to Ancestry software:\n\n {path}.csv"
            )
        else:
            messagebox.showinfo(
                "Info",
                f"Finished.  Created file for Import to Ancestry software:\n\n {path}.{self.out_suffix}"
            )
        self.logger.info('End of  file')
        self.shutdown()
Exemplo n.º 4
0
    def load_data(self):
        # Read in Skiplist, Replace list  list
        self.skiplist = CachedDictionary(self.cache_dir, "skiplist.pkl")
        self.skiplist.read()
        self.global_replace = CachedDictionary(self.cache_dir,
                                               "global_replace.pkl")
        self.global_replace.read()
        # self.user_accepted = CachedDictionary(self.cache_dir, "accepted.pkl")  # List of items that have been accepted
        # self.user_accepted.read()

        # Initialize geodata
        self.geodata = Geodata.Geodata(directory_name=self.directory,
                                       progress_bar=self.w.prog)
        error = self.geodata.read()
        if error:
            TKHelper.fatal_error(MISSING_FILES)

        # If the list of supported countries is unusually short, display note to user
        num = self.display_country_note()
        self.logger.info('{} countries will be loaded'.format(num))

        # Read in Geoname Gazeteer file - city names, lat/long, etc.
        error = self.geodata.read_geonames()
        if error:
            TKHelper.fatal_error(MISSING_FILES)
        self.w.root.update()
        self.w.prog.update_progress(100, " ")
Exemplo n.º 5
0
    def display_country_note(self) -> int:
        """ display warning if only a small number of countries are enabled """
        country_list, supported_countries = self.geodata.geo_files.get_supported_countries(
        )
        self.w.root.update()
        if supported_countries == 0:
            TKHelper.fatal_error(
                "No countries enabled.\n\nUse Config Country Tab to change country list\n"
            )

        # if supported_countries < 3:
        #    messagebox.showinfo("Info", f"Loading geocode data for the following ISO country codes:"
        #                                f"\n\n{country_list}\n\nUse Config Country Tab to change country list\n")
        return supported_countries
Exemplo n.º 6
0
 def filename_handler(self):
     """ Display file open selector dialog """
     fname = filedialog.askopenfilename(initialdir=self.directory,
                                        title=f"Select {file_types} file",
                                        filetypes=[
                                            ("GEDCOM files", "*.ged"),
                                            ("Gramps files", "*.gramps"),
                                            ("all files", "*.*")
                                        ])
     if len(fname) > 1:
         self.cfg.set("gedcom_path", fname)  # Add filename to dict
         self.cfg.write()  # Write out config file
         self.w.status.set_text(f"Click Open to load {file_types} file")
         self.w.original_entry.set_text(self.cfg.get("gedcom_path"))
         TKHelper.set_preferred_button(self.w.load_button,
                                       self.w.initialization_buttons,
                                       "Preferred.TButton")
Exemplo n.º 7
0
    def configure_widgets(self, frm):
        super().configure_widgets(frm)

        # Add Lable for allow user to Add to list
        TKHelper.set_grid_position(self.pad, "pad", grd=self.grd)

        # Add Lable for allow user to Add to list
        TKHelper.set_grid_position(self.add_label, "add_label", grd=self.grd)

        # Add Button to allow user to Add to list
        TKHelper.set_grid_position(self.add_button, "add_button", grd=self.grd)

        # Create listbox of countries to add with scrollbar
        TKHelper.set_grid_position(self.listbox_all_countries,
                                   "listbox_all_countries",
                                   grd=self.grd)
        self.scrollbar2.config(command=self.listbox_all_countries.yview)
        TKHelper.set_grid_position(self.scrollbar2, "scrollbar2", grd=self.grd)
Exemplo n.º 8
0
    def quit_handler(self):
        """ Set flag for shutdown.  Process all global replaces and exit """
        self.skip_count += 1

        path = self.cfg.get("gedcom_path")
        if self.w.prog.shutdown_requested:
            # Already in shutdown and user aborted
            self.logger.info('Shutdown')
            self.shutdown()

        self.w.prog.shutdown_requested = True

        if messagebox.askyesno(
                'Generate Import File?',
                f'All updates saved.\n\nDo you want to generate a file for import'
                f' to Gedcom/Gramps?\n\n',
                default='no'):
            # Write file for importing back
            messagebox.showinfo(
                "Generate Import File",
                "Reminder -  make sure the ancestry export file you are working on is up to date before "
                "generating a file to import back!\n\nThe file will take about 10 minutes per 1000 places"
            )

            TKHelper.disable_buttons(button_list=self.w.review_buttons)
            self.w.quit_button.config(state="disabled")
            self.w.prog.startup = True
            self.w.statistics_text.configure(style="Good.TLabel")

            self.w.user_entry.set_text("Creating Import File...")
            self.start_time = time.time()
            # Write out the item we are on
            self.ancestry_file_handler.write_asis(
                self.w.original_entry.get_text())

            # We will still continue to go through file, but only handle global replaces
            self.handle_place_entry()
        else:
            # Immediate exit
            self.logger.info('Shutdown')
            self.shutdown()
Exemplo n.º 9
0
    def __init__(self):
        print('GeoFinder v{}'.format(__version__.__version__))
        print('Python {}.{}'.format(sys.version_info[0], sys.version_info[1]))

        if sys.version_info < (3, 6, 0):
            raise Exception("GeoFinder Requires Python 3.6 or higher.")
        val = ''
        print(f'GeoFinder Requires Python 3.6 or higher {val}')

        self.save_enabled = False  # Only allow SAVE when we have an item that was matched in geonames
        self.user_selected_list = False  # Indicates whether user selected a list entry or text edit entry
        self.err_count = 0
        self.matched_count = 0
        self.review_count = 0
        self.skip_count = 0
        self.odd = False
        self.ancestry_file_handler = None
        self.place = None
        self.skiplist = None
        self.global_replace = None
        self.geodata = None
        self.out_suffix = 'unknown_suffix'
        self.out_diag_file = None
        self.in_diag_file = None

        # initiate the parser
        parser = argparse.ArgumentParser()
        parser.add_argument("--logging", help="Enable quiet logging")
        parser.add_argument("--diagnostics", help="Create diagnostics files")

        # read arguments from the command line
        args = parser.parse_args()

        # check for --verbose switch
        if args.logging == 'info':
            self.logger = self.setup_logging_info('geofinder Init')
            self.logger.info(f"--logging set to INFO logging {args.logging}")
        else:
            self.logger = self.setup_logging('geofinder Init')

        # check for --diagnostics switch
        if args.diagnostics:
            self.logger.info(f"--diagnostics files enabled {args.diagnostics}")
            self.diagnostics = True
        else:
            self.diagnostics = False

        # Create App window and configure  window buttons and widgets
        self.w: AppLayout.AppLayout = AppLayout.AppLayout(self)
        self.w.create_initialization_widgets()
        self.w.config_button.config(state="normal")

        # Get our base directory path from INI file.  Create INI if it doesnt exist
        home_path = str(Path.home())
        self.directory = Path(
            os.path.join(home_path, GeoKeys.get_directory_name()))
        self.ini_handler = IniHandler(home_path=home_path,
                                      ini_name='geofinder.ini')
        self.directory = self.ini_handler.get_directory_from_ini()

        self.cache_dir = GeoKeys.get_cache_directory(self.directory)
        self.logger.info(f'Cache directory {self.cache_dir}')

        # Set up configuration  class
        self.cfg = Config.Config(self.directory)
        self.util = UtilLayout.UtilLayout(root=self.w.root,
                                          directory=self.directory,
                                          cache_dir=self.cache_dir)

        if not os.path.exists(self.cache_dir):
            # Create directories for GeoFinder
            if messagebox.askyesno(
                    'Geoname Data Cache Folder not found',
                    f'Create Geoname Cache folder?\n\n{self.cache_dir} '):
                err = self.cfg.create_directories()
                if not os.path.exists(self.cache_dir):
                    messagebox.showwarning(
                        'Geoname Data Cache Folder not found',
                        f'Unable to create folder\n\n{self.cache_dir} ')
                    self.shutdown()
                else:
                    self.logger.debug(f'Created {self.cache_dir}')
                    messagebox.showinfo(
                        'Geoname Data Cache Folder created',
                        f'Created folder\n\n{self.cache_dir} ')
            else:
                self.shutdown()

        # Ensure GeoFinder directory structure is valid
        if self.cfg.valid_directories():
            # Directories are valid.  See if  required Geonames files are present
            err = self.check_configuration()
            if err:
                # Missing files
                self.logger.warning('Missing files')
                self.w.status.set_text("Click Config to set up Geo Finder")
                TKHelper.set_preferred_button(self.w.config_button,
                                              self.w.initialization_buttons,
                                              "Preferred.TButton")
                self.w.load_button.config(state="disabled")
            else:
                # No config errors
                # Read config settings (Ancestry file path)
                err = self.cfg.read()
                if err:
                    self.logger.warning('error reading {} config.pkl'.format(
                        self.cache_dir))

                self.w.original_entry.set_text(self.cfg.get("gedcom_path"))
                TKHelper.enable_buttons(self.w.initialization_buttons)
                if os.path.exists(self.cfg.get("gedcom_path")):
                    #  file is valid.  Prompt user to click Open for  file
                    self.w.status.set_text(
                        f"Click Open to load {file_types} file")
                    TKHelper.set_preferred_button(
                        self.w.load_button, self.w.initialization_buttons,
                        "Preferred.TButton")
                else:
                    # No file.  prompt user to select a  file - GEDCOM file name isn't valid
                    self.w.status.set_text(f"Choose a {file_types} file")
                    self.w.load_button.config(state="disabled")
                    TKHelper.set_preferred_button(
                        self.w.choose_button, self.w.initialization_buttons,
                        "Preferred.TButton")
        else:
            # Missing directories
            self.logger.warning('Directories not found: {} '.format(
                self.cache_dir))
            self.w.status.set_text("Click Config to set up Geo Finder")
            self.w.load_button.config(state="disabled")
            TKHelper.set_preferred_button(self.w.config_button,
                                          self.w.initialization_buttons,
                                          "Preferred.TButton")

        # Flag to indicate whether we are in startup or in Window loop.  Determines how window idle is called
        self.startup = False
        self.w.root.mainloop(
        )  # ENTER MAIN LOOP and Wait for user to click on load button
Exemplo n.º 10
0
    def display_result(self, place: Loc.Loc):
        """ Display result details for an item  """
        # Enable buttons so user can either click Skip, or edit the item and Click Verify.
        place.safe_strings()

        TKHelper.enable_buttons(self.w.review_buttons)

        # Enable action buttons based on type of result
        if place.result_type == GeoKeys.Result.MULTIPLE_MATCHES or \
                place.result_type == GeoKeys.Result.NO_MATCH or \
                place.result_type == GeoKeys.Result.NO_COUNTRY:
            # Disable the Save & Map button until user clicks Verify and item is found
            self.set_save_allowed(False)
            TKHelper.set_preferred_button(self.w.verify_button,
                                          self.w.review_buttons,
                                          "Preferred.TButton")
        elif place.result_type == GeoKeys.Result.NOT_SUPPORTED:
            # Found a match or Not supported - enable save and verify
            # self.set_save_allowed(True)  # Enable save button
            TKHelper.set_preferred_button(self.w.skip_button,
                                          self.w.review_buttons,
                                          "Preferred.TButton")
        else:
            # Found a match or Not supported - enable save and verify
            self.set_save_allowed(True)  # Enable save button
            TKHelper.set_preferred_button(self.w.save_button,
                                          self.w.review_buttons,
                                          "Preferred.TButton")

        # Display status and color based on success
        self.set_status_text(place.get_status())
        if place.result_type in GeoKeys.successful_match:
            if place.place_type == Loc.PlaceType.CITY:
                self.w.status.configure(style="Good.TLabel")
            else:
                self.w.status.configure(style="GoodCounty.TLabel")
        else:
            self.w.status.configure(style="Error.TLabel")

        # set Verify as preferred button
        if len(place.georow_list) > 1:
            TKHelper.set_preferred_button(self.w.verify_button,
                                          self.w.review_buttons,
                                          "Preferred.TButton")
            self.set_save_allowed(False)

        if len(place.georow_list) > 0:
            # Display matches in listbox
            self.w.tree.focus()  # Set focus to listbox
            self.display_georow_list(place)
        else:
            # No matches
            self.w.user_entry.focus()  # Set focus to text edit widget
            self.display_one_georow(place.status_detail,
                                    place.geoid,
                                    score=9999,
                                    feat='')

        # Display GEDCOM person and event that this location refers to
        self.w.ged_event_info.set_text(
            f'{self.ancestry_file_handler.get_name(self.ancestry_file_handler.id)}: '
            f'{self.ancestry_file_handler.event_name} {self.ancestry_file_handler.date}'
        )
        self.w.root.update_idletasks()