diff --git a/protobuf/profile.proto b/protobuf/profile.proto index 6e13ff4..1018f01 100644 --- a/protobuf/profile.proto +++ b/protobuf/profile.proto @@ -32,21 +32,6 @@ message Profile { optional fixed64 f30 = 30; //empty optional fixed64 f31 = 31; //empty optional fixed64 f32 = 32; //empty - /*message Privacy { //does not stored here - optional bool approval_required = 1; - optional bool display_weight = 2; - optional bool minor = 3; - optional bool private_messaging = 4; - optional bool default_fitness_data_privacy = 5; - optional bool suppress_follower_notification = 6; - optional bool display_age = 7; - enum ActivityPrivacyType { - PUBLIC = 0; - PRIVATE = 1; - FRIENDS = 2; - } - optional ActivityPrivacyType default_activity_privacy = 8; - }*/ optional bytes challenge_info = 33; optional uint32 country_code = 34; optional uint32 total_distance_in_meters = 35; @@ -80,14 +65,14 @@ message Profile { optional uint32 achievement_level = 49; optional bool use_metric = 50; optional bool f51 = 51; //empty - optional uint32 power_source = 52; + optional uint32 power_source_model = 52; optional uint32 f53 = 53; //empty optional uint32 f54 = 54; //empty optional uint32 age = 55; optional fixed32 f56 = 56; //empty optional uint32 f57 = 57; //empty optional string large_avatar_url = 58; - optional fixed64 f59 = 59; //empty + optional fixed64 privacy_bits = 59; repeated ProfileEntitlement entitlements = 60; optional SocialFacts social_facts = 61; @@ -140,7 +125,7 @@ message Profile { } optional string mix_panel_distinct_id = 83; optional uint32 run_achievement_level = 84; - optional uint32 f85 = 85; //0 begin run + optional uint32 total_run_time_in_minutes = 85; optional Sport sport = 86; optional uint32 f87 = 87; //360? optional bool connected_to_under_armour = 88; @@ -160,7 +145,7 @@ message Profile { optional uint32 f102 = 102; //empty optional uint32 f103 = 103; //empty optional uint32 f104 = 104; //empty - optional bool f105 = 105; //? false + optional bool connected_to_withings = 105; optional bool connected_to_fitbit = 106; repeated bytes f107 = 107; //empty optional string launched_game_client = 108; @@ -181,7 +166,7 @@ message Profile { optional bool f112 = 112; //? false repeated Attribute private_attributes = 113; repeated Attribute public_attributes = 114; - optional int32 f115 = 115; //false begin run + optional int32 total_run_calories = 115; optional int64 f116 = 116; //empty optional int32 run_time_1mi_in_seconds = 117; optional int32 run_time_5km_in_seconds = 118; @@ -197,8 +182,13 @@ message Profile { } optional CyclingOrganization cycling_organization = 123; optional string f124 = 124; /* org name? */ - optional int32 f125 = 125; //? 0 - /* 126 ? */ + enum ActivityPrivacyType { + PUBLIC = 0; + PRIVATE = 1; + FRIENDS = 2; + } + optional ActivityPrivacyType default_activity_privacy = 125; + optional bool connected_to_runtastic = 126; repeated PropertyChange property_changes = 127; } diff --git a/protobuf/profile_pb2.py b/protobuf/profile_pb2.py index 141724a..962ed02 100644 --- a/protobuf/profile_pb2.py +++ b/protobuf/profile_pb2.py @@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rprofile.proto\"\xd7\x1d\n\x07Profile\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08world_id\x18\x02 \x01(\x03\x12\r\n\x05\x65mail\x18\x03 \x01(\t\x12\x12\n\nfirst_name\x18\x04 \x01(\t\x12\x11\n\tlast_name\x18\x05 \x01(\t\x12\x0f\n\x07is_male\x18\x06 \x01(\x08\x12\n\n\x02\x66\x37\x18\x07 \x01(\t\x12\x17\n\x0fweight_in_grams\x18\t \x01(\r\x12\x0b\n\x03\x66tp\x18\n \x01(\r\x12\x0b\n\x03\x66\x31\x31\x18\x0b \x01(\r\x12\x11\n\tbody_type\x18\x0c \x01(\r\x12\x11\n\thair_type\x18\r \x01(\r\x12\x18\n\x10\x66\x61\x63ial_hair_type\x18\x0e \x01(\r\x12\x18\n\x10ride_helmet_type\x18\x0f \x01(\r\x12\x14\n\x0cglasses_type\x18\x10 \x01(\r\x12\x17\n\x0fride_shoes_type\x18\x11 \x01(\r\x12\x17\n\x0fride_socks_type\x18\x12 \x01(\r\x12\x13\n\x0bride_gloves\x18\x13 \x01(\r\x12\x13\n\x0bride_jersey\x18\x14 \x01(\x07\x12\x0b\n\x03\x66\x32\x31\x18\x15 \x01(\x07\x12\x13\n\x0b\x62ike_wheel1\x18\x16 \x01(\x07\x12\x13\n\x0b\x62ike_wheel2\x18\x17 \x01(\x07\x12\x12\n\nbike_frame\x18\x18 \x01(\x07\x12\x0b\n\x03\x66\x32\x35\x18\x19 \x01(\x07\x12\x0b\n\x03\x66\x32\x36\x18\x1a \x01(\x07\x12\x19\n\x11\x62ike_frame_colour\x18\x1b \x01(\x06\x12\x0b\n\x03\x66\x32\x38\x18\x1c \x01(\x06\x12\x0b\n\x03\x66\x32\x39\x18\x1d \x01(\x06\x12\x0b\n\x03\x66\x33\x30\x18\x1e \x01(\x06\x12\x0b\n\x03\x66\x33\x31\x18\x1f \x01(\x06\x12\x0b\n\x03\x66\x33\x32\x18 \x01(\x06\x12\x16\n\x0e\x63hallenge_info\x18! \x01(\x0c\x12\x14\n\x0c\x63ountry_code\x18\" \x01(\r\x12 \n\x18total_distance_in_meters\x18# \x01(\r\x12 \n\x18\x65levation_gain_in_meters\x18$ \x01(\r\x12\x1e\n\x16time_ridden_in_minutes\x18% \x01(\r\x12\x1b\n\x13total_in_kom_jersey\x18& \x01(\r\x12!\n\x19total_in_sprinters_jersey\x18\' \x01(\r\x12\x1e\n\x16total_in_orange_jersey\x18( \x01(\r\x12\x18\n\x10total_watt_hours\x18) \x01(\r\x12\x1d\n\x15height_in_millimeters\x18* \x01(\r\x12\x0b\n\x03\x64ob\x18+ \x01(\t\x12\x16\n\x0emax_heart_rate\x18, \x01(\r\x12\x1b\n\x13\x63onnected_to_strava\x18- \x01(\x08\x12\x10\n\x08total_xp\x18. \x01(\r\x12\x18\n\x10total_gold_drops\x18/ \x01(\r\x12(\n\x0bplayer_type\x18\x30 \x01(\x0e\x32\x13.Profile.PlayerType\x12\x19\n\x11\x61\x63hievement_level\x18\x31 \x01(\r\x12\x12\n\nuse_metric\x18\x32 \x01(\x08\x12\x0b\n\x03\x66\x35\x31\x18\x33 \x01(\x08\x12\x14\n\x0cpower_source\x18\x34 \x01(\r\x12\x0b\n\x03\x66\x35\x33\x18\x35 \x01(\r\x12\x0b\n\x03\x66\x35\x34\x18\x36 \x01(\r\x12\x0b\n\x03\x61ge\x18\x37 \x01(\r\x12\x0b\n\x03\x66\x35\x36\x18\x38 \x01(\x07\x12\x0b\n\x03\x66\x35\x37\x18\x39 \x01(\r\x12\x18\n\x10large_avatar_url\x18: \x01(\t\x12\x0b\n\x03\x66\x35\x39\x18; \x01(\x06\x12)\n\x0c\x65ntitlements\x18< \x03(\x0b\x32\x13.ProfileEntitlement\x12*\n\x0csocial_facts\x18= \x01(\x0b\x32\x14.Profile.SocialFacts\x12$\n\rfollow_status\x18> \x01(\x0e\x32\r.FollowStatus\x12#\n\x1b\x63onnected_to_training_peaks\x18? \x01(\x08\x12 \n\x18\x63onnected_to_todays_plan\x18@ \x01(\x08\x12\x32\n\x10\x65nrolled_program\x18\x41 \x01(\x0e\x32\x18.Profile.EnrolledProgram\x12\x0b\n\x03\x66\x36\x36\x18\x42 \x01(\t\x12\x0b\n\x03\x66\x36\x37\x18\x43 \x01(\r\x12\x16\n\x0erun_shirt_type\x18\x44 \x01(\x07\x12\x17\n\x0frun_shorts_type\x18\x45 \x01(\x07\x12\x16\n\x0erun_shoes_type\x18\x46 \x01(\x07\x12\x16\n\x0erun_socks_type\x18G \x01(\x07\x12\x17\n\x0frun_helmet_type\x18H \x01(\x07\x12\x0b\n\x03\x66\x37\x33\x18I \x01(\x07\x12\x1a\n\x12total_run_distance\x18J \x01(\r\x12#\n\x1btotal_run_experience_points\x18K \x01(\r\x12\x0b\n\x03\x66\x37\x36\x18L \x01(\x07\x12\x0b\n\x03\x66\x37\x37\x18M \x01(\x07\x12\x0b\n\x03\x66\x37\x38\x18N \x01(\x07\x12\x0b\n\x03\x66\x37\x39\x18O \x01(\x07\x12\x0b\n\x03\x66\x38\x30\x18P \x01(\r\x12\x0b\n\x03\x66\x38\x31\x18Q \x01(\r\x12\x1a\n\x03\x66\x38\x32\x18R \x01(\x0b\x32\r.Subscription\x12\x1d\n\x15mix_panel_distinct_id\x18S \x01(\t\x12\x1d\n\x15run_achievement_level\x18T \x01(\r\x12\x0b\n\x03\x66\x38\x35\x18U \x01(\r\x12\x1d\n\x05sport\x18V \x01(\x0e\x32\x0e.Profile.Sport\x12\x0b\n\x03\x66\x38\x37\x18W \x01(\r\x12!\n\x19\x63onnected_to_under_armour\x18X \x01(\x08\x12\x1a\n\x12preferred_language\x18Y \x01(\t\x12\x13\n\x0bhair_colour\x18Z \x01(\r\x12\x1a\n\x12\x66\x61\x63ial_hair_colour\x18[ \x01(\r\x12\x0b\n\x03\x66\x39\x32\x18\\ \x01(\r\x12\x0b\n\x03\x66\x39\x33\x18] \x01(\r\x12\x19\n\x11run_shorts_length\x18^ \x01(\r\x12\x0b\n\x03\x66\x39\x35\x18_ \x01(\r\x12\x18\n\x10run_socks_length\x18` \x01(\r\x12\x0b\n\x03\x66\x39\x37\x18\x61 \x01(\r\x12\x19\n\x11ride_socks_length\x18\x62 \x01(\r\x12\x0b\n\x03\x66\x39\x39\x18\x63 \x01(\r\x12\x0c\n\x04\x66\x31\x30\x30\x18\x64 \x01(\r\x12\x0c\n\x04\x66\x31\x30\x31\x18\x65 \x01(\r\x12\x0c\n\x04\x66\x31\x30\x32\x18\x66 \x01(\r\x12\x0c\n\x04\x66\x31\x30\x33\x18g \x01(\r\x12\x0c\n\x04\x66\x31\x30\x34\x18h \x01(\r\x12\x0c\n\x04\x66\x31\x30\x35\x18i \x01(\x08\x12\x1b\n\x13\x63onnected_to_fitbit\x18j \x01(\x08\x12\x0c\n\x04\x66\x31\x30\x37\x18k \x03(\x0c\x12\x1c\n\x14launched_game_client\x18l \x01(\t\x12\x1b\n\x13\x63urrent_activity_id\x18m \x01(\x03\x12\x1b\n\x13\x63onnected_to_garmin\x18n \x01(\x08\x12$\n\tremainder\x18o \x03(\x0b\x32\x11.Profile.Reminder\x12\x0c\n\x04\x66\x31\x31\x32\x18p \x01(\x08\x12&\n\x12private_attributes\x18q \x03(\x0b\x32\n.Attribute\x12%\n\x11public_attributes\x18r \x03(\x0b\x32\n.Attribute\x12\x0c\n\x04\x66\x31\x31\x35\x18s \x01(\x05\x12\x0c\n\x04\x66\x31\x31\x36\x18t \x01(\x03\x12\x1f\n\x17run_time_1mi_in_seconds\x18u \x01(\x05\x12\x1f\n\x17run_time_5km_in_seconds\x18v \x01(\x05\x12 \n\x18run_time_10km_in_seconds\x18w \x01(\x05\x12)\n!run_time_half_marathon_in_seconds\x18x \x01(\x05\x12)\n!run_time_full_marathon_in_seconds\x18y \x01(\x05\x12\x0c\n\x04\x66\x31\x32\x32\x18z \x01(\x05\x12:\n\x14\x63ycling_organization\x18{ \x01(\x0e\x32\x1c.Profile.CyclingOrganization\x12\x0c\n\x04\x66\x31\x32\x34\x18| \x01(\t\x12\x0c\n\x04\x66\x31\x32\x35\x18} \x01(\x05\x12)\n\x10property_changes\x18\x7f \x03(\x0b\x32\x0f.PropertyChange\x1a\xa7\x02\n\x0bSocialFacts\x12\x12\n\nprofile_id\x18\x01 \x01(\x03\x12\x17\n\x0f\x66ollowers_count\x18\x02 \x01(\x05\x12\x17\n\x0f\x66ollowees_count\x18\x03 \x01(\x05\x12\x31\n)followees_in_common_with_logged_in_player\x18\x04 \x01(\x05\x12:\n#follower_status_of_logged_in_player\x18\x05 \x01(\x0e\x32\r.FollowStatus\x12:\n#followee_status_of_logged_in_player\x18\x06 \x01(\x0e\x32\r.FollowStatus\x12\'\n\x1fis_favorite_of_logged_in_player\x18\x07 \x01(\x08\x1a\x96\x01\n\x08Reminder\x12\n\n\x02\x66\x31\x18\x01 \x01(\x03\x12\n\n\x02\x66\x32\x18\x02 \x01(\t\x12\n\n\x02\x66\x33\x18\x03 \x01(\x03\x12.\n\x02\x66\x34\x18\x04 \x03(\x0b\x32\".Profile.Reminder.ReminderProperty\x1a\x36\n\x10ReminderProperty\x12\n\n\x02\x66\x31\x18\x01 \x01(\x03\x12\n\n\x02\x66\x32\x18\x02 \x01(\t\x12\n\n\x02\x66\x33\x18\x03 \x01(\t\"\x9f\x01\n\nPlayerType\x12\x0f\n\x0bPLAYERTYPE0\x10\x00\x12\n\n\x06NORMAL\x10\x01\x12\x0f\n\x0bPRO_CYCLIST\x10\x02\x12\x0f\n\x0bZWIFT_STAFF\x10\x03\x12\x0e\n\nAMBASSADOR\x10\x04\x12\x0c\n\x08VERIFIED\x10\x05\x12\x07\n\x03ZED\x10\x06\x12\x07\n\x03ZAC\x10\x07\x12\x12\n\x0ePRO_TRIATHLETE\x10\x08\x12\x0e\n\nPRO_RUNNER\x10\t\"|\n\x0f\x45nrolledProgram\x12\x14\n\x10\x45NROLLEDPROGRAM0\x10\x00\x12\x11\n\rZWIFT_ACADEMY\x10\x01\x12\x14\n\x10\x45NROLLEDPROGRAM2\x10\x02\x12\x14\n\x10\x45NROLLEDPROGRAM3\x10\x03\x12\x14\n\x10\x45NROLLEDPROGRAM4\x10\x04\"E\n\x05Sport\x12\x0b\n\x07\x43YCLING\x10\x00\x12\x0b\n\x07RUNNING\x10\x01\x12\n\n\x06ROWING\x10\x02\x12\n\n\x06SPORT3\x10\x03\x12\n\n\x06SPORT4\x10\x04\"w\n\x13\x43yclingOrganization\x12\x16\n\x12NO_CYCLING_LICENSE\x10\x00\x12\x18\n\x14\x43YCLING_SOUTH_AFRICA\x10\x01\x12\x15\n\x11\x43YCLING_AUSTRALIA\x10\x02\x12\x17\n\x13\x43YCLING_NEW_ZEALAND\x10\x03\"&\n\x08Profiles\x12\x1a\n\x08profiles\x18\x01 \x03(\x0b\x32\x08.Profile\"\xa3\x05\n\x12ProfileEntitlement\x12\x31\n\x04type\x18\x01 \x01(\x0e\x32#.ProfileEntitlement.EntitlementType\x12\n\n\x02\x66\x32\x18\x02 \x01(\x03\x12\x37\n\x01\x63\x18\x03 \x01(\x0e\x32,.ProfileEntitlement.ProfileEntitlementStatus\x12\n\n\x02\x66\x34\x18\x04 \x01(\t\x12\n\n\x02\x66\x35\x18\x05 \x01(\r\x12\n\n\x02\x66\x36\x18\x06 \x01(\r\x12\n\n\x02\x66\x37\x18\x07 \x01(\r\x12\n\n\x02\x66\x38\x18\x08 \x01(\r\x12\n\n\x02\x66\x39\x18\t \x01(\r\x12\x0b\n\x03\x66\x31\x30\x18\n \x01(\t\x12.\n\x08platform\x18\x0b \x01(\x0e\x32\x1c.ProfileEntitlement.Platform\x12\x0b\n\x03\x66\x31\x32\x18\x0c \x01(\r\x12\x0b\n\x03\x66\x31\x33\x18\r \x01(\x08\x12\x0b\n\x03\x66\x31\x34\x18\x0e \x03(\r\"L\n\x0f\x45ntitlementType\x12\x14\n\x10\x45NTITLEMENTTYPE0\x10\x00\x12\x08\n\x04RIDE\x10\x01\x12\x07\n\x03RUN\x10\x02\x12\x07\n\x03ROW\x10\x03\x12\x07\n\x03USE\x10\x04\"\x91\x01\n\x18ProfileEntitlementStatus\x12\x16\n\x12\x45NTITLEMENTSTATUS0\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06\x41\x43TIVE\x10\x02\x12\x0c\n\x08\x43\x41NCELED\x10\x03\x12\x0c\n\x08INACTIVE\x10\x04\x12(\n$APPLIED_AS_SUBSCRIPTION_TRIAL_PERIOD\x10\x05\"\x86\x01\n\x08Platform\x12\x10\n\x0cPLATFORM_OSX\x10\x00\x12\x0f\n\x0bPLATFORM_PC\x10\x01\x12\x10\n\x0cPLATFORM_IOS\x10\x02\x12\x14\n\x10PLATFORM_ANDROID\x10\x03\x12\x11\n\rPLATFORM_TVOS\x10\x04\x12\r\n\tPLATFORM5\x10\x05\x12\r\n\tPLATFORM6\x10\x06\"\xcc\x02\n\x0cSubscription\x12&\n\x07gateway\x18\x01 \x01(\x0e\x32\x15.Subscription.Gateway\x12\x30\n\x06status\x18\x02 \x01(\x0e\x32 .Subscription.SubscriptionStatus\"#\n\x07Gateway\x12\r\n\tBRAINTREE\x10\x00\x12\t\n\x05\x41PPLE\x10\x01\"\xbc\x01\n\x12SubscriptionStatus\x12\x07\n\x03NEW\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06\x41\x43TIVE\x10\x02\x12\x0c\n\x08\x43\x41NCELED\x10\x03\x12\x0c\n\x08PAST_DUE\x10\x04\x12\x0b\n\x07PENDING\x10\x05\x12\x0c\n\x08SUBERROR\x10\x06\x12\x10\n\x0cUNRECOGNIZED\x10\x07\x12\x0b\n\x07UNKNOWN\x10\x08\x12\x1f\n\x1b\x41\x43TIVE_WITH_PAYMENT_FAILURE\x10\t\x12\r\n\tABANDONED\x10\n\"\x96\x01\n\x0ePropertyChange\x12)\n\rproperty_name\x18\x01 \x02(\x0e\x32\x12.PropertyChange.Id\x12\x14\n\x0c\x63hange_count\x18\x02 \x01(\x05\x12\x13\n\x0bmax_changes\x18\x03 \x01(\x05\".\n\x02Id\x12\t\n\x05TYPE0\x10\x00\x12\x11\n\rDATE_OF_BIRTH\x10\x01\x12\n\n\x06GENDER\x10\x02\"X\n\tAttribute\x12\n\n\x02id\x18\x01 \x02(\x05\x12\x14\n\x0cnumber_value\x18\x02 \x01(\x04\x12\x13\n\x0b\x66loat_value\x18\x03 \x01(\x02\x12\x14\n\x0cstring_value\x18\x05 \x01(\t*\x9e\x01\n\x0c\x46ollowStatus\x12\x11\n\rFOLLOWSTATUS0\x10\x00\x12\x0b\n\x07UNKNOWN\x10\x01\x12\x16\n\x12REQUESTS_TO_FOLLOW\x10\x02\x12\x10\n\x0cIS_FOLLOWING\x10\x03\x12\x15\n\x11HAS_BEEN_DECLINED\x10\x07\x12\x0e\n\nIS_BLOCKED\x10\x04\x12\x13\n\x0fNO_RELATIONSHIP\x10\x05\x12\x08\n\x04SELF\x10\x06') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rprofile.proto\"\xaa\x1f\n\x07Profile\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08world_id\x18\x02 \x01(\x03\x12\r\n\x05\x65mail\x18\x03 \x01(\t\x12\x12\n\nfirst_name\x18\x04 \x01(\t\x12\x11\n\tlast_name\x18\x05 \x01(\t\x12\x0f\n\x07is_male\x18\x06 \x01(\x08\x12\n\n\x02\x66\x37\x18\x07 \x01(\t\x12\x17\n\x0fweight_in_grams\x18\t \x01(\r\x12\x0b\n\x03\x66tp\x18\n \x01(\r\x12\x0b\n\x03\x66\x31\x31\x18\x0b \x01(\r\x12\x11\n\tbody_type\x18\x0c \x01(\r\x12\x11\n\thair_type\x18\r \x01(\r\x12\x18\n\x10\x66\x61\x63ial_hair_type\x18\x0e \x01(\r\x12\x18\n\x10ride_helmet_type\x18\x0f \x01(\r\x12\x14\n\x0cglasses_type\x18\x10 \x01(\r\x12\x17\n\x0fride_shoes_type\x18\x11 \x01(\r\x12\x17\n\x0fride_socks_type\x18\x12 \x01(\r\x12\x13\n\x0bride_gloves\x18\x13 \x01(\r\x12\x13\n\x0bride_jersey\x18\x14 \x01(\x07\x12\x0b\n\x03\x66\x32\x31\x18\x15 \x01(\x07\x12\x13\n\x0b\x62ike_wheel1\x18\x16 \x01(\x07\x12\x13\n\x0b\x62ike_wheel2\x18\x17 \x01(\x07\x12\x12\n\nbike_frame\x18\x18 \x01(\x07\x12\x0b\n\x03\x66\x32\x35\x18\x19 \x01(\x07\x12\x0b\n\x03\x66\x32\x36\x18\x1a \x01(\x07\x12\x19\n\x11\x62ike_frame_colour\x18\x1b \x01(\x06\x12\x0b\n\x03\x66\x32\x38\x18\x1c \x01(\x06\x12\x0b\n\x03\x66\x32\x39\x18\x1d \x01(\x06\x12\x0b\n\x03\x66\x33\x30\x18\x1e \x01(\x06\x12\x0b\n\x03\x66\x33\x31\x18\x1f \x01(\x06\x12\x0b\n\x03\x66\x33\x32\x18 \x01(\x06\x12\x16\n\x0e\x63hallenge_info\x18! \x01(\x0c\x12\x14\n\x0c\x63ountry_code\x18\" \x01(\r\x12 \n\x18total_distance_in_meters\x18# \x01(\r\x12 \n\x18\x65levation_gain_in_meters\x18$ \x01(\r\x12\x1e\n\x16time_ridden_in_minutes\x18% \x01(\r\x12\x1b\n\x13total_in_kom_jersey\x18& \x01(\r\x12!\n\x19total_in_sprinters_jersey\x18\' \x01(\r\x12\x1e\n\x16total_in_orange_jersey\x18( \x01(\r\x12\x18\n\x10total_watt_hours\x18) \x01(\r\x12\x1d\n\x15height_in_millimeters\x18* \x01(\r\x12\x0b\n\x03\x64ob\x18+ \x01(\t\x12\x16\n\x0emax_heart_rate\x18, \x01(\r\x12\x1b\n\x13\x63onnected_to_strava\x18- \x01(\x08\x12\x10\n\x08total_xp\x18. \x01(\r\x12\x18\n\x10total_gold_drops\x18/ \x01(\r\x12(\n\x0bplayer_type\x18\x30 \x01(\x0e\x32\x13.Profile.PlayerType\x12\x19\n\x11\x61\x63hievement_level\x18\x31 \x01(\r\x12\x12\n\nuse_metric\x18\x32 \x01(\x08\x12\x0b\n\x03\x66\x35\x31\x18\x33 \x01(\x08\x12\x1a\n\x12power_source_model\x18\x34 \x01(\r\x12\x0b\n\x03\x66\x35\x33\x18\x35 \x01(\r\x12\x0b\n\x03\x66\x35\x34\x18\x36 \x01(\r\x12\x0b\n\x03\x61ge\x18\x37 \x01(\r\x12\x0b\n\x03\x66\x35\x36\x18\x38 \x01(\x07\x12\x0b\n\x03\x66\x35\x37\x18\x39 \x01(\r\x12\x18\n\x10large_avatar_url\x18: \x01(\t\x12\x14\n\x0cprivacy_bits\x18; \x01(\x06\x12)\n\x0c\x65ntitlements\x18< \x03(\x0b\x32\x13.ProfileEntitlement\x12*\n\x0csocial_facts\x18= \x01(\x0b\x32\x14.Profile.SocialFacts\x12$\n\rfollow_status\x18> \x01(\x0e\x32\r.FollowStatus\x12#\n\x1b\x63onnected_to_training_peaks\x18? \x01(\x08\x12 \n\x18\x63onnected_to_todays_plan\x18@ \x01(\x08\x12\x32\n\x10\x65nrolled_program\x18\x41 \x01(\x0e\x32\x18.Profile.EnrolledProgram\x12\x0b\n\x03\x66\x36\x36\x18\x42 \x01(\t\x12\x0b\n\x03\x66\x36\x37\x18\x43 \x01(\r\x12\x16\n\x0erun_shirt_type\x18\x44 \x01(\x07\x12\x17\n\x0frun_shorts_type\x18\x45 \x01(\x07\x12\x16\n\x0erun_shoes_type\x18\x46 \x01(\x07\x12\x16\n\x0erun_socks_type\x18G \x01(\x07\x12\x17\n\x0frun_helmet_type\x18H \x01(\x07\x12\x0b\n\x03\x66\x37\x33\x18I \x01(\x07\x12\x1a\n\x12total_run_distance\x18J \x01(\r\x12#\n\x1btotal_run_experience_points\x18K \x01(\r\x12\x0b\n\x03\x66\x37\x36\x18L \x01(\x07\x12\x0b\n\x03\x66\x37\x37\x18M \x01(\x07\x12\x0b\n\x03\x66\x37\x38\x18N \x01(\x07\x12\x0b\n\x03\x66\x37\x39\x18O \x01(\x07\x12\x0b\n\x03\x66\x38\x30\x18P \x01(\r\x12\x0b\n\x03\x66\x38\x31\x18Q \x01(\r\x12\x1a\n\x03\x66\x38\x32\x18R \x01(\x0b\x32\r.Subscription\x12\x1d\n\x15mix_panel_distinct_id\x18S \x01(\t\x12\x1d\n\x15run_achievement_level\x18T \x01(\r\x12!\n\x19total_run_time_in_minutes\x18U \x01(\r\x12\x1d\n\x05sport\x18V \x01(\x0e\x32\x0e.Profile.Sport\x12\x0b\n\x03\x66\x38\x37\x18W \x01(\r\x12!\n\x19\x63onnected_to_under_armour\x18X \x01(\x08\x12\x1a\n\x12preferred_language\x18Y \x01(\t\x12\x13\n\x0bhair_colour\x18Z \x01(\r\x12\x1a\n\x12\x66\x61\x63ial_hair_colour\x18[ \x01(\r\x12\x0b\n\x03\x66\x39\x32\x18\\ \x01(\r\x12\x0b\n\x03\x66\x39\x33\x18] \x01(\r\x12\x19\n\x11run_shorts_length\x18^ \x01(\r\x12\x0b\n\x03\x66\x39\x35\x18_ \x01(\r\x12\x18\n\x10run_socks_length\x18` \x01(\r\x12\x0b\n\x03\x66\x39\x37\x18\x61 \x01(\r\x12\x19\n\x11ride_socks_length\x18\x62 \x01(\r\x12\x0b\n\x03\x66\x39\x39\x18\x63 \x01(\r\x12\x0c\n\x04\x66\x31\x30\x30\x18\x64 \x01(\r\x12\x0c\n\x04\x66\x31\x30\x31\x18\x65 \x01(\r\x12\x0c\n\x04\x66\x31\x30\x32\x18\x66 \x01(\r\x12\x0c\n\x04\x66\x31\x30\x33\x18g \x01(\r\x12\x0c\n\x04\x66\x31\x30\x34\x18h \x01(\r\x12\x1d\n\x15\x63onnected_to_withings\x18i \x01(\x08\x12\x1b\n\x13\x63onnected_to_fitbit\x18j \x01(\x08\x12\x0c\n\x04\x66\x31\x30\x37\x18k \x03(\x0c\x12\x1c\n\x14launched_game_client\x18l \x01(\t\x12\x1b\n\x13\x63urrent_activity_id\x18m \x01(\x03\x12\x1b\n\x13\x63onnected_to_garmin\x18n \x01(\x08\x12$\n\tremainder\x18o \x03(\x0b\x32\x11.Profile.Reminder\x12\x0c\n\x04\x66\x31\x31\x32\x18p \x01(\x08\x12&\n\x12private_attributes\x18q \x03(\x0b\x32\n.Attribute\x12%\n\x11public_attributes\x18r \x03(\x0b\x32\n.Attribute\x12\x1a\n\x12total_run_calories\x18s \x01(\x05\x12\x0c\n\x04\x66\x31\x31\x36\x18t \x01(\x03\x12\x1f\n\x17run_time_1mi_in_seconds\x18u \x01(\x05\x12\x1f\n\x17run_time_5km_in_seconds\x18v \x01(\x05\x12 \n\x18run_time_10km_in_seconds\x18w \x01(\x05\x12)\n!run_time_half_marathon_in_seconds\x18x \x01(\x05\x12)\n!run_time_full_marathon_in_seconds\x18y \x01(\x05\x12\x0c\n\x04\x66\x31\x32\x32\x18z \x01(\x05\x12:\n\x14\x63ycling_organization\x18{ \x01(\x0e\x32\x1c.Profile.CyclingOrganization\x12\x0c\n\x04\x66\x31\x32\x34\x18| \x01(\t\x12>\n\x18\x64\x65\x66\x61ult_activity_privacy\x18} \x01(\x0e\x32\x1c.Profile.ActivityPrivacyType\x12\x1e\n\x16\x63onnected_to_runtastic\x18~ \x01(\x08\x12)\n\x10property_changes\x18\x7f \x03(\x0b\x32\x0f.PropertyChange\x1a\xa7\x02\n\x0bSocialFacts\x12\x12\n\nprofile_id\x18\x01 \x01(\x03\x12\x17\n\x0f\x66ollowers_count\x18\x02 \x01(\x05\x12\x17\n\x0f\x66ollowees_count\x18\x03 \x01(\x05\x12\x31\n)followees_in_common_with_logged_in_player\x18\x04 \x01(\x05\x12:\n#follower_status_of_logged_in_player\x18\x05 \x01(\x0e\x32\r.FollowStatus\x12:\n#followee_status_of_logged_in_player\x18\x06 \x01(\x0e\x32\r.FollowStatus\x12\'\n\x1fis_favorite_of_logged_in_player\x18\x07 \x01(\x08\x1a\x96\x01\n\x08Reminder\x12\n\n\x02\x66\x31\x18\x01 \x01(\x03\x12\n\n\x02\x66\x32\x18\x02 \x01(\t\x12\n\n\x02\x66\x33\x18\x03 \x01(\x03\x12.\n\x02\x66\x34\x18\x04 \x03(\x0b\x32\".Profile.Reminder.ReminderProperty\x1a\x36\n\x10ReminderProperty\x12\n\n\x02\x66\x31\x18\x01 \x01(\x03\x12\n\n\x02\x66\x32\x18\x02 \x01(\t\x12\n\n\x02\x66\x33\x18\x03 \x01(\t\"\x9f\x01\n\nPlayerType\x12\x0f\n\x0bPLAYERTYPE0\x10\x00\x12\n\n\x06NORMAL\x10\x01\x12\x0f\n\x0bPRO_CYCLIST\x10\x02\x12\x0f\n\x0bZWIFT_STAFF\x10\x03\x12\x0e\n\nAMBASSADOR\x10\x04\x12\x0c\n\x08VERIFIED\x10\x05\x12\x07\n\x03ZED\x10\x06\x12\x07\n\x03ZAC\x10\x07\x12\x12\n\x0ePRO_TRIATHLETE\x10\x08\x12\x0e\n\nPRO_RUNNER\x10\t\"|\n\x0f\x45nrolledProgram\x12\x14\n\x10\x45NROLLEDPROGRAM0\x10\x00\x12\x11\n\rZWIFT_ACADEMY\x10\x01\x12\x14\n\x10\x45NROLLEDPROGRAM2\x10\x02\x12\x14\n\x10\x45NROLLEDPROGRAM3\x10\x03\x12\x14\n\x10\x45NROLLEDPROGRAM4\x10\x04\"E\n\x05Sport\x12\x0b\n\x07\x43YCLING\x10\x00\x12\x0b\n\x07RUNNING\x10\x01\x12\n\n\x06ROWING\x10\x02\x12\n\n\x06SPORT3\x10\x03\x12\n\n\x06SPORT4\x10\x04\"w\n\x13\x43yclingOrganization\x12\x16\n\x12NO_CYCLING_LICENSE\x10\x00\x12\x18\n\x14\x43YCLING_SOUTH_AFRICA\x10\x01\x12\x15\n\x11\x43YCLING_AUSTRALIA\x10\x02\x12\x17\n\x13\x43YCLING_NEW_ZEALAND\x10\x03\";\n\x13\x41\x63tivityPrivacyType\x12\n\n\x06PUBLIC\x10\x00\x12\x0b\n\x07PRIVATE\x10\x01\x12\x0b\n\x07\x46RIENDS\x10\x02\"&\n\x08Profiles\x12\x1a\n\x08profiles\x18\x01 \x03(\x0b\x32\x08.Profile\"\xa3\x05\n\x12ProfileEntitlement\x12\x31\n\x04type\x18\x01 \x01(\x0e\x32#.ProfileEntitlement.EntitlementType\x12\n\n\x02\x66\x32\x18\x02 \x01(\x03\x12\x37\n\x01\x63\x18\x03 \x01(\x0e\x32,.ProfileEntitlement.ProfileEntitlementStatus\x12\n\n\x02\x66\x34\x18\x04 \x01(\t\x12\n\n\x02\x66\x35\x18\x05 \x01(\r\x12\n\n\x02\x66\x36\x18\x06 \x01(\r\x12\n\n\x02\x66\x37\x18\x07 \x01(\r\x12\n\n\x02\x66\x38\x18\x08 \x01(\r\x12\n\n\x02\x66\x39\x18\t \x01(\r\x12\x0b\n\x03\x66\x31\x30\x18\n \x01(\t\x12.\n\x08platform\x18\x0b \x01(\x0e\x32\x1c.ProfileEntitlement.Platform\x12\x0b\n\x03\x66\x31\x32\x18\x0c \x01(\r\x12\x0b\n\x03\x66\x31\x33\x18\r \x01(\x08\x12\x0b\n\x03\x66\x31\x34\x18\x0e \x03(\r\"L\n\x0f\x45ntitlementType\x12\x14\n\x10\x45NTITLEMENTTYPE0\x10\x00\x12\x08\n\x04RIDE\x10\x01\x12\x07\n\x03RUN\x10\x02\x12\x07\n\x03ROW\x10\x03\x12\x07\n\x03USE\x10\x04\"\x91\x01\n\x18ProfileEntitlementStatus\x12\x16\n\x12\x45NTITLEMENTSTATUS0\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06\x41\x43TIVE\x10\x02\x12\x0c\n\x08\x43\x41NCELED\x10\x03\x12\x0c\n\x08INACTIVE\x10\x04\x12(\n$APPLIED_AS_SUBSCRIPTION_TRIAL_PERIOD\x10\x05\"\x86\x01\n\x08Platform\x12\x10\n\x0cPLATFORM_OSX\x10\x00\x12\x0f\n\x0bPLATFORM_PC\x10\x01\x12\x10\n\x0cPLATFORM_IOS\x10\x02\x12\x14\n\x10PLATFORM_ANDROID\x10\x03\x12\x11\n\rPLATFORM_TVOS\x10\x04\x12\r\n\tPLATFORM5\x10\x05\x12\r\n\tPLATFORM6\x10\x06\"\xcc\x02\n\x0cSubscription\x12&\n\x07gateway\x18\x01 \x01(\x0e\x32\x15.Subscription.Gateway\x12\x30\n\x06status\x18\x02 \x01(\x0e\x32 .Subscription.SubscriptionStatus\"#\n\x07Gateway\x12\r\n\tBRAINTREE\x10\x00\x12\t\n\x05\x41PPLE\x10\x01\"\xbc\x01\n\x12SubscriptionStatus\x12\x07\n\x03NEW\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06\x41\x43TIVE\x10\x02\x12\x0c\n\x08\x43\x41NCELED\x10\x03\x12\x0c\n\x08PAST_DUE\x10\x04\x12\x0b\n\x07PENDING\x10\x05\x12\x0c\n\x08SUBERROR\x10\x06\x12\x10\n\x0cUNRECOGNIZED\x10\x07\x12\x0b\n\x07UNKNOWN\x10\x08\x12\x1f\n\x1b\x41\x43TIVE_WITH_PAYMENT_FAILURE\x10\t\x12\r\n\tABANDONED\x10\n\"\x96\x01\n\x0ePropertyChange\x12)\n\rproperty_name\x18\x01 \x02(\x0e\x32\x12.PropertyChange.Id\x12\x14\n\x0c\x63hange_count\x18\x02 \x01(\x05\x12\x13\n\x0bmax_changes\x18\x03 \x01(\x05\".\n\x02Id\x12\t\n\x05TYPE0\x10\x00\x12\x11\n\rDATE_OF_BIRTH\x10\x01\x12\n\n\x06GENDER\x10\x02\"X\n\tAttribute\x12\n\n\x02id\x18\x01 \x02(\x05\x12\x14\n\x0cnumber_value\x18\x02 \x01(\x04\x12\x13\n\x0b\x66loat_value\x18\x03 \x01(\x02\x12\x14\n\x0cstring_value\x18\x05 \x01(\t*\x9e\x01\n\x0c\x46ollowStatus\x12\x11\n\rFOLLOWSTATUS0\x10\x00\x12\x0b\n\x07UNKNOWN\x10\x01\x12\x16\n\x12REQUESTS_TO_FOLLOW\x10\x02\x12\x10\n\x0cIS_FOLLOWING\x10\x03\x12\x15\n\x11HAS_BEEN_DECLINED\x10\x07\x12\x0e\n\nIS_BLOCKED\x10\x04\x12\x13\n\x0fNO_RELATIONSHIP\x10\x05\x12\x08\n\x04SELF\x10\x06') _FOLLOWSTATUS = DESCRIPTOR.enum_types_by_name['FollowStatus'] FollowStatus = enum_type_wrapper.EnumTypeWrapper(_FOLLOWSTATUS) @@ -42,6 +42,7 @@ _PROFILE_PLAYERTYPE = _PROFILE.enum_types_by_name['PlayerType'] _PROFILE_ENROLLEDPROGRAM = _PROFILE.enum_types_by_name['EnrolledProgram'] _PROFILE_SPORT = _PROFILE.enum_types_by_name['Sport'] _PROFILE_CYCLINGORGANIZATION = _PROFILE.enum_types_by_name['CyclingOrganization'] +_PROFILE_ACTIVITYPRIVACYTYPE = _PROFILE.enum_types_by_name['ActivityPrivacyType'] _PROFILEENTITLEMENT_ENTITLEMENTTYPE = _PROFILEENTITLEMENT.enum_types_by_name['EntitlementType'] _PROFILEENTITLEMENT_PROFILEENTITLEMENTSTATUS = _PROFILEENTITLEMENT.enum_types_by_name['ProfileEntitlementStatus'] _PROFILEENTITLEMENT_PLATFORM = _PROFILEENTITLEMENT.enum_types_by_name['Platform'] @@ -117,44 +118,46 @@ _sym_db.RegisterMessage(Attribute) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _FOLLOWSTATUS._serialized_start=5116 - _FOLLOWSTATUS._serialized_end=5274 + _FOLLOWSTATUS._serialized_start=5327 + _FOLLOWSTATUS._serialized_end=5485 _PROFILE._serialized_start=18 - _PROFILE._serialized_end=3817 - _PROFILE_SOCIALFACTS._serialized_start=2889 - _PROFILE_SOCIALFACTS._serialized_end=3184 - _PROFILE_REMINDER._serialized_start=3187 - _PROFILE_REMINDER._serialized_end=3337 - _PROFILE_REMINDER_REMINDERPROPERTY._serialized_start=3283 - _PROFILE_REMINDER_REMINDERPROPERTY._serialized_end=3337 - _PROFILE_PLAYERTYPE._serialized_start=3340 - _PROFILE_PLAYERTYPE._serialized_end=3499 - _PROFILE_ENROLLEDPROGRAM._serialized_start=3501 - _PROFILE_ENROLLEDPROGRAM._serialized_end=3625 - _PROFILE_SPORT._serialized_start=3627 - _PROFILE_SPORT._serialized_end=3696 - _PROFILE_CYCLINGORGANIZATION._serialized_start=3698 - _PROFILE_CYCLINGORGANIZATION._serialized_end=3817 - _PROFILES._serialized_start=3819 - _PROFILES._serialized_end=3857 - _PROFILEENTITLEMENT._serialized_start=3860 - _PROFILEENTITLEMENT._serialized_end=4535 - _PROFILEENTITLEMENT_ENTITLEMENTTYPE._serialized_start=4174 - _PROFILEENTITLEMENT_ENTITLEMENTTYPE._serialized_end=4250 - _PROFILEENTITLEMENT_PROFILEENTITLEMENTSTATUS._serialized_start=4253 - _PROFILEENTITLEMENT_PROFILEENTITLEMENTSTATUS._serialized_end=4398 - _PROFILEENTITLEMENT_PLATFORM._serialized_start=4401 - _PROFILEENTITLEMENT_PLATFORM._serialized_end=4535 - _SUBSCRIPTION._serialized_start=4538 - _SUBSCRIPTION._serialized_end=4870 - _SUBSCRIPTION_GATEWAY._serialized_start=4644 - _SUBSCRIPTION_GATEWAY._serialized_end=4679 - _SUBSCRIPTION_SUBSCRIPTIONSTATUS._serialized_start=4682 - _SUBSCRIPTION_SUBSCRIPTIONSTATUS._serialized_end=4870 - _PROPERTYCHANGE._serialized_start=4873 - _PROPERTYCHANGE._serialized_end=5023 - _PROPERTYCHANGE_ID._serialized_start=4977 - _PROPERTYCHANGE_ID._serialized_end=5023 - _ATTRIBUTE._serialized_start=5025 - _ATTRIBUTE._serialized_end=5113 + _PROFILE._serialized_end=4028 + _PROFILE_SOCIALFACTS._serialized_start=3039 + _PROFILE_SOCIALFACTS._serialized_end=3334 + _PROFILE_REMINDER._serialized_start=3337 + _PROFILE_REMINDER._serialized_end=3487 + _PROFILE_REMINDER_REMINDERPROPERTY._serialized_start=3433 + _PROFILE_REMINDER_REMINDERPROPERTY._serialized_end=3487 + _PROFILE_PLAYERTYPE._serialized_start=3490 + _PROFILE_PLAYERTYPE._serialized_end=3649 + _PROFILE_ENROLLEDPROGRAM._serialized_start=3651 + _PROFILE_ENROLLEDPROGRAM._serialized_end=3775 + _PROFILE_SPORT._serialized_start=3777 + _PROFILE_SPORT._serialized_end=3846 + _PROFILE_CYCLINGORGANIZATION._serialized_start=3848 + _PROFILE_CYCLINGORGANIZATION._serialized_end=3967 + _PROFILE_ACTIVITYPRIVACYTYPE._serialized_start=3969 + _PROFILE_ACTIVITYPRIVACYTYPE._serialized_end=4028 + _PROFILES._serialized_start=4030 + _PROFILES._serialized_end=4068 + _PROFILEENTITLEMENT._serialized_start=4071 + _PROFILEENTITLEMENT._serialized_end=4746 + _PROFILEENTITLEMENT_ENTITLEMENTTYPE._serialized_start=4385 + _PROFILEENTITLEMENT_ENTITLEMENTTYPE._serialized_end=4461 + _PROFILEENTITLEMENT_PROFILEENTITLEMENTSTATUS._serialized_start=4464 + _PROFILEENTITLEMENT_PROFILEENTITLEMENTSTATUS._serialized_end=4609 + _PROFILEENTITLEMENT_PLATFORM._serialized_start=4612 + _PROFILEENTITLEMENT_PLATFORM._serialized_end=4746 + _SUBSCRIPTION._serialized_start=4749 + _SUBSCRIPTION._serialized_end=5081 + _SUBSCRIPTION_GATEWAY._serialized_start=4855 + _SUBSCRIPTION_GATEWAY._serialized_end=4890 + _SUBSCRIPTION_SUBSCRIPTIONSTATUS._serialized_start=4893 + _SUBSCRIPTION_SUBSCRIPTIONSTATUS._serialized_end=5081 + _PROPERTYCHANGE._serialized_start=5084 + _PROPERTYCHANGE._serialized_end=5234 + _PROPERTYCHANGE_ID._serialized_start=5188 + _PROPERTYCHANGE_ID._serialized_end=5234 + _ATTRIBUTE._serialized_start=5236 + _ATTRIBUTE._serialized_end=5324 # @@protoc_insertion_point(module_scope) diff --git a/storage/profile_test.py b/storage/profile_test.py index 0880a11..a0cc4b4 100644 --- a/storage/profile_test.py +++ b/storage/profile_test.py @@ -10,7 +10,8 @@ app = Flask(__name__) profile = profile_pb2.Profile() #profile_file = '../../zoffline-helper/profile.bin-sul' #profile_file = '../../zoffline-helper/profile.bin' -profile_file = '../storage/5/profile.bin' +#profile_file = '../storage/2/profile.bin' +profile_file = '../storage/profile4357549.bin' with open(profile_file, 'rb') as fd: profile.ParseFromString(fd.read()) @@ -42,8 +43,32 @@ def copyAttributes(jprofile, jprofileFull, src): dest[di['id']] = di[v] jprofile[src] = dest +def powerSourceModelToStr(val): + if (val == 1): + return "Power Meter" + else: + return "zPower" + +def privacy(profile): + privacy_bits = jsf(profile, 'privacy_bits', 0) + return {"approvalRequired": bool(privacy_bits & 1), "displayWeight": bool(privacy_bits & 4), "minor": bool(privacy_bits & 2), "privateMessaging": bool(privacy_bits & 8), "defaultFitnessDataPrivacy": bool(privacy_bits & 16), +"suppressFollowerNotification": bool(privacy_bits & 32), "displayAge": not bool(privacy_bits & 64), "defaultActivityPrivacy": profile_pb2.Profile.ActivityPrivacyType.Name(jsv0(profile, 'default_activity_privacy'))} + 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(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"} +if True: + 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": privacy(profile), "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, 'total_run_time_in_minutes'), "totalRunExperiencePoints": jsv0(profile, 'total_run_experience_points'), "totalRunCalories": jsv0(profile, 'total_run_calories'), "totalGold": jsv0(profile, 'total_gold_drops'), +"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": jsb0(profile, 'connected_to_withings'), "connectedToRuntastic": jsb0(profile, 'connected_to_runtastic'), "connectedToZwiftPower": False, "powerSourceType": "Power Source", "powerSourceModel": powerSourceModelToStr(profile.power_source_model), "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 afa2717..82b2d11 100644 --- a/zwift_offline.py +++ b/zwift_offline.py @@ -21,6 +21,7 @@ from functools import wraps from io import BytesIO from shutil import copyfile from logging.handlers import RotatingFileHandler +from urllib.parse import unquote import jwt from flask import Flask, request, jsonify, redirect, render_template, url_for, flash, session, abort, make_response, send_file, send_from_directory @@ -1104,6 +1105,17 @@ def copyAttributes(jprofile, jprofileFull, src): dest[di['id']] = di[v] jprofile[src] = dest +def powerSourceModelToStr(val): + if (val == 1): + return "Power Meter" + else: + return "zPower" + +def privacy(profile): + privacy_bits = jsf(profile, 'privacy_bits', 0) + return {"approvalRequired": bool(privacy_bits & 1), "displayWeight": bool(privacy_bits & 4), "minor": bool(privacy_bits & 2), "privateMessaging": bool(privacy_bits & 8), "defaultFitnessDataPrivacy": bool(privacy_bits & 16), +"suppressFollowerNotification": bool(privacy_bits & 32), "displayAge": not bool(privacy_bits & 64), "defaultActivityPrivacy": profile_pb2.Profile.ActivityPrivacyType.Name(jsv0(profile, 'default_activity_privacy'))} + def do_api_profiles_me(is_json): profile_id = current_user.player_id if MULTIPLAYER: @@ -1162,13 +1174,19 @@ def do_api_profiles_me(is_json): if profile.dob != "": profile.age = age(datetime.datetime.strptime(profile.dob, "%m/%d/%Y")) jprofileFull = MessageToDict(profile) - privacy_file = '%s/%s/privacy.json' % (STORAGE_DIR, profile.id) - if not os.path.isfile(privacy_file): - jprivacy = {"approvalRequired": False, "displayWeight": True, "minor": False, "privateMessaging": False, "defaultFitnessDataPrivacy": False, "suppressFollowerNotification": False, "displayAge": True, "defaultActivityPrivacy": "PUBLIC"} - else: - with open(privacy_file, 'r') as fprivacy: - jprivacy = json.load(fprivacy) - 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": jprivacy, "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": privacy(profile), "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, 'total_run_time_in_minutes'), "totalRunExperiencePoints": jsv0(profile, 'total_run_experience_points'), "totalRunCalories": jsv0(profile, 'total_run_calories'), "totalGold": jsv0(profile, 'total_gold_drops'), +"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": jsb0(profile, 'connected_to_withings'), "connectedToRuntastic": jsb0(profile, 'connected_to_runtastic'), "connectedToZwiftPower": False, "powerSourceType": "Power Source", "powerSourceModel": powerSourceModelToStr(profile.power_source_model), "riding": False, "location": "", "publicId": "5a72e9b1-239f-435e-8757-af9467336b40", +"mixpanelDistinctId": "21304417-af2d-4c9b-8543-8ba7c0500e84"} copyAttributes(jprofile, jprofileFull, 'publicAttributes') copyAttributes(jprofile, jprofileFull, 'privateAttributes') #print (jsonify(jprofile).data.decode("utf-8")) @@ -1193,8 +1211,38 @@ def api_profiles_me_json(): @login_required def api_profiles_id_privacy(player_id): privacy_file = '%s/%s/privacy.json' % (STORAGE_DIR, player_id) + jp = request.get_json() with open(privacy_file, 'w', encoding='utf-8') as fprivacy: - fprivacy.write(json.dumps(request.get_json(), ensure_ascii=False)) + fprivacy.write(json.dumps(jp, ensure_ascii=False)) + #{"displayAge": false, "defaultActivityPrivacy": "PUBLIC", "approvalRequired": false, "privateMessaging": false, "defaultFitnessDataPrivacy": false} + profile_dir = '%s/%s' % (STORAGE_DIR, player_id) + profile = profile_pb2.Profile() + profile_file = '%s/profile.bin' % profile_dir + with open(profile_file, 'rb') as fd: + profile.ParseFromString(fd.read()) + profile.privacy_bits = 0 + if (jp["approvalRequired"]): + profile.privacy_bits += 1 + if ("displayWeight" in jp and jp["displayWeight"]): + profile.privacy_bits += 4 + if ("minor" in jp and jp["minor"]): + profile.privacy_bits += 2 + if (jp["privateMessaging"]): + profile.privacy_bits += 8 + if (jp["defaultFitnessDataPrivacy"]): + profile.privacy_bits += 16 + if ("suppressFollowerNotification" in jp and jp["suppressFollowerNotification"]): + profile.privacy_bits += 32 + if (not jp["displayAge"]): + profile.privacy_bits += 64 + defaultActivityPrivacy = jp["defaultActivityPrivacy"] + profile.default_activity_privacy = 0 #PUBLIC + if(defaultActivityPrivacy == "PRIVATE"): + profile.default_activity_privacy = 1 + if(defaultActivityPrivacy == "FRIENDS"): + profile.default_activity_privacy = 2 + with open(profile_file, 'wb') as fd: + fd.write(profile.SerializeToString()) return '', 200 @app.route('/api/search/profiles', methods=['POST']) @@ -1273,6 +1321,7 @@ def api_profiles_me_id(player_id): @jwt_to_session_cookie @login_required def api_profiles_id(player_id): + #print(request.__dict__) if not request.stream: return '', 400 if player_id == 0: