diff --git a/cookies/willbrunogmailcom.cookiejar b/cookies/willbrunogmailcom.cookiejar index bb7e4cc..84f748f 100644 --- a/cookies/willbrunogmailcom.cookiejar +++ b/cookies/willbrunogmailcom.cookiejar @@ -1,24 +1,24 @@ #LWP-Cookies-2.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: acn01=KVgOa2TlSALDmkRBN3HjFqQsmjntJ3LJQtZC9wATSlL+oYci; path="/"; domain=.apple.com; path_spec; secure; expires="2027-04-21 18:02:51Z"; HttpOnly=None; version=0 -Set-Cookie3: aasp=97997103CCD7FEC9173190AED7457252EBCD7B770AB7B784C902761FC601C83B02A28C2DE1B84D51A690620FBBE43A9F53E20534400A5BABA174C06BCDF6D1239746712B62A97006E8A95F03A96A584A7185B1EB24404B0F03A152E9F46C23451139DEBF74FACF2C476512DC59E85823694E20CF535BBE50; path="/"; domain=.idmsa.apple.com; path_spec; secure; discard; 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=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-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-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-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-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_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-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-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-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-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-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-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-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-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-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-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-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-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-FMIP="\"BA==BST_IAAAAAAABLwIAAAAAGnoSj8RDmdzLmljbG91ZC5hdXRovQBIW8hdgh_zfyx02_y4Hn4HvHqQgiLD7363DvLz7pwBtrTvdm3V7I3ffhB0g2EHzkFt1dIaDrk1sdCY46eySjfCpcSrwcRxUhMWIuvWzV4dvbKKudZw4ESK__dFUngctbzufvHZm3Ik0x6Ql7094pfT7Iuo-Q~~\""; 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: 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="\"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="\"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="\"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="\"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="\"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="\"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="\"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="\"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_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_IAAAAAAABLwIAAAAAGnyPZERDmdzLmljbG91ZC5hdXRovQBRQwz2gEQUeMSQmoFWfYWYe-B6ednKfbyuYcl7f6yIxQEMhsu8dsKNsh3DkrsIyUQsTnE-JxBaAXFpRK9BHtN7_4gW5LtreKPam3-zPLzyYLPMTUwpmOKu595hl4PeJtmR5EVt5ZKANCXsjBRmlvCwXIUhFw~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; 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 diff --git a/cookies/willbrunogmailcom.session b/cookies/willbrunogmailcom.session index ee7328e..782ae66 100644 --- a/cookies/willbrunogmailcom.session +++ b/cookies/willbrunogmailcom.session @@ -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"} \ No newline at end of file +{"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"} \ No newline at end of file diff --git a/geocache.db b/geocache.db index ad9b4e2..3ddbc83 100644 Binary files a/geocache.db and b/geocache.db differ diff --git a/src/pymd3_vue_location_sim/geo_cache.py b/src/pymd3_vue_location_sim/geo_cache.py index 1a3d593..d0f53a2 100644 --- a/src/pymd3_vue_location_sim/geo_cache.py +++ b/src/pymd3_vue_location_sim/geo_cache.py @@ -6,8 +6,19 @@ from geopy.adapters import AioHTTPAdapter from geopy.extra.rate_limiter import AsyncRateLimiter logger = logging.getLogger("ios-api") -CACHE_LOOKUP_SQL = "SELECT address FROM location_cache WHERE lat_lon = ?" -CACHE_UPSERT_SQL = "INSERT OR REPLACE INTO location_cache VALUES (?, ?)" +CACHE_LOOKUP_SQL = "SELECT address, favorite FROM location_cache WHERE lat_lon = ?" +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: @@ -27,9 +38,15 @@ class AsyncReverseGeocoder: cursor.execute(''' CREATE TABLE IF NOT EXISTS location_cache ( 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() @staticmethod @@ -40,19 +57,65 @@ class AsyncReverseGeocoder: with sqlite3.connect(self.db_path) as conn: cursor = conn.execute(CACHE_LOOKUP_SQL, (key,)) 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: with sqlite3.connect(self.db_path) as conn: conn.execute(CACHE_UPSERT_SQL, (key, json.dumps(address_data))) 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: """Reverse geocode with SQLite cache.""" key = self._cache_key(lat, lon) - logger.info("Checking location_cache for %s", key) cached_address = self._read_cached_address(key) if cached_address is not None: + logger.info("Found cached address for %s", key) return cached_address async with Nominatim( @@ -64,10 +127,11 @@ class AsyncReverseGeocoder: geolocator.reverse, min_delay_seconds=1) location = await reverse(key) if location: + response = {} logger.info("Nominatim response: %s", location) - address_data = location.raw.get("address", {}) - self._store_cached_address(key, address_data) - return address_data + response['address'] = location.raw.get("address", {}) + self._store_cached_address(key, response['address']) + return response return None except Exception: logger.exception("Reverse geocoding failed for key=%s", key) diff --git a/src/pymd3_vue_location_sim/server.py b/src/pymd3_vue_location_sim/server.py index c18f154..7c047df 100644 --- a/src/pymd3_vue_location_sim/server.py +++ b/src/pymd3_vue_location_sim/server.py @@ -642,10 +642,8 @@ class TunneldRunnerSio: "command": "start", "message": "Simulation started", "data": { - - "simulation_active": self.context.simulation_active, - "simulation_queue_state": self.context.simulation_queue_state - } + "simulation_queue": get_simulation_status(), + }, } else: data = { @@ -654,9 +652,8 @@ class TunneldRunnerSio: "command": "start", "message": "Simulation already running", "data": { - "simulation_active": self.context.simulation_active, - "simulation_queue_state": self.context.simulation_queue_state - } + "simulation_queue": get_simulation_status(), + }, } return data @@ -763,6 +760,7 @@ class TunneldRunnerSio: { "type": "simulation_crash", "udid": self.context.udid, + "udid": self.context.udid, "error": traceback.format_exc(), }, namespace="/", @@ -885,7 +883,6 @@ class TunneldRunnerSio: "command": "delete", "message": f"Location {loc_id} deleted from the queue", "data": { - "simulation_queue": get_simulation_status(), "simulation_queue": get_simulation_status(), "location_item": self.context.simulation_queue_data[loc_id], }, @@ -1179,12 +1176,69 @@ class TunneldRunnerSio: else getattr(data, "longitude", 999) ) if latitude != 999 and longitude != 999: - coords = f"{latitude}, {longitude}" rev_geocode = await self.context.reverse_geocode.get_address(latitude, longitude) return rev_geocode else: 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""" def generate_http_response( @@ -1738,6 +1792,20 @@ class TunneldRunnerSio: } 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": """ Pause the simulation queue""" await pause_simulation_queue() @@ -1751,6 +1819,7 @@ class TunneldRunnerSio: } } return resp + case "resume": """ Resume the simulation queue""" await resume_simulation_queue() @@ -1764,6 +1833,7 @@ class TunneldRunnerSio: } } return resp + case "end": """ End the simulation queue""" logger.info( @@ -1779,12 +1849,14 @@ class TunneldRunnerSio: } } return resp + case "start": """ Start the simulation queue""" logger.info( "Start location simulation request from %s", sid) data = await start_simulation_queue() return data + case "gps-noise": """ Toggle GPS noise""" before_toggle = self.context.simulation_noise @@ -1952,6 +2024,27 @@ class TunneldRunnerSio: "command_status": "ERROR", "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": """ Start Tunneld Watcher """ @@ -2060,6 +2153,76 @@ class TunneldRunnerSio: rev_geocode = await get_reverse_geocode(data) 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.mount(