Added Favorites to geocache.db (needs rework)

and more
This commit is contained in:
2026-04-29 13:19:28 -04:00
parent c10d785bfa
commit e48c22e0f7
5 changed files with 263 additions and 36 deletions

View File

@@ -1,24 +1,24 @@
#LWP-Cookies-2.0 #LWP-Cookies-2.0
Set-Cookie3: dslang=US-EN; path="/"; domain=.apple.com; path_spec; secure; discard; HttpOnly=None; version=0 Set-Cookie3: dslang=US-EN; path="/"; domain=.apple.com; path_spec; secure; discard; HttpOnly=None; version=0
Set-Cookie3: site=USA; path="/"; domain=.apple.com; path_spec; secure; discard; HttpOnly=None; version=0 Set-Cookie3: site=USA; path="/"; domain=.apple.com; path_spec; secure; discard; HttpOnly=None; version=0
Set-Cookie3: acn01=KVgOa2TlSALDmkRBN3HjFqQsmjntJ3LJQtZC9wATSlL+oYci; path="/"; domain=.apple.com; path_spec; secure; expires="2027-04-21 18:02:51Z"; HttpOnly=None; version=0 Set-Cookie3: acn01=70L4mLhmweVoXyGsy5nJlIQubkrJOwRcyl3qLwAVJO5xpjKw; path="/"; domain=.apple.com; path_spec; secure; expires="2027-04-29 16:06:06Z"; HttpOnly=None; version=0
Set-Cookie3: aasp=97997103CCD7FEC9173190AED7457252EBCD7B770AB7B784C902761FC601C83B02A28C2DE1B84D51A690620FBBE43A9F53E20534400A5BABA174C06BCDF6D1239746712B62A97006E8A95F03A96A584A7185B1EB24404B0F03A152E9F46C23451139DEBF74FACF2C476512DC59E85823694E20CF535BBE50; path="/"; domain=.idmsa.apple.com; path_spec; secure; discard; HttpOnly=None; version=0 Set-Cookie3: aasp=3C2D0B45AFDCBAC81490E66E2DB79DD28298FB98A4E44381F64D4CFC4A677C6E4BE90E2B7F77BAFC992186F745E8A39EC5B52EE814BB65F1BA8137C80C973C9B657E1300A0E9C22BE32927B428866415AE2E3E66BA4541A67D8411C808E20F8797B807AEB5BDEDA05F2B6FF1306E59D4212F589D7028ED1B; path="/"; domain=.idmsa.apple.com; path_spec; secure; discard; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-UNIQUE-CLIENT-ID="\"BA==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; discard; version=0 Set-Cookie3: X-APPLE-UNIQUE-CLIENT-ID="\"BA==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; discard; version=0
Set-Cookie3: X-APPLE-WEBAUTH-LOGIN="\"v=1:t=BA==BST_IAAAAAAABLwIAAAAAGnnu8wRDmdzLmljbG91ZC5hdXRovQDEXUpbkZ6MgVpJex6704NeoKMirs7DTjQaMiLP3D7RDPPgRrN1eyRakxlhJwOczfTWOBtEP6_JywPTG3CmSA0RzajX5msyXsLEbn2K7IC-IF2NRP6-O8ACrZc8NLmZhrpYcMuYd7-cRNCfP9YrPhaLOOIYjQ~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; discard; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-LOGIN="\"v=1:t=BA==BST_IAAAAAAABLwIAAAAAGnyLG8RDmdzLmljbG91ZC5hdXRovQB9kwQUaVp5mcYpwvOxZ4GCnC3PL21rIb1KWfwqyYi3lai2xZjOlnV9toJ7ElKE2hRWdegjf6QPvLBIR3qtNxAV8sYd2zZVy7HQj1jd0bSMIj1lQH17O7vZ7UZ9V4sjGYCoYe1OO4jPyE8NLSEv-apjhUGiMg~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; discard; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-VALIDATE="\"v=1:t=BA==BST_IAAAAAAABLwIAAAAAGnnu8wRDmdzLmljbG91ZC5hdXRovQDEXUpbkZ6MgVpJex6704NeoKMirs7DTjQaMiLP3D7RDPPgRrN1eyRakxlhJwOczfTWOBtEP6_JywPTG3CmSA0RzajX5msyXsLEbn2K7IC-IHq8h87PbRbxm_5NFEGqbnrBegyo4fAVl3K0v8zi4ALPFmK-uw~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; discard; version=0 Set-Cookie3: X-APPLE-WEBAUTH-VALIDATE="\"v=1:t=BA==BST_IAAAAAAABLwIAAAAAGnyLG8RDmdzLmljbG91ZC5hdXRovQB9kwQUaVp5mcYpwvOxZ4GCnC3PL21rIb1KWfwqyYi3lai2xZjOlnV9toJ7ElKE2hRWdegjf6QPvLBIR3qtNxAV8sYd2zZVy7HQj1jd0bSMIuKq-K9HG0t1RhYt6T0QyYD3uOqatUxNZx7ujEE75WQMFsa6eg~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; discard; version=0
Set-Cookie3: X-APPLE-WEBAUTH-USER="\"v=1:s=1:d=157320350\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-USER="\"v=1:s=1:d=157320350\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X_APPLE_WEB_KB-FHMLYL_TPMN_3A8D3KIPPI0C_EC="\"v=1:t=BA==BST_IAAAAAAABLwIAAAAAGm_OLQRDmdzLmljbG91ZC5hdXRovQD38nYoxQenHW9WggeFKkoDa8I8zeKoOshv6I4dsZQalR2itry1r6kUZe9d_BZan1W-oKlImTrYi_-Vt5Q4YEJWJITWeqN8QChxvbTXB0o8sQ-wAIzBL1J5sQIRBqMadrtP5U0wslkRg0u0AguK20CM4TGoGg~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 00:32:52Z"; HttpOnly=None; version=0 Set-Cookie3: X_APPLE_WEB_KB-FHMLYL_TPMN_3A8D3KIPPI0C_EC="\"v=1:t=BA==BST_IAAAAAAABLwIAAAAAGm_OLQRDmdzLmljbG91ZC5hdXRovQD38nYoxQenHW9WggeFKkoDa8I8zeKoOshv6I4dsZQalR2itry1r6kUZe9d_BZan1W-oKlImTrYi_-Vt5Q4YEJWJITWeqN8QChxvbTXB0o8sQ-wAIzBL1J5sQIRBqMadrtP5U0wslkRg0u0AguK20CM4TGoGg~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 00:32:52Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-DS-WEB-SESSION-TOKEN="\"AQGaLX9cVeJ7EnQI/NCzMqxhb2pDyS9YSfQ1UGym2zF1fVrljZeKrlUA3e7k6IbGJwPd7ssN4+feYO2egAdRyJhQ0LJ89jY0jkyCAahyW4neQn/tbHwb49oChj+vjIK0Yv52Y3293nImzWSw1iUtNL6EhIgISPRk47tBH3PrEPwaFuPEK+YtFT8TeKaAWdIbXRIGxBkYEJYyl8BUFt4dobnS2shzOX7dfjOaBKClBF4y2x3/EVb6TeR6+kBoyLbZHe0+RMvyqrO0FFhCagmUZ0+xPAABPJq4r4JTmVfvKOU6j5gPO9Jsz97Damf9G6QyaqKcy4MjSmow4v+diEVaUdR4HyByCRTYcH+biNLnoVBeSPoVIuUQAlqdcDry6epZquivcATUeCUBEMroSWRz6gdLWkdCMSGqP+TR+aV0VROoJkGjT3lKlOJ4ElgfD5aQh4PHKyg70o9K5Eq8C+nMlphuFAgPVypRYL5rDebOWBfIlJRNuUSUIvvVyiBq94Ii2YI8BwX07TdZszdPj9oHtnX264nZe3YUw4W9XCkdPDufluUzFIP3bMIifRrOk6yEbXObUjbf5POU1taM6S2zaMvN7GspAkV5FvYE+E2NHRPGGq8PZ+8fqSIAdOx+O+zQq9T69NmxpvloIZYAUZUlwjOFtXr3vfHQhik82eLifYuiqsp/9M4yDIJvQfC7H6Mc4aM4aNHfHt2BdgXaRR2Zsx35CKLCKQtxpqT5DdO3y4+dDZt/Le7lIF/N\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-DS-WEB-SESSION-TOKEN="\"AQHabF8DfZ/FjCaFRDyaWdhzHLkfHKJ7x4QBikmeVCkCi4UMOxseAhL0l4roIVCB5CcjlGwqkXkBR30TGViREh5tXUpcTxlPXuZU4BGrwkUfXZmLxgLIAdfx6GEmbRfNzjH043ONXOYRRhsdAzTdC1atFGVUWrY3Vbvmd3QkTA8SB2UmTgVqgZ76mz7+rN5c5qeFm3YU66xjGTYrEAmzB2McNoXQSzq0lXBEWtBCMAVcr2VdIYkKOIPXUO0RL8w7k0++xh5Ci4uIggcArg1NJSF8l58yZ3P3CGZhVHigMgTE9/cKniRMPprV6mjyeWV7hU+HyFyspGvSTEk7vMXiyub/64bI/6wzsJFdm8WKXIJq9rok1KGZmO8mu3Nw8oeMRW2Ee45FRChCwzixHHhmEmd6z3OnJUZabRjo8XqAfR3Iq84PgDu8VxkONvfng4YZgxlqv0rSzZ5lI6+BX6Z2nJoH5kOw//L7t6XfgEL2zBmlWR9VY1GOlTEcA2+tfsoVWKkjk0Fhuum72fnuTeIsu1WNLi3noE8zYaSEAwzGw/vw95wr5JGodpm5pRvr0BauTKJEFUmb4FGTeh7ajE5/wrJzvFV9EyT3nc3WWrtjOXU+lCXGZNMZUbBnOdQh3X6KZw9zK16d8RJTkQ9eZc5p5RIShtAz+G0sBqo/Eu+m3e9GnRsrFafZF/oTjN4w/kCfqGzi/L59d5uCX8qYgmm1GgB7lffSaZS+gsNHVrGU7R3VaUQCbeQ=\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-HSA-TRUST="\"28a33818a1dce9a0eecde38e7c8fcc6f080b70bc9feb505599fb2855903a4792_HSARMTKNSRVXWFlajR2ecD1662phQjqU9vXxnL49ZjypuVYYXHDpA3wTiX6Mf2J4WDlIhZj52z81aDOuz+VC80bVhV41TSNN4ggoPjW8WnsQrjniTQYkgJycPQNnzhkK4hfe2AMrr/bhrJJm8sHHc+Oh1HUckN6T7T4c1bmf2Qg9tRwsdRDNyMMyFH/Ml/cQlWKj39/YHlY=SRVX\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-07-19 17:15:45Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-HSA-TRUST="\"28a33818a1dce9a0eecde38e7c8fcc6f080b70bc9feb505599fb2855903a4792_HSARMTKNSRVXWFlajR2ecD1662phQjqU9vXxnL49ZjypuVYYXHDpA3wTiX6Mf2J4WDlIhZj52z81aDOuz+VC80bVhV41TSNN4ggoPjW8WnsQrjniTQYkgJycPQNnzhkK4hfe2AMrr/bhrJJm8sHHc+Oh1HUckN6T7T4c1bmf2Qg9tRwsdRDNyMMyFH/Ml/cQlWKj39/YHlY=SRVX\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-07-19 17:15:45Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-PCS-Events="\"S2V5QXBwbDoBAAAA8QRuAAD03QLs6kAdJCQM23wVykZFD0clWmO+gTubXQ9MuQcaLA==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-PCS-Events="\"S2V5QXBwbDoBAAAA8QSiAABatpm4trV8/etQj0u/A6tHpJUw4moCXsjVZDJXsYq6kA==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-PCS-Documents="\"S2V5QXBwbDoBAAAAAgRuAAAy5taxxsiD1jDBrDQrQ1SiNyKmIxvvaWA7D0nA4Dl1iw==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-PCS-Documents="\"S2V5QXBwbDoBAAAAAgSiAACYRyWWhc7fclX72+yhSwP7V59ZVhDjbD3/73X0+tbM9g==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-PCS-Photos="\"S2V5QXBwbDoBAAAAAwRuAADS4+q95r+DyWl1ZGAmQT9MS2LUEBKAYun3XGW61iPTXg==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-PCS-Photos="\"S2V5QXBwbDoBAAAAAwSiAACHdvS2WQTlY3AwSrlOI6jwNVxtl5PqGxlyIwB3aLx51A==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-PCS-Cloudkit="\"S2V5QXBwbDoBAAAABARuAABOeS5LblTFkG8u6j7mIwaaRXTJwPVJ0sZ8/g9jV8910g==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-PCS-Cloudkit="\"S2V5QXBwbDoBAAAABASiAAAP9q4i2ZIdylYNYlXx8nBxmKXR8gNPHT9SP2roM5mYqQ==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-PCS-Safari="\"S2V5QXBwbDoBAAAAFgRuAABsSNg/+jBeWh2M6qOISYiUBEq79JiSuu7otGjyBpBf4Q==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-PCS-Safari="\"S2V5QXBwbDoBAAAAFgSiAACPOMgOztdO9qPNcfjmAEma8Qe6YoZUGyYFAMNAUgLOOg==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-PCS-Mail="\"S2V5QXBwbDoBAAAABwRuAADF1hkuqi8C9dtlFR42VnoNAyVPpWhcrELIRAjf+N3M0g==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-PCS-Mail="\"S2V5QXBwbDoBAAAABwSiAACrlC0iGK9bSx5JbJ0D4eW9I9IBOUZZIITLVpXQ8sBmnA==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-PCS-Notes="\"S2V5QXBwbDoBAAAACQRuAACUkk2Drkms4w+Wh9VFeFzbkOOMxla+5RXOacqRl/OT5A==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-PCS-Notes="\"S2V5QXBwbDoBAAAACQSiAAANah46BoeEOKAQozY+h/bkxj7PoDKmNU+m43Tpj9T8NA==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-PCS-News="\"S2V5QXBwbDoBAAAACwRuAACI8hcv3wQKVQc/jrosTdSeaOV7wKGolh3SsnB2KV4l5Q==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-PCS-News="\"S2V5QXBwbDoBAAAACwSiAACWD0i2SZ/V8tcRZctrfyzmp86gP+tmGX+L4/zPdI10qQ==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-PCS-Sharing="\"S2V5QXBwbDoBAAAADARuAAAMNHurlvF3BExXBzOliO8/XXMKPJVICVoKrapQdZ6DtA==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-21 18:02:55Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-PCS-Sharing="\"S2V5QXBwbDoBAAAADASiAAB4PKdY80kDHNy139gec9nGrrIC1uUmtMpeXly3YS463g==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-29 16:06:09Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-TOKEN="\"v=2:t=BA==BST_IAAAAAAABLwIAAAAAGnoSj8RDmdzLmljbG91ZC5hdXRovQBIW8hdgh_zfyx02_y4Hn4HvHqQgiLD7363DvLz7pwBtrTvdm3V7I3ffhB0g2EHzkFt1dIaDrk1sdCY46eySjfCpcSrwcRxUhMWIuvWzV4dvZbUKrHr4X5v98wrzMX-Xwvwo1OOFuv04U9NhQTZqEdQF22Oeg~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-06 04:10:39Z"; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-TOKEN="\"v=2:t=BA==BST_IAAAAAAABLwIAAAAAGnyPZERDmdzLmljbG91ZC5hdXRovQBRQwz2gEQUeMSQmoFWfYWYe-B6ednKfbyuYcl7f6yIxQEMhsu8dsKNsh3DkrsIyUQsTnE-JxBaAXFpRK9BHtN7_4gW5LtreKPam3-zPLzyYO30KMk3RJfRWefeq2Gore-5VAyynFkd8C-umulnmR6JbAxamQ~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-13 17:19:13Z"; HttpOnly=None; version=0
Set-Cookie3: X-APPLE-WEBAUTH-FMIP="\"BA==BST_IAAAAAAABLwIAAAAAGnoSj8RDmdzLmljbG91ZC5hdXRovQBIW8hdgh_zfyx02_y4Hn4HvHqQgiLD7363DvLz7pwBtrTvdm3V7I3ffhB0g2EHzkFt1dIaDrk1sdCY46eySjfCpcSrwcRxUhMWIuvWzV4dvbKKudZw4ESK__dFUngctbzufvHZm3Ik0x6Ql7094pfT7Iuo-Q~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; discard; HttpOnly=None; version=0 Set-Cookie3: X-APPLE-WEBAUTH-FMIP="\"BA==BST_IAAAAAAABLwIAAAAAGnyPZERDmdzLmljbG91ZC5hdXRovQBRQwz2gEQUeMSQmoFWfYWYe-B6ednKfbyuYcl7f6yIxQEMhsu8dsKNsh3DkrsIyUQsTnE-JxBaAXFpRK9BHtN7_4gW5LtreKPam3-zPLzyYLPMTUwpmOKu595hl4PeJtmR5EVt5ZKANCXsjBRmlvCwXIUhFw~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; discard; HttpOnly=None; version=0
Set-Cookie3: xr_3n2093n1a="tF9S/YsknhHffdhwA1W+2NKKwF/D5M+PVtX/BUh5l6Q="; path="/"; domain=p144-fmipweb.icloud.com; path_spec; secure; discard; HttpOnly=None; version=0 Set-Cookie3: xr_3n2093n1a=73p69RLLLRMyqW9DQrVFv8skkXX2Jkkf6hOctf+2G9sk; path="/"; domain=p144-fmipweb.icloud.com; path_spec; secure; discard; HttpOnly=None; version=0

View File

@@ -1 +1 @@
{"client_id": "a803c3ce-2586-11f1-a724-8f6777a1d2b5", "session_id": "97997103CCD7FEC9173190AED7457252EBCD7B770AB7B784C902761FC601C83B02A28C2DE1B84D51A690620FBBE43A9F53E20534400A5BABA174C06BCDF6D1239746712B62A97006E8A95F03A96A584A7185B1EB24404B0F03A152E9F46C23451139DEBF74FACF2C476512DC59E85823694E20CF535BBE50", "auth_attributes": "FhGAEYBRc1+aEJafKEWyMXwiTKgOCf4ENrADIEy/mfp/TywQkHi2sHOKpvo4RqEGn1nUCPCD/nfX9Gyi4W0N6XDtZ7HOCNGtlVhaSGJYoWSNk4/5dBcodUuA2hlYQdPs7P2MqVEIotktBhNmd/YYTGPmgjAd7gyRHhAQqC+07dw9Fwqtvv8q0dazx35kIyuErdWQ5Shb8dZ4GRjO59OCjqlwyfjWjvG4OX1pLDHwVHkljxlRfeGLRR/ILOwIwWQY0/8QvHoyFuN8d3qaDFceABK2qXKADwU=", "scnt": "AAAA-jk3OTk3MTAzQ0NEN0ZFQzkxNzMxOTBBRUQ3NDU3MjUyRUJDRDdCNzcwQUI3Qjc4NEM5MDI3NjFGQzYwMUM4M0IwMkEyOEMyREUxQjg0RDUxQTY5MDYyMEZCQkU0M0E5RjUzRTIwNTM0NDAwQTVCQUJBMTc0QzA2QkNERjZEMTIzOTc0NjcxMkI2MkE5NzAwNkU4QTk1RjAzQTk2QTU4NEE3MTg1QjFFQjI0NDA0QjBGMDNBMTUyRTlGNDZDMjM0NTExMzlERUJGNzRGQUNGMkM0NzY1MTJEQzU5RTg1ODIzNjk0RTIwQ0Y1MzVCQkU1MHwzAAABnbFDT1gK_eXTVA7MXRwWGzc7EYk78w8VdprXZA2_PjYhD7pR3jUfI2JNzgoAABK2qWyRXF7vCiS5BW4XleIhsTtwY-WrzQDbwxWdrOD8PmGOC4IDBA", "account_country": "USA", "session_token": "L5N1qDC1TDTKZcGkEcC0YgEUG63qGf9QDs7tuISwtYdNAYqz9ErHPJL3bmQIqs8+2xAQiPTOaceoglSsjq8BThr/OpJBQPFncwAcE2c66T+rK712+3GWgraF5K8yZl2vnXxFY3nLpDYAIz+jt5jiMNxgD9sOugH32kGlal2QBJSRiXnz7SrWe8hI35zfXmjrM/ARD45ZNzuSfYJZ+G6g4bK7+EWqwC3TOhrIpVXzGrqpm7FWgj2W/ZZnNGfpVq+fZ7CZ1Yp0HkEgEiM4WA8+ewstJzGOzh7pVTSc/aTA0l5/8jwqJjEvdc7C+WaJN4tjydlRre+Z6jnWuHcHP0TzhXyKfU3oHKiKMMll1WEJfNFGXzBJyhC2ZgkNMte+Ddr3u/68iv2T5foIsoJv8B8ztcD8ka/lcnf8oP5myT1CYt0P8NlOn3kg9PKWjQR5GbzgDOtmnqeHkhTkAdswD5cidKUXCnP534tur4997bYvZY3bgt6kR7ix4v9F8gBzWkDeUyP7gu0IeYisyDA8Xf1d4C6HdP+65YRoXn/Xqo94+n0A5g19Y+p5pb6X2vE2obKewTZCmH0d+VMMvFECTs9tr37zkYDV2sjXv7oSOTzdT9AWp3zVkL12+IoqswhppcZ+xWBnA2+VX4n83EKf8enRimYFx2gssnSbGJCRBIlkSggoXTO15+5j2l4eO3akjA9d4hDfL+agH/RT/h1oTm08ImD6Vw0lRkOUhFZydUUMgcbt15ZFzBt9bly+rN4BbmM2X7SStGYLRZXxPNe3iu6oy/tTucWeRXjCAHkAWqqrpIfGF/adhaDbRAwaRyfw61YxQM8P/yJy1vXXov3lnyFM9yJiggZrc1DSov7PMfBdhhpFTcAvuiEimP7Utou6b1BjfvyA/nrXqBiCDc6lkHkEd4ozamIMsyM77ZOBsb1fyrNZ867pbubUdqtr/70OuyQkkmVUgRSpJ2N+o7pvL1FY7Ux3Ukh7RNF/O+jATX6XdWBdEi8HF0C0+sHCCQxXAqgIMwDKeqwIQUD3im2i4c7aFQPwIAAStqlygRYH", "trust_eligible": "true", "grant_code": "c7f4eb1fa9c0c4821bb56e7f0d86f4410.0.srzwz.Qg-aHawHsScPT5s8mVqKoA", "trust_token": "HSARMTKNSRVXWFlajR2ecD1662phQjqU9vXxnL49ZjypuVYYXHDpA3wTiX6Mf2J4WDlIhZj52z81aDOuz+VC80bVhV41TSNN4ggoPjW8WnsQrjniTQYkgJycPQNnzhkK4hfe2AMrr/bhrJJm8sHHc+Oh1HUckN6T7T4c1bmf2Qg9tRwsdRDNyMMyFH/Ml/cQlWKj39/YHlY=SRVX"} {"client_id": "a803c3ce-2586-11f1-a724-8f6777a1d2b5", "session_id": "3C2D0B45AFDCBAC81490E66E2DB79DD28298FB98A4E44381F64D4CFC4A677C6E4BE90E2B7F77BAFC992186F745E8A39EC5B52EE814BB65F1BA8137C80C973C9B657E1300A0E9C22BE32927B428866415AE2E3E66BA4541A67D8411C808E20F8797B807AEB5BDEDA05F2B6FF1306E59D4212F589D7028ED1B", "auth_attributes": "VsXLJh/Xck+NoyZTEUSuCMIuwFZpPHTgWKmVRrIPf4pLGNC52y5WlHKP/lS77U6ULEEAAyIkdNvXrU3uIZr29W7OgGfVgsX+jPkqIb6Ve9v/PGYUAWcvxNMdQD0iHiAZ+Rum9P+QLERwoC3/p7rPhK7NJ94aMlMK/Dg9D+8friEd9nGVgbs7Jy29l5Iir3jWaYsoQKHcFA6D88WCiYEKYp4OfVDog3LEL5IvyYv4uRUAdb2lGOKxcKi4G7iX00T1z+GWb1DGMebu1Ya9+gl9ABTMu8/ZLxM=", "scnt": "AAAA-jNDMkQwQjQ1QUZEQ0JBQzgxNDkwRTY2RTJEQjc5REQyODI5OEZCOThBNEU0NDM4MUY2NEQ0Q0ZDNEE2NzdDNkU0QkU5MEUyQjdGNzdCQUZDOTkyMTg2Rjc0NUU4QTM5RUM1QjUyRUU4MTRCQjY1RjFCQTgxMzdDODBDOTczQzlCNjU3RTEzMDBBMEU5QzIyQkUzMjkyN0I0Mjg4NjY0MTVBRTJFM0U2NkJBNDU0MUE2N0Q4NDExQzgwOEUyMEY4Nzk3QjgwN0FFQjVCREVEQTA1RjJCNkZGMTMwNkU1OUQ0MjEyRjU4OUQ3MDI4RUQxQnwzAAABndoLS0dWpQExE5EJSwL6PIMmSS-olE_EI2BaYpY9v1wSg3Bw60qrXHGB2DoYABTMu8qXOh9L73-Oy0-NxNuGj6itTdeX-GICGK70IWc1gQU98HXS5g", "account_country": "USA", "session_token": "JnRudepNo3OB68SHldgrFYDze+Jxhyll/djlkEG8RCVYTG92cOQBVg26vNvFp86vwz30N2UzJD9hpJMONB4YC3/IxpnIu+J7cLgv3hO2tg98L3vTmdwkUerzeO6cmRnourDqbDNiGGvQhhrtNpzOH4dMeVqy6qjRKZHTVnYEUl8EnT7S/LUHtrXkjgW7cYY3dhbk5xm6J+zVi7oTNzsQ+QQF1Bgr2s7mnr6u0cWeVh7BNIOLfQhyGMlRRYWiG+QjzcJBNlMVWsHEYKLxbVStnE9l2DXcyMhbWy6y8kgdDqINIOyIT9PLtoY3LESDyXKd8fuv32ZYF/qe6P1jKjSZhjSRz+4ZGEBFaPvKQ6qty5CQn62lU6ZZlksR/6KWPNgZQkQJnnmou9fun0xslOjJYCT8EvT1EL7Y0xFQbvgZZTm+1kvqNlPKVtE6gHVhdeJiFZgX8wkZkT5rRx7rTnNFWJVLDjNV2w3zV8lOgiURgrJCwvOQmOl3BiveoDXPPrQlz07RW5l1bDedyMa6puuEPdU2BRWDJLMZmRTnbvnp8IOwcKGNvIQWTnSnViItsdBvJx8HCcLOhI/xBhzJyUxWimSJy2HbQ+Y4DbCniVfjw/ynWKqvM9ntA3TchDS3oiO8l9GJbJ/PhcAgtFVXRmHHD1imHf8OSDIoLp5UDdRi2dw4Z6crZgJNx9Nkp2i3gcv4Zy/vwZHgabi2W2zCU6x9hMP/biDPUBa9fXplH2rMHZ4mRQvKgLQAEYJKQ103754KEExUYNihOnwz5wZGhJAFGCCIuyCD3/I/OLUf48brVbrmuF3ehUY7b7FykIGBLmSRxwCtQr/wxXPhYb3yJ5gygy45+fA3+fXhQ8+W7RlTFduRP5nCHw5vbrMiPhLNpe9Tu3rBT6BTboufzGEmgyZHRwh5c0g/3pfagVAGXtqTONuWY15T5Bmgdz7AKi8JFYPJL84yF2QyZFLwOf05jrjx6f/MvrC4/nX2TlXhr9woxeM6WSmg/fpxizJQT0ybLM5sxxeyVgG3n4BDFONobc+sZa436QAUzLvP2t8m", "trust_eligible": "true", "grant_code": "c7f4eb1fa9c0c4821bb56e7f0d86f4410.0.srzwz.Qg-aHawHsScPT5s8mVqKoA", "trust_token": "HSARMTKNSRVXWFlajR2ecD1662phQjqU9vXxnL49ZjypuVYYXHDpA3wTiX6Mf2J4WDlIhZj52z81aDOuz+VC80bVhV41TSNN4ggoPjW8WnsQrjniTQYkgJycPQNnzhkK4hfe2AMrr/bhrJJm8sHHc+Oh1HUckN6T7T4c1bmf2Qg9tRwsdRDNyMMyFH/Ml/cQlWKj39/YHlY=SRVX"}

Binary file not shown.

View File

@@ -6,8 +6,19 @@ from geopy.adapters import AioHTTPAdapter
from geopy.extra.rate_limiter import AsyncRateLimiter from geopy.extra.rate_limiter import AsyncRateLimiter
logger = logging.getLogger("ios-api") logger = logging.getLogger("ios-api")
CACHE_LOOKUP_SQL = "SELECT address FROM location_cache WHERE lat_lon = ?" CACHE_LOOKUP_SQL = "SELECT address, favorite FROM location_cache WHERE lat_lon = ?"
CACHE_UPSERT_SQL = "INSERT OR REPLACE INTO location_cache VALUES (?, ?)" CACHE_UPSERT_SQL = """
INSERT INTO location_cache (lat_lon, address)
VALUES (?, ?)
ON CONFLICT(lat_lon) DO UPDATE SET address = excluded.address
"""
FAVORITE_LOOKUP_SQL = "SELECT favorite FROM location_cache WHERE favorite IS NOT NULL"
FAVORITE_UPSERT_SQL = """
INSERT INTO location_cache (lat_lon, favorite)
VALUES (?, ?)
ON CONFLICT(lat_lon) DO UPDATE SET favorite = excluded.favorite
"""
FAVORITE_CLEAR_SQL = "UPDATE location_cache SET favorite = NULL WHERE lat_lon = ?"
class AsyncReverseGeocoder: class AsyncReverseGeocoder:
@@ -27,9 +38,15 @@ class AsyncReverseGeocoder:
cursor.execute(''' cursor.execute('''
CREATE TABLE IF NOT EXISTS location_cache ( CREATE TABLE IF NOT EXISTS location_cache (
lat_lon TEXT PRIMARY KEY, lat_lon TEXT PRIMARY KEY,
address TEXT address TEXT,
favorite TEXT
) )
''') ''')
cursor.execute("PRAGMA table_info(location_cache)")
columns = {row[1] for row in cursor.fetchall()}
if "favorite" not in columns:
cursor.execute("ALTER TABLE location_cache ADD COLUMN favorite TEXT")
conn.commit() conn.commit()
@staticmethod @staticmethod
@@ -40,19 +57,65 @@ class AsyncReverseGeocoder:
with sqlite3.connect(self.db_path) as conn: with sqlite3.connect(self.db_path) as conn:
cursor = conn.execute(CACHE_LOOKUP_SQL, (key,)) cursor = conn.execute(CACHE_LOOKUP_SQL, (key,))
row = cursor.fetchone() row = cursor.fetchone()
return json.loads(row[0]) if row else None cached = {}
if row:
cached['address'] = json.loads(row[0]) if row[0] else {}
cached['favorite'] = json.loads(row[1]) if row[1] else {}
return cached if row else None
def _store_cached_address(self, key: str, address_data: dict) -> None: def _store_cached_address(self, key: str, address_data: dict) -> None:
with sqlite3.connect(self.db_path) as conn: with sqlite3.connect(self.db_path) as conn:
conn.execute(CACHE_UPSERT_SQL, (key, json.dumps(address_data))) conn.execute(CACHE_UPSERT_SQL, (key, json.dumps(address_data)))
conn.commit() conn.commit()
def _read_favorites(self) -> list | None:
with sqlite3.connect(self.db_path) as conn:
cursor = conn.execute(FAVORITE_LOOKUP_SQL)
rows = cursor.fetchall()
favorites = [json.loads(row[0]) for row in rows if row[0]]
return favorites if favorites else None
async def clear_favorite(self, lat: float, lon: float) -> bool:
key = self._cache_key(lat, lon)
cached = self._read_cached_address(key)
if cached and cached.get("favorite"):
favorite = cached.get("favorite")
name = favorite.get("name") if isinstance(favorite, dict) else key
logger.info("Clearing favorite %s", name)
with sqlite3.connect(self.db_path) as conn:
cursor = conn.execute(FAVORITE_CLEAR_SQL, (key,))
conn.commit()
return cursor.rowcount > 0
else:
return False
async def set_favorite(self, lat: float, lon: float, favorite_data: dict) -> bool:
key = self._cache_key(lat, lon)
name = favorite_data.get("name")
if not name:
return False
logger.info("Setting favorite location %s to location_cache for %s", name, key)
try:
with sqlite3.connect(self.db_path) as conn:
conn.execute(FAVORITE_UPSERT_SQL, (key, json.dumps(favorite_data)))
conn.commit()
return True
except sqlite3.Error as e:
logger.exception("Failed to set favorite location %s to location_cache for %s: %s", name, key, e)
return False
async def get_favorites(self) -> list | None:
"""Reverse geocode with SQLite cache."""
logger.info("Checking location_cache for favorites")
favorites = self._read_favorites()
return favorites
async def get_address(self, lat: float, lon: float) -> dict | None: async def get_address(self, lat: float, lon: float) -> dict | None:
"""Reverse geocode with SQLite cache.""" """Reverse geocode with SQLite cache."""
key = self._cache_key(lat, lon) key = self._cache_key(lat, lon)
logger.info("Checking location_cache for %s", key)
cached_address = self._read_cached_address(key) cached_address = self._read_cached_address(key)
if cached_address is not None: if cached_address is not None:
logger.info("Found cached address for %s", key)
return cached_address return cached_address
async with Nominatim( async with Nominatim(
@@ -64,10 +127,11 @@ class AsyncReverseGeocoder:
geolocator.reverse, min_delay_seconds=1) geolocator.reverse, min_delay_seconds=1)
location = await reverse(key) location = await reverse(key)
if location: if location:
response = {}
logger.info("Nominatim response: %s", location) logger.info("Nominatim response: %s", location)
address_data = location.raw.get("address", {}) response['address'] = location.raw.get("address", {})
self._store_cached_address(key, address_data) self._store_cached_address(key, response['address'])
return address_data return response
return None return None
except Exception: except Exception:
logger.exception("Reverse geocoding failed for key=%s", key) logger.exception("Reverse geocoding failed for key=%s", key)

View File

@@ -642,10 +642,8 @@ class TunneldRunnerSio:
"command": "start", "command": "start",
"message": "Simulation started", "message": "Simulation started",
"data": { "data": {
"simulation_queue": get_simulation_status(),
"simulation_active": self.context.simulation_active, },
"simulation_queue_state": self.context.simulation_queue_state
}
} }
else: else:
data = { data = {
@@ -654,9 +652,8 @@ class TunneldRunnerSio:
"command": "start", "command": "start",
"message": "Simulation already running", "message": "Simulation already running",
"data": { "data": {
"simulation_active": self.context.simulation_active, "simulation_queue": get_simulation_status(),
"simulation_queue_state": self.context.simulation_queue_state },
}
} }
return data return data
@@ -763,6 +760,7 @@ class TunneldRunnerSio:
{ {
"type": "simulation_crash", "type": "simulation_crash",
"udid": self.context.udid, "udid": self.context.udid,
"udid": self.context.udid,
"error": traceback.format_exc(), "error": traceback.format_exc(),
}, },
namespace="/", namespace="/",
@@ -885,7 +883,6 @@ class TunneldRunnerSio:
"command": "delete", "command": "delete",
"message": f"Location {loc_id} deleted from the queue", "message": f"Location {loc_id} deleted from the queue",
"data": { "data": {
"simulation_queue": get_simulation_status(),
"simulation_queue": get_simulation_status(), "simulation_queue": get_simulation_status(),
"location_item": self.context.simulation_queue_data[loc_id], "location_item": self.context.simulation_queue_data[loc_id],
}, },
@@ -1179,12 +1176,69 @@ class TunneldRunnerSio:
else getattr(data, "longitude", 999) else getattr(data, "longitude", 999)
) )
if latitude != 999 and longitude != 999: if latitude != 999 and longitude != 999:
coords = f"{latitude}, {longitude}"
rev_geocode = await self.context.reverse_geocode.get_address(latitude, longitude) rev_geocode = await self.context.reverse_geocode.get_address(latitude, longitude)
return rev_geocode return rev_geocode
else: else:
return None return None
async def get_favorites():
favorites = await self.context.reverse_geocode.get_favorites()
return favorites
async def clear_favorite(data):
latitude = float(
data.get("latitude", 999)
if isinstance(data, dict)
else getattr(data, "latitude", 999)
)
longitude = float(
data.get("longitude", 999)
if isinstance(data, dict)
else getattr(data, "longitude", 999)
)
if latitude != 999 and longitude != 999:
clear_status = await self.context.reverse_geocode.clear_favorite(latitude, longitude)
if clear_status:
return "OK", "Favorite cleared"
else:
return "ERROR", "Failed to clear favorite"
else:
return "ERROR", "Invalid latitude and longitude"
async def set_favorite(data):
favorite = (
data.get("favorite")
if isinstance(data, dict)
else getattr(data, "favorite", None)
)
if favorite is not None:
name = (
favorite.get("name")
if isinstance(favorite, dict)
else getattr(favorite, "name", None)
)
logger.info("Adding favorite: %s", name)
latitude = float(
favorite.get("latitude", 999)
if isinstance(favorite, dict)
else getattr(favorite, "latitude", 999)
)
longitude = float(
favorite.get("longitude", 999)
if isinstance(favorite, dict)
else getattr(favorite, "longitude", 999)
)
if latitude != 999 and longitude != 999 and favorite:
set_status = await self.context.reverse_geocode.set_favorite(latitude, longitude, favorite)
if set_status:
return "OK", "Favorite added"
else:
return "ERROR", "Failed to add favorite"
else:
return "ERROR", "Invalid latitude and longitude"
else:
return "ERROR", "Invalid favorite data"
""" FastAPI HTTP Functions""" """ FastAPI HTTP Functions"""
def generate_http_response( def generate_http_response(
@@ -1738,6 +1792,20 @@ class TunneldRunnerSio:
} }
return resp return resp
case "reset":
""" Reset the simulation queue"""
reset_queue()
resp = {
"command": command,
"command_class": "simulation_control",
"command_status": "OK",
"message": "Simulation queue reset",
"data": {
"simulation_queue": get_simulation_status(),
}
}
return resp
case "pause": case "pause":
""" Pause the simulation queue""" """ Pause the simulation queue"""
await pause_simulation_queue() await pause_simulation_queue()
@@ -1751,6 +1819,7 @@ class TunneldRunnerSio:
} }
} }
return resp return resp
case "resume": case "resume":
""" Resume the simulation queue""" """ Resume the simulation queue"""
await resume_simulation_queue() await resume_simulation_queue()
@@ -1764,6 +1833,7 @@ class TunneldRunnerSio:
} }
} }
return resp return resp
case "end": case "end":
""" End the simulation queue""" """ End the simulation queue"""
logger.info( logger.info(
@@ -1779,12 +1849,14 @@ class TunneldRunnerSio:
} }
} }
return resp return resp
case "start": case "start":
""" Start the simulation queue""" """ Start the simulation queue"""
logger.info( logger.info(
"Start location simulation request from %s", sid) "Start location simulation request from %s", sid)
data = await start_simulation_queue() data = await start_simulation_queue()
return data return data
case "gps-noise": case "gps-noise":
""" Toggle GPS noise""" """ Toggle GPS noise"""
before_toggle = self.context.simulation_noise before_toggle = self.context.simulation_noise
@@ -1952,6 +2024,27 @@ class TunneldRunnerSio:
"command_status": "ERROR", "command_status": "ERROR",
"message": f"Error starting tunneld: {e}", "message": f"Error starting tunneld: {e}",
} }
case "restart":
"""Restart Tunneld"""
logger.info("Restart tunneld request from %s: %s", sid, data)
try:
self._tunneld_core.clear()
await asyncio.sleep(2)
self._tunneld_core.start()
return {
"command_status": "OK",
"command_class": "tunneld_control",
"command": command,
"message": "Tunneld started successfully",
}
except Exception as e:
logger.error("Error restarting tunneld: %s", e)
return {
"command_status": "ERROR",
"command_class": "tunneld_control",
"command": command,
"message": f"Error starting tunneld: {e}",
}
case "start-watcher": case "start-watcher":
""" Start Tunneld Watcher """ """ Start Tunneld Watcher """
@@ -2060,6 +2153,76 @@ class TunneldRunnerSio:
rev_geocode = await get_reverse_geocode(data) rev_geocode = await get_reverse_geocode(data)
return rev_geocode return rev_geocode
@self.context.sio.event
async def favorite_control(sid, data: dict):
command = (
data.get("command")
if isinstance(data, dict)
else getattr(data, "command", None)
)
logger.info(
"Favorite Control command: %s requested from %s", command, sid
)
match command:
case "set":
""" Add a favorite location to database"""
cstat, cmessage = await set_favorite(data)
if cstat == "ERROR":
logger.error('Favorite set failed: %s', cmessage)
resp = {
"command": command,
"command_class": "favorite_control",
"command_status": cstat,
"message": cmessage,
"data": {
"favorites": await get_favorites(),
}
}
return resp
case "clear":
""" Clear a favorite location from database"""
cstat, cmessage = await clear_favorite(data)
resp = {
"command": command,
"command_class": "favorite_control",
"command_status": cstat,
"message": cmessage,
"data": {
"favorites": await get_favorites(),
}
}
return resp
case "get":
""" Get favorite locations from database"""
favs = await get_favorites()
if favs:
cstat = "OK"
cmessage = "Favorites retrieved successfully"
else:
cstat = "ERROR"
cmessage = "No favorites found"
resp = {
"command": command,
"command_class": "favorite_control",
"command_status": cstat,
"message": cmessage,
"data": {
"favorites": favs,
}
}
return resp
case _:
return {
"command": command,
"command_class": "favorite_control",
"command_status": "ERROR",
"message": f"Invalid command: {command}",
}
self._vue_app.include_router(self._app, prefix="/api") self._vue_app.include_router(self._app, prefix="/api")
self._vue_app.mount( self._vue_app.mount(