def copy_data(overwite, latest, stats): """Copy data from a mounted Garmin USB device to files.""" logger.info("___Copying Data___") copy = Copy(gc_config.device_mount_dir()) settings_dir = GarminDBConfigManager.get_or_create_fit_files_dir() root_logger.info("Copying settings to %s", settings_dir) copy.copy_settings(settings_dir) if Statistics.activities in stats: activities_dir = GarminDBConfigManager.get_or_create_activities_dir() root_logger.info("Copying activities to %s", activities_dir) copy.copy_activities(activities_dir, latest) if Statistics.monitoring in stats: monitoring_dir = GarminDBConfigManager.get_or_create_monitoring_dir(datetime.datetime.now().year) root_logger.info("Copying monitoring to %s", monitoring_dir) copy.copy_monitoring(monitoring_dir, latest) if Statistics.sleep in stats: monitoring_dir = GarminDBConfigManager.get_or_create_monitoring_dir(datetime.datetime.now().year) root_logger.info("Copying sleep to %s", monitoring_dir) copy.copy_sleep(monitoring_dir, latest)
def login(self): """Login to Garmin Connect.""" profile_dir = GarminDBConfigManager.get_or_create_fit_files_dir() username = self.gc_config.get_user() password = self.gc_config.get_password() if not username or not password: print("Missing config: need username and password. Edit GarminConnectConfig.json.") return logger.debug("login: %s %s", username, password) get_headers = { 'Referer' : self.garmin_connect_login_url } params = { 'service' : self.modern_rest_client.url(), 'webhost' : self.garmin_connect_base_url, 'source' : self.garmin_connect_login_url, 'redirectAfterAccountLoginUrl' : self.modern_rest_client.url(), 'redirectAfterAccountCreationUrl' : self.modern_rest_client.url(), 'gauthHost' : self.sso_rest_client.url(), 'locale' : 'en_US', 'id' : 'gauth-widget', 'cssUrl' : self.garmin_connect_css_url, 'privacyStatementUrl' : '//connect.garmin.com/en-US/privacy/', 'clientId' : 'GarminConnect', 'rememberMeShown' : 'true', 'rememberMeChecked' : 'false', 'createAccountShown' : 'true', 'openCreateAccount' : 'false', 'displayNameShown' : 'false', 'consumeServiceTicket' : 'false', 'initialFocus' : 'true', 'embedWidget' : 'false', 'generateExtraServiceTicket' : 'true', 'generateTwoExtraServiceTickets' : 'false', 'generateNoServiceTicket' : 'false', 'globalOptInShown' : 'true', 'globalOptInChecked' : 'false', 'mobile' : 'false', 'connectLegalTerms' : 'true', 'locationPromptShown' : 'true', 'showPassword' : 'true' } try: response = self.sso_rest_client.get(self.garmin_connect_sso_login, get_headers, params) except RestResponseException as e: root_logger.error("Exception during login get: %s", e) RestClient.save_binary_file('login_get.html', e.response) return False found = re.search(r"name=\"_csrf\" value=\"(\w*)", response.text, re.M) if not found: logger.error("_csrf not found: %s", response.status_code) RestClient.save_binary_file('login_get.html', response) return False logger.debug("_csrf found (%s).", found.group(1)) data = { 'username' : username, 'password' : password, 'embed' : 'false', '_csrf' : found.group(1) } post_headers = { 'Referer' : response.url, 'Content-Type' : 'application/x-www-form-urlencoded' } try: response = self.sso_rest_client.post(self.garmin_connect_sso_login, post_headers, params, data) except RestException as e: root_logger.error("Exception during login post: %s", e) return False found = re.search(r"\?ticket=([\w-]*)", response.text, re.M) if not found: logger.error("Login ticket not found (%d).", response.status_code) RestClient.save_binary_file('login_post.html', response) return False params = { 'ticket' : found.group(1) } try: response = self.modern_rest_client.get('', params=params) except RestException: logger.error("Login get homepage failed (%d).", response.status_code) RestClient.save_binary_file('login_home.html', response) return False self.user_prefs = self.__get_json(response.text, 'VIEWER_USERPREFERENCES') if profile_dir: self.modern_rest_client.save_json_to_file(f'{profile_dir}/profile.json', self.user_prefs) self.display_name = self.user_prefs['displayName'] self.social_profile = self.__get_json(response.text, 'VIEWER_SOCIAL_PROFILE') self.full_name = self.social_profile['fullName'] root_logger.info("login: %s (%s)", self.full_name, self.display_name) return True
def import_data(debug, latest, stats): """Import previously downloaded Garmin data into the database.""" logger.info("___Importing %s Data___", 'Latest' if latest else 'All') db_params_dict = GarminDBConfigManager.get_db_params() ignore_dev_fields = gc_config.ignore_dev_fields() # Import the user profile and/or settings FIT file first so that we can get the measurement system and some other things sorted out first. fit_files_dir = GarminDBConfigManager.get_or_create_fit_files_dir() gp = GarminProfile(db_params_dict, fit_files_dir, debug) if gp.file_count() > 0: gp.process() gsfd = GarminSettingsFitData(fit_files_dir, ignore_dev_fields, debug) if gsfd.file_count() > 0: gsfd.process_files(db_params_dict) garmindb = GarminDB.GarminDB(db_params_dict) measurement_system = GarminDB.Attributes.measurements_type(garmindb) if Statistics.weight in stats: weight_dir = GarminDBConfigManager.get_or_create_weight_dir() gwd = GarminWeightData(db_params_dict, weight_dir, latest, measurement_system, debug) if gwd.file_count() > 0: gwd.process() if Statistics.monitoring in stats: monitoring_dir = GarminDBConfigManager.get_or_create_monitoring_base_dir() gsd = GarminSummaryData(db_params_dict, monitoring_dir, latest, measurement_system, debug) if gsd.file_count() > 0: gsd.process() ghd = GarminHydrationData(db_params_dict, monitoring_dir, latest, measurement_system, debug) if ghd.file_count() > 0: ghd.process() gfd = GarminMonitoringFitData(monitoring_dir, latest, measurement_system, ignore_dev_fields, debug) if gfd.file_count() > 0: gfd.process_files(db_params_dict) if Statistics.sleep in stats: sleep_dir = GarminDBConfigManager.get_or_create_sleep_dir() gsd = GarminSleepData(db_params_dict, sleep_dir, latest, debug) if gsd.file_count() > 0: gsd.process() if Statistics.rhr in stats: rhr_dir = GarminDBConfigManager.get_or_create_rhr_dir() grhrd = GarminRhrData(db_params_dict, rhr_dir, latest, debug) if grhrd.file_count() > 0: grhrd.process() if Statistics.activities in stats: activities_dir = GarminDBConfigManager.get_or_create_activities_dir() # Tcx fields are less precise than the JSON files, so load Tcx first and overwrite with better JSON values. gtd = GarminTcxData(activities_dir, latest, measurement_system, debug) if gtd.file_count() > 0: gtd.process_files(db_params_dict) gjsd = GarminJsonSummaryData(db_params_dict, activities_dir, latest, measurement_system, debug) if gjsd.file_count() > 0: gjsd.process() gdjd = GarminJsonDetailsData(db_params_dict, activities_dir, latest, measurement_system, debug) if gdjd.file_count() > 0: gdjd.process() gfd = GarminActivitiesFitData(activities_dir, latest, measurement_system, ignore_dev_fields, debug) if gfd.file_count() > 0: gfd.process_files(db_params_dict)
def test_copy_settings(self): settings_dir = GarminDBConfigManager.get_or_create_fit_files_dir(test_dir=True) root_logger.info("Copying settings to %s", settings_dir) self.copy.copy_settings(settings_dir)