From cd48d7acf1695b0c2ce77442be6ff45c8a2a37ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=AE=D1=80=D0=B8=D0=B9=20=D0=9F=D0=B5=D1=80=D1=88=D0=B8?= =?UTF-8?q?=D0=BD?= Date: Sun, 9 Jan 2022 21:55:06 +0500 Subject: [PATCH] fix bugs --- storage/profile_test.py | 6 ++--- zwift_offline.py | 57 ++++++++++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/storage/profile_test.py b/storage/profile_test.py index 480f5fc..0880a11 100644 --- a/storage/profile_test.py +++ b/storage/profile_test.py @@ -8,9 +8,9 @@ from google.protobuf.json_format import MessageToDict app = Flask(__name__) profile = profile_pb2.Profile() -profile_file = '../../zoffline-helper/profile.bin-sul' +#profile_file = '../../zoffline-helper/profile.bin-sul' #profile_file = '../../zoffline-helper/profile.bin' -#profile_file = '../storage/5/profile.bin' +profile_file = '../storage/5/profile.bin' with open(profile_file, 'rb') as fd: profile.ParseFromString(fd.read()) @@ -43,7 +43,7 @@ def copyAttributes(jprofile, jprofileFull, src): jprofile[src] = dest jprofileFull = MessageToDict(profile) -jprofile = {"id": profile.id, "firstName": jsf(profile, 'first_name'), "lastName": jsf(profile, 'last_name'), "preferredLanguage": jsf(profile, 'preferred_language'), "bodyType":jsv0(profile, 'body_type'), "male": jsb1(profile, 'is_male'), "imageSrc": "https://us-or-rly101.zwift.com/download/%s/avatarLarge.jpg" % profile.id, "imageSrcLarge": "https://us-or-rly101.zwift.com/download/%s/avatarLarge.jpg" % profile.id, "playerType": profile_pb2.Profile.PlayerType.Name(jsv0(profile, 'player_type')), "playerTypeId": jsv0(profile, 'player_type'), "playerSubTypeId": None, "emailAddress": jsf(profile, 'email'), "countryCode": jsf(profile, 'country_code'), "dob": jsf(profile, 'dob'), "countryAlpha3": "rus", "useMetric": jsb1(profile, 'use_metric'), "privacy": {"approvalRequired": False, "displayWeight": True, "minor": False, "privateMessaging": False, "defaultFitnessDataPrivacy": False, "suppressFollowerNotification": False, "displayAge": True, "defaultActivityPrivacy": "PUBLIC"}, "age": jsv0(profile, 'age'), "ftp": jsf(profile, 'ftp'), "b": False, "weight": jsf(profile, 'weight_in_grams'), "connectedToStrava": jsb0(profile, 'connected_to_strava'), "connectedToTrainingPeaks": jsb0(profile, 'connected_to_training_peaks'), "connectedToTodaysPlan": jsb0(profile, 'connected_to_todays_plan'), "connectedToUnderArmour": jsb0(profile, 'connected_to_under_armour'), "connectedToFitbit": jsb0(profile, 'connected_to_fitbit'), "connectedToGarmin": jsb0(profile, 'connected_to_garmin'), "height": jsf(profile, 'height_in_millimeters'), "location": "", "socialFacts": jprofileFull.get('socialFacts'), "totalExperiencePoints": jsv0(profile, 'total_xp'), "worldId": jsf(profile, 'world_id'), "totalDistance": jsv0(profile, 'total_distance_in_meters'), "totalDistanceClimbed": jsv0(profile, 'elevation_gain_in_meters'), "totalTimeInMinutes": jsv0(profile, 'time_ridden_in_minutes'), "achievementLevel": jsv0(profile, 'achievement_level'), "totalWattHours": jsv0(profile, 'total_watt_hours'), "runTime1miInSeconds": jsv0(profile, 'run_time_1mi_in_seconds'), "runTime5kmInSeconds": jsv0(profile, 'run_time_5km_in_seconds'), "runTime10kmInSeconds": jsv0(profile, 'run_time_10km_in_seconds'), "runTimeHalfMarathonInSeconds": jsv0(profile, 'run_time_half_marathon_in_seconds'), "runTimeFullMarathonInSeconds": jsv0(profile, 'run_time_full_marathon_in_seconds'), "totalInKomJersey": jsv0(profile, 'total_in_kom_jersey'), "totalInSprintersJersey": jsv0(profile, 'total_in_sprinters_jersey'), "totalInOrangeJersey": jsv0(profile, 'total_in_orange_jersey'), "currentActivityId": jsf(profile, 'current_activity_id'), "enrolledZwiftAcademy": jsv0(profile, 'enrolled_program') == profile.EnrolledProgram.ZWIFT_ACADEMY, "runAchievementLevel": jsv0(profile, 'run_achievement_level'), "totalRunDistance": jsv0(profile, 'total_run_distance'), "totalRunTimeInMinutes": jsv0(profile, 'time_ridden_in_minutes'), "totalRunExperiencePoints": jsv0(profile, 'total_run_experience_points'), "totalRunCalories": int(profile.total_watt_hours * 3.07089), "totalGold": jsv0(profile, 'total_gold_drops'), "powerSourceType": "Power Source", "powerSourceModel": "Power Meter", "virtualBikeModel": "Zwift Carbon", "profilePropertyChanges": jprofileFull.get('propertyChanges'), "cyclingOrganization": jsf(profile, 'cycling_organization'), "userAgent": "CNL/3.13.0 (Android 11) zwift/1.0.85684 curl/7.78.0-DEV", "stravaPremium": False, "profileChanges": False, "launchedGameClient": "09/19/2021 13:24:19 +0000", "createdOn":"2021-09-19T13:24:17.783+0000", "likelyInGame": False, "address": None, "bt":"f97803d3-efac-4510-a17a-ef44e65d3071", "numberOfFolloweesInCommon": 0, "fundraiserId": None, "source": "Android", "origin": None, "licenseNumber": None, "bigCommerceId": None, "marketingConsent": None, "affiliate": None, "avantlinkId": None, "virtualBikeModel": "Zwift Carbon", "connectedToWithings": False, "connectedToRuntastic": False, "connectedToZwiftPower": False, "powerSourceType": "Power Source", "powerSourceModel": "Power Meter", "riding": False, "location": "", "publicId": "5a72e9b1-239f-435e-8757-af9467336b40", "mixpanelDistinctId": "21304417-af2d-4c9b-8543-8ba7c0500e84"} +jprofile = {"id": profile.id, "firstName": jsf(profile, 'first_name'), "lastName": jsf(profile, 'last_name'), "preferredLanguage": jsf(profile, 'preferred_language'), "bodyType":jsv0(profile, 'body_type'), "male": jsb1(profile, 'is_male'), "imageSrc": "https://us-or-rly101.zwift.com/download/%s/avatarLarge.jpg" % profile.id, "imageSrcLarge": "https://us-or-rly101.zwift.com/download/%s/avatarLarge.jpg" % profile.id, "playerType": profile_pb2.Profile.PlayerType.Name(jsf(profile, 'player_type', 1)), "playerTypeId": jsf(profile, 'player_type', 1), "playerSubTypeId": None, "emailAddress": jsf(profile, 'email'), "countryCode": jsf(profile, 'country_code'), "dob": jsf(profile, 'dob'), "countryAlpha3": "rus", "useMetric": jsb1(profile, 'use_metric'), "privacy": {"approvalRequired": False, "displayWeight": True, "minor": False, "privateMessaging": False, "defaultFitnessDataPrivacy": False, "suppressFollowerNotification": False, "displayAge": True, "defaultActivityPrivacy": "PUBLIC"}, "age": jsv0(profile, 'age'), "ftp": jsf(profile, 'ftp'), "b": False, "weight": jsf(profile, 'weight_in_grams'), "connectedToStrava": jsb0(profile, 'connected_to_strava'), "connectedToTrainingPeaks": jsb0(profile, 'connected_to_training_peaks'), "connectedToTodaysPlan": jsb0(profile, 'connected_to_todays_plan'), "connectedToUnderArmour": jsb0(profile, 'connected_to_under_armour'), "connectedToFitbit": jsb0(profile, 'connected_to_fitbit'), "connectedToGarmin": jsb0(profile, 'connected_to_garmin'), "height": jsf(profile, 'height_in_millimeters'), "location": "", "socialFacts": jprofileFull.get('socialFacts'), "totalExperiencePoints": jsv0(profile, 'total_xp'), "worldId": jsf(profile, 'world_id'), "totalDistance": jsv0(profile, 'total_distance_in_meters'), "totalDistanceClimbed": jsv0(profile, 'elevation_gain_in_meters'), "totalTimeInMinutes": jsv0(profile, 'time_ridden_in_minutes'), "achievementLevel": jsv0(profile, 'achievement_level'), "totalWattHours": jsv0(profile, 'total_watt_hours'), "runTime1miInSeconds": jsv0(profile, 'run_time_1mi_in_seconds'), "runTime5kmInSeconds": jsv0(profile, 'run_time_5km_in_seconds'), "runTime10kmInSeconds": jsv0(profile, 'run_time_10km_in_seconds'), "runTimeHalfMarathonInSeconds": jsv0(profile, 'run_time_half_marathon_in_seconds'), "runTimeFullMarathonInSeconds": jsv0(profile, 'run_time_full_marathon_in_seconds'), "totalInKomJersey": jsv0(profile, 'total_in_kom_jersey'), "totalInSprintersJersey": jsv0(profile, 'total_in_sprinters_jersey'), "totalInOrangeJersey": jsv0(profile, 'total_in_orange_jersey'), "currentActivityId": jsf(profile, 'current_activity_id'), "enrolledZwiftAcademy": jsv0(profile, 'enrolled_program') == profile.EnrolledProgram.ZWIFT_ACADEMY, "runAchievementLevel": jsv0(profile, 'run_achievement_level'), "totalRunDistance": jsv0(profile, 'total_run_distance'), "totalRunTimeInMinutes": jsv0(profile, 'time_ridden_in_minutes'), "totalRunExperiencePoints": jsv0(profile, 'total_run_experience_points'), "totalRunCalories": int(profile.total_watt_hours * 3.07089), "totalGold": jsv0(profile, 'total_gold_drops'), "powerSourceType": "Power Source", "powerSourceModel": "Power Meter", "virtualBikeModel": "Zwift Carbon", "profilePropertyChanges": jprofileFull.get('propertyChanges'), "cyclingOrganization": jsf(profile, 'cycling_organization'), "userAgent": "CNL/3.13.0 (Android 11) zwift/1.0.85684 curl/7.78.0-DEV", "stravaPremium": False, "profileChanges": False, "launchedGameClient": "09/19/2021 13:24:19 +0000", "createdOn":"2021-09-19T13:24:17.783+0000", "likelyInGame": False, "address": None, "bt":"f97803d3-efac-4510-a17a-ef44e65d3071", "numberOfFolloweesInCommon": 0, "fundraiserId": None, "source": "Android", "origin": None, "licenseNumber": None, "bigCommerceId": None, "marketingConsent": None, "affiliate": None, "avantlinkId": None, "virtualBikeModel": "Zwift Carbon", "connectedToWithings": False, "connectedToRuntastic": False, "connectedToZwiftPower": False, "powerSourceType": "Power Source", "powerSourceModel": "Power Meter", "riding": False, "location": "", "publicId": "5a72e9b1-239f-435e-8757-af9467336b40", "mixpanelDistinctId": "21304417-af2d-4c9b-8543-8ba7c0500e84"} copyAttributes(jprofile, jprofileFull, 'publicAttributes') copyAttributes(jprofile, jprofileFull, 'privateAttributes') diff --git a/zwift_offline.py b/zwift_offline.py index 9fa13cb..afa2717 100644 --- a/zwift_offline.py +++ b/zwift_offline.py @@ -1364,20 +1364,20 @@ def api_profiles(): elif seconds < 5259492: span = '%s weeks' % (seconds // 604800) else: span = '%s months' % (seconds // 2629746) p.last_name = span + ' ago [ghost]' - p.f24 = 1456463855 # tron bike + p.bike_frame = 1456463855 # tron bike p.country_code = 0 - if p.f20 == 3761002195: - p.f20 = 1869390707 # basic 2 jersey - p.f27 = 80 # green bike + if p.ride_jersey == 3761002195: + p.ride_jersey = 1869390707 # basic 2 jersey + p.bike_frame_colour = 80 # green bike else: - p.f20 = 3761002195 # basic 4 jersey - p.f27 = 125 # blue bike - if p.f68 == 3344420794: - p.f68 = 4197967370 # shirt 11 - p.f69 = 3273293920 # shorts 11 + p.ride_jersey = 3761002195 # basic 4 jersey + p.bike_frame_colour = 125 # blue bike + if p.run_shirt_type == 3344420794: + p.run_shirt_type = 4197967370 # shirt 11 + p.run_shorts_type = 3273293920 # shorts 11 else: - p.f68 = 3344420794 # shirt 10 - p.f69 = 4269451728 # shorts 10 + p.run_shirt_type = 3344420794 # shirt 10 + p.run_shorts_type = 4269451728 # shorts 10 else: if p_id > 2000000 and p_id < 3000000: profile_file = '%s/%s/profile.bin' % (PACE_PARTNERS_DIR, i) @@ -1402,23 +1402,26 @@ def strava_upload(player_id, activity): logger.warn("stravalib is not installed. Skipping Strava upload attempt.") return profile_dir = '%s/%s' % (STORAGE_DIR, player_id) + strava_token = '%s/strava_token.txt' % profile_dir + if not os.path.exists(strava_token): + logger.info("strava_token.txt missing, skip Strava activity update") + return strava = Client() try: - with open('%s/strava_token.txt' % profile_dir, 'r') as f: + with open(strava_token, 'r') as f: client_id = f.readline().rstrip('\r\n') client_secret = f.readline().rstrip('\r\n') strava.access_token = f.readline().rstrip('\r\n') refresh_token = f.readline().rstrip('\r\n') expires_at = f.readline().rstrip('\r\n') except Exception as exc: - logger.warn('strava_token: %s' % repr(exc)) - logger.warn("Failed to read %s/strava_token.txt. Skipping Strava upload attempt." % profile_dir) + logger.warn("Failed to read %s. Skipping Strava upload attempt. %s" % (strava_token, repr(exc))) return try: if get_utc_time() > int(expires_at): refresh_response = strava.refresh_access_token(client_id=client_id, client_secret=client_secret, refresh_token=refresh_token) - with open('%s/strava_token.txt' % profile_dir, 'w') as f: + with open(strava_token, 'w') as f: f.write(client_id + '\n') f.write(client_secret + '\n') f.write(refresh_response['access_token'] + '\n') @@ -1442,8 +1445,12 @@ def garmin_upload(player_id, activity): logger.warn("garmin_uploader is not installed. Skipping Garmin upload attempt. %s" % repr(exc)) return profile_dir = '%s/%s' % (STORAGE_DIR, player_id) + garmin_credentials = '%s/garmin_credentials.txt' % profile_dir + if not os.path.exists(garmin_credentials): + logger.info("garmin_credentials.txt missing, skip Garmin activity update") + return try: - with open('%s/garmin_credentials.txt' % profile_dir, 'r') as f: + with open(garmin_credentials, 'r') as f: if credentials_key is not None: cipher_suite = Fernet(credentials_key) ciphered_text = f.read() @@ -1456,7 +1463,7 @@ def garmin_upload(player_id, activity): username = f.readline().rstrip('\r\n') password = f.readline().rstrip('\r\n') except Exception as exc: - logger.warn("Failed to read %s/garmin_credentials.txt. Skipping Garmin upload attempt. $s" % (profile_dir, repr(exc))) + logger.warn("Failed to read %s. Skipping Garmin upload attempt. %s" % (garmin_credentials, repr(exc))) return try: with open('%s/last_activity.fit' % profile_dir, 'wb') as f: @@ -1472,11 +1479,15 @@ def garmin_upload(player_id, activity): def runalyze_upload(player_id, activity): profile_dir = '%s/%s' % (STORAGE_DIR, player_id) + runalyze_token = '%s/runalyze_token.txt' % profile_dir + if not os.path.exists(runalyze_token): + logger.info("runalyze_token.txt missing, skip Runalyze activity update") + return try: - with open('%s/runalyze_token.txt' % profile_dir, 'r') as f: + with open(runalyze_token, 'r') as f: runtoken = f.readline().rstrip('\r\n') except Exception as exc: - logger.warn("Failed to read %s/runalyze_token.txt. Skipping Runalyze upload attempt." % (profile_dir, repr(exc))) + logger.warn("Failed to read %s. Skipping Runalyze upload attempt." % (runalyze_token, repr(exc))) return try: with open('%s/last_activity.fit' % profile_dir, 'wb') as f: @@ -1496,11 +1507,15 @@ def runalyze_upload(player_id, activity): def zwift_upload(player_id, activity): profile_dir = '%s/%s' % (STORAGE_DIR, player_id) SERVER_IP_FILE = "%s/server-ip.txt" % STORAGE_DIR + zwift_credentials = '%s/zwift_credentials.txt' % profile_dir + if not os.path.exists(zwift_credentials): + logger.info("zwift_credentials.txt missing, skip Zwift activity update") + return if not os.path.exists(SERVER_IP_FILE): logger.info("server_ip.txt missing, skip Zwift activity update") return try: - with open('%s/zwift_credentials.txt' % profile_dir, 'r') as f: + with open(zwift_credentials, 'r') as f: if credentials_key is not None: cipher_suite = Fernet(credentials_key) ciphered_text = f.read() @@ -1513,7 +1528,7 @@ def zwift_upload(player_id, activity): username = f.readline().rstrip('\r\n') password = f.readline().rstrip('\r\n') except Exception as exc: - logger.warn("Failed to read %s/zwift_credentials.txt. Skipping Zwift upload attempt. %s" % (profile_dir, repr(exc))) + logger.warn("Failed to read %s. Skipping Zwift upload attempt. %s" % (zwift_credentials, repr(exc))) return try: