fixes
This commit is contained in:
@@ -1,25 +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="siA7JPBndkEejEnE/127L8mBwoisazQDFIhojgAQ/KEGDE9i"; path="/"; domain=.apple.com; path_spec; secure; expires="2027-04-16 02:29:40Z"; 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=31DACD6478D254816871CEC71746594E9EB265E23843BFE54ACC23E6CD21C7967B4A74875C4B64D8D546102A6808900C1DFFE23602181DADE792ED7B73E9C5A4CC7C56CCF9C822DA32264AE474FEDF84ADC645D0F5B9D01FF71B500A76FBE7FF8AA5B0B9A6B0FB8F7A61CDB741E9973C9A04245DF7E939AB; path="/"; domain=.idmsa.apple.com; path_spec; secure; discard; HttpOnly=None; version=0
|
Set-Cookie3: aasp=97997103CCD7FEC9173190AED7457252EBCD7B770AB7B784C902761FC601C83B02A28C2DE1B84D51A690620FBBE43A9F53E20534400A5BABA174C06BCDF6D1239746712B62A97006E8A95F03A96A584A7185B1EB24404B0F03A152E9F46C23451139DEBF74FACF2C476512DC59E85823694E20CF535BBE50; path="/"; domain=.idmsa.apple.com; path_spec; secure; discard; HttpOnly=None; version=0
|
||||||
Set-Cookie3: DES580750186337023c50d1415a6e6ca44a2="HSARMTKNSRVXWFlajR2ecD1662phQjqU9vXxnL49ZjypuVYYXHDpA3wTiX6Mf2J4WDlIhZj52z81aDOuz+VC80bVhV41TSNN4ggoPjW8WnsQrjniTQYkgJycPQNnzhkK4hfe2AMrr/bhrJJm8sHHc+Oh1HUckN6T7T4c1bmf2Qg9tRwsdRDNyMMyFH/Ml/cQlWKj39/YHlY=SRVX"; path="/"; domain=.idmsa.apple.com; path_spec; secure; expires="2026-04-21 03:09:12Z"; 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_IAAAAAAABLwIAAAAAGngXy8RDmdzLmljbG91ZC5hdXRovQD04k7cSA0I7tz8P6YR10gGD7CeiE4Sp9KmB4NcfSJGJ9mMfV3s3UQpxtOj9bruFqCinlYpdqRIEyP2Gq5A_XBK1p7RsIkCrmxvCBTILwOf1RyEF9rd5VMxpyFJXo26hjHe8Cb6EB346qaJbrZ0r89Gs_Dp-A~~\""; 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_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_IAAAAAAABLwIAAAAAGngXy8RDmdzLmljbG91ZC5hdXRovQD04k7cSA0I7tz8P6YR10gGD7CeiE4Sp9KmB4NcfSJGJ9mMfV3s3UQpxtOj9bruFqCinlYpdqRIEyP2Gq5A_XBK1p7RsIkCrmxvCBTILwOf1bJlsm_AS1Djsp7P1ioqPimN8HaW0JDK-1gjsxQX4O6MgDpkxQ~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; discard; 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-16 04:01:54Z"; 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-21 18:02:55Z"; 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="\"AQE2jvAclZD065mntDlVLyvYiJo3gR1bQrXcbC4UJg7cfXVcjogcjL3EORqqwOCw/77BmeCLIYZVCGY/rdu/a7P8a3P628zN4M3/97eFNWavQnlNfVotwXIPv7qcWQoIm7C2G7Gf4JHklBOmzWU9tmub3JpV5bzxRYb41I1YvwUYt8wWigFwQeX1p0djcpB0YbQp7Ign0RzHelQ0LE0046v2mWkeTXN59E57xpVChCkcsydb1LQ7dARyG6K8nDVBxYMrB4CiWR93/w9GbdECWXDl1zGyUcUEKjveXj/f4yUMmP97xlNYSr4T1srOGXuqyGQ35QBbcVhfgciSTSC8IWp1CfoJYDFoRjgsock39xnQIzkV0kgqbqh9KmMnRpra+BvTwFpkZooM5yqBH6q83k1mrQwv3WpGpKSgJf7DHk/DllkZi9mnZHVgukX+KWlgCnl5IPACmg72mbM9Lt43Rn6NxCXE4LoOxSRCg0OM7U5VB2KQEW0itAifwYbTeLDYEy2FK0GysmpQUdiRLPqbY/5tmR29VsrH11ILDmWcMkuClbf4MgFo723r2wPIZc8VXWSNAwArChh6gGmYRmmgpJwMoAADz+e53bH9t2zdNeo5Gl4UXCo2krrwW6hPDvIvIsO2G9RsqxPjfWe8TEhWxqSNZ0NCXihX0AZ+jYVR1eNu6d55TEBavM/wYPxJW7y8YCFJV3xXIpZRmPWAO/+WiqeBBH3jRSIGQZcCe5Sa8114Bf5zVUl2Ccgpo6A4ONfoWkXlDHbeXSxmuRKE7QXjToAcLgEErM1UOPo=\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-16 04:01:54Z"; 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-WEBAUTH-HSA-TRUST="\"28a33818a1dce9a0eecde38e7c8fcc6f080b70bc9feb505599fb2855903a4792_HSARMTKNSRVXWFlajR2ecD1662phQjqU9vXxnL49ZjypuVYYXHDpA3wTiX6Mf2J4WDlIhZj52z81aDOuz+VC80bVhV41TSNN4ggoPjW8WnsQrjniTQYkgJycPQNnzhkK4hfe2AMrr/bhrJJm8sHHc+Oh1HUckN6T7T4c1bmf2Qg9tRwsdRDNyMMyFH/Ml/cQlWKj39/YHlY=SRVX\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-07-15 04:01:51Z"; 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="\"S2V5QXBwbDoBAAAA8QRZAADyjPVu3Zmkep80V+qJNHa5C3NwfKpeMyW67J1rMKpK4Q==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-16 04:01:54Z"; 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="\"S2V5QXBwbDoBAAAAAgRZAABipc9p/kcwMIQ/uzTmZZxdtx00DjfUVtPIn8qIK3qBiw==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-16 04:01:54Z"; 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="\"S2V5QXBwbDoBAAAAAwRZAABdIvbUGMfQwMvJBKaERpK7lH+LKZUfwl8xaaM0s/9G3A==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-16 04:01:54Z"; 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="\"S2V5QXBwbDoBAAAABARZAABLV1DirvkB63ct2xhJbufRGeA6yHF1dzCZyT2lUxmHqg==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-16 04:01:54Z"; 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="\"S2V5QXBwbDoBAAAAFgRZAAD1MhBAfPNJA/LzwgvGElc+wsl5KKnPYjLUu4/gMxexQg==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-16 04:01:54Z"; 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="\"S2V5QXBwbDoBAAAABwRZAABpYZPPRGY/AiCTZ+FxbMFSnuLaJ83tH7xhjpL0BjSDDg==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-16 04:01:54Z"; 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="\"S2V5QXBwbDoBAAAACQRZAAAHGYf+WnAkIKAbEuOfLXsDNDwkpc9fc9XRBT7MuUB8oA==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-16 04:01:54Z"; 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="\"S2V5QXBwbDoBAAAACwRZAADjYc71gjGFasFxH7Z1SUqX3HeZxOksxRuTIbRcuYhNlA==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-16 04:01:54Z"; 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="\"S2V5QXBwbDoBAAAADARZAABkkP52Jyp0ESCIUjeMwkIQt7V6sNsaAMg/Fqp2BpcFBg==\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-05-16 04:01:54Z"; 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_IAAAAAAABLwIAAAAAGngbgERDmdzLmljbG91ZC5hdXRovQA3sNfo8nQ2WqjRiW8b2v6FBA7xVM9ABBbUseXK6M1xna_9nP0GiTFniTIZZOBZKPWrAYTMjtv4yy7kM54yBmzwmpnsWfZi5eEJsLoboChOa7f6SKHTZUIsYnzV_GQH8efLnI9WppfwGYtR-h1kK71sisAa3g~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; expires="2026-04-30 05:05:05Z"; 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_IAAAAAAABLwIAAAAAGngbgERDmdzLmljbG91ZC5hdXRovQA3sNfo8nQ2WqjRiW8b2v6FBA7xVM9ABBbUseXK6M1xna_9nP0GiTFniTIZZOBZKPWrAYTMjtv4yy7kM54yBmzwmpnsWfZi5eEJsLoboChOa_OhPIyPKAsZumke00vIotvQgxBnmoPPwJSambgtmkzhunV0BQ~~\""; path="/"; domain=.icloud.com; path_spec; domain_dot; secure; discard; 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="B50g9gcKmoM+KF+j8hPX6wKXv22QcYsBKEONZTiNR4g="; path="/"; domain=p144-fmipweb.icloud.com; path_spec; 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
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"client_id": "a803c3ce-2586-11f1-a724-8f6777a1d2b5", "session_id": "31DACD6478D254816871CEC71746594E9EB265E23843BFE54ACC23E6CD21C7967B4A74875C4B64D8D546102A6808900C1DFFE23602181DADE792ED7B73E9C5A4CC7C56CCF9C822DA32264AE474FEDF84ADC645D0F5B9D01FF71B500A76FBE7FF8AA5B0B9A6B0FB8F7A61CDB741E9973C9A04245DF7E939AB", "auth_attributes": "TZEZq6jNK7opptLHNWdfaXDIdIxdU7QFMD77vSobzh8nCntqlxgqc//nJp+R019Uu1BCkbJQ2kQqR1klW6lvKS0MLfWf9rNzaflu5uQgHMQhqOm4MJzIb8Mebqfmh2rsPlbm137EJO468E/sZbLLwl1PKOjj3o1IqEhfG17Xsa7TlxJAfLQorZTGJtMAapcxBu3NJIAnYSJRoY7h11keWBRWxGSb6zuYAy0yXAD4x3Pu7tFVtYwQTiUX3+HrcGFVJa/D8f/3vfiryreNgQX7ABD8oRF8Ooc=", "scnt": "AAAA-jMxREFDRDY0NzhEMjU0ODE2ODcxQ0VDNzE3NDY1OTRFOUVCMjY1RTIzODQzQkZFNTRBQ0MyM0U2Q0QyMUM3OTY3QjRBNzQ4NzVDNEI2NEQ4RDU0NjEwMkE2ODA4OTAwQzFERkZFMjM2MDIxODFEQURFNzkyRUQ3QjczRTlDNUE0Q0M3QzU2Q0NGOUM4MjJEQTMyMjY0QUU0NzRGRURGODRBREM2NDVEMEY1QjlEMDFGRjcxQjUwMEE3NkZCRTdGRjhBQTVCMEI5QTZCMEZCOEY3QTYxQ0RCNzQxRTk5NzNDOUEwNDI0NURGN0U5MzlBQnwyAAABnZQtJsgyKZp42zbZ-0Z4oWrpA3YXiaHUTiSnXR609FFr-Gp8mXl0K2uZyfgHABD8oPi9bmzasngL_Wz-FTxJCZqjsaEPEy_FduILu2V9ZZicjLLe-w", "account_country": "USA", "session_token": "r1NSUQJqcNyXMokmn8eZ7kwyXJSKyZ+bfM6J1EO3EK+JWP5PGpyTXp2LoUGHTr14FeEigC9HrJ+Fldhzd+lFxZ5vwSik14II4CD3cJdJ0OS/+hJRQDEqfW4YPsYHia7RsWL7Bn9NcZ2V2CjwROu7KChcUT0Lpjwz2JVsfkX+h8m25H8Rh3jz5Osz+V7raXq5OlAOx7crzXt2dtuZm0zFlhg0X9lmI/NUmx3GlP4kou82pHPWcLQOa+i5sk86WsyjyhoeeCGS1ShuWch6+Cf+0G4ROe/6xSvnaNWU/Lqe8OMddybR0bbvkIAwsD7roIAxk0kRcL8k4MYUBByIw3C0KUKB1cJDdHTyoTJRq9UtUcH0vb+bbs4j2NfuJGO6k99/iG1yFNUj3X+DewCaEeKlb0sMw4Ja9BRfktZ8ql5/2blPa61cg9CNwUl93OXrJ58ux+QYHGKCQbT9v6YwGOLdfRZ24D9EV6n9nKeXrQg6xazO5R3EOtvmiGltLGFIhIWFb2L56juB1hahXXL4yJRL4w7x0kcPIFwdAFXQ0rJCqHWs/DiijrXDINFRgEeEJroyHKw/heO+yiGnHY8xLh51LoRR+5Wx55NJQm54z2P9JXKUqIjj5KPE1kbOBMJQXsUYL3aNVUbzPfDeOrsNCJ/3O0jjyoNfPvU/YPwCBGD5WjYhQJhvmk5J/QVTLantotSj2tU+NwN+BOiCDrs5cC+DKFTph0mN1xap3TSudHMSKNqlSGQ4kTAJaAcG2ECbraedI3b6WhjRPgiWx/fRCmpxpyPZvldFJq3QQXMM64hPQkk/8KG8D2ZLX1rKvZXZRKHo10PbRGYt8injSUjvgYf26+9sK2rCR/mngu0Rye+0fDG6BI4g2FfQ1v2vZW7Y7Q1UXhNxmXXZE/1Lgv7qm6gbHhOEO6JFCn2XfAt1Iee/purvYvkn0ldiuw20/3TNB6DR4AAQ/KEXuV7c", "trust_eligible": "true", "grant_code": "c9517c9fb90e44df386b19607971fb557.0.srzwz.W1TnJS7PpGpVTWSqASYfRw", "trust_token": "HSARMTKNSRVXWFlajR2ecD1662phQjqU9vXxnL49ZjypuVYYXHDpA3wTiX6Mf2J4WDlIhZj52z81aDOuz+VC80bVhV41TSNN4ggoPjW8WnsQrjniTQYkgJycPQNnzhkK4hfe2AMrr/bhrJJm8sHHc+Oh1HUckN6T7T4c1bmf2Qg9tRwsdRDNyMMyFH/Ml/cQlWKj39/YHlY=SRVX"}
|
{"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"}
|
||||||
BIN
geocache.db
BIN
geocache.db
Binary file not shown.
@@ -114,10 +114,10 @@ class LocationSimulationState:
|
|||||||
self.simulation_queue: asyncio.Queue = asyncio.Queue()
|
self.simulation_queue: asyncio.Queue = asyncio.Queue()
|
||||||
self.simulation_queue_data: Dict = {}
|
self.simulation_queue_data: Dict = {}
|
||||||
self.simulation_queue_order: list[str] = []
|
self.simulation_queue_order: list[str] = []
|
||||||
|
self.simulation_queue_deleted_items: list[str] = []
|
||||||
self.simulation_queue_pending_ids: set[str] = set()
|
self.simulation_queue_pending_ids: set[str] = set()
|
||||||
self.simulation_queue_state: str = "STOPPED"
|
self.simulation_queue_state: str = "STOPPED"
|
||||||
self.simulation_noise: bool = False
|
self.simulation_noise: bool = False
|
||||||
self.set_location_enabled: bool = True
|
|
||||||
self.simulation_active: bool = False
|
self.simulation_active: bool = False
|
||||||
self.simulation_task: Optional[asyncio.Task] = None
|
self.simulation_task: Optional[asyncio.Task] = None
|
||||||
self.sio: socketio.AsyncServer = socketio.AsyncServer(
|
self.sio: socketio.AsyncServer = socketio.AsyncServer(
|
||||||
@@ -642,6 +642,7 @@ class TunneldRunnerSio:
|
|||||||
"command": "start",
|
"command": "start",
|
||||||
"message": "Simulation started",
|
"message": "Simulation started",
|
||||||
"data": {
|
"data": {
|
||||||
|
|
||||||
"simulation_active": self.context.simulation_active,
|
"simulation_active": self.context.simulation_active,
|
||||||
"simulation_queue_state": self.context.simulation_queue_state
|
"simulation_queue_state": self.context.simulation_queue_state
|
||||||
}
|
}
|
||||||
@@ -667,10 +668,11 @@ class TunneldRunnerSio:
|
|||||||
try:
|
try:
|
||||||
if self.context.test_mode:
|
if self.context.test_mode:
|
||||||
logger.info("Simulation worker: test mode enabled")
|
logger.info("Simulation worker: test mode enabled")
|
||||||
with LocationSimulationTestQueue(self.context) as locate_simulation:
|
locate_simulation = LocationSimulationQueue(None, self.context)
|
||||||
await locate_simulation.play_queue()
|
await locate_simulation.play_queue()
|
||||||
|
return
|
||||||
|
|
||||||
if self.context.udid is None and not self.context.test_mode:
|
if self.context.udid is None:
|
||||||
active_udids = sorted(
|
active_udids = sorted(
|
||||||
{
|
{
|
||||||
t.udid
|
t.udid
|
||||||
@@ -841,7 +843,10 @@ class TunneldRunnerSio:
|
|||||||
"command_class": "simulation_control",
|
"command_class": "simulation_control",
|
||||||
"command": "add",
|
"command": "add",
|
||||||
"message": f"Location {loc_id} added to the queue",
|
"message": f"Location {loc_id} added to the queue",
|
||||||
"data": location_item,
|
"data": {
|
||||||
|
"simulation_queue": get_simulation_status(),
|
||||||
|
"location_item": location_item,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
add_item(loc_id, location_item)
|
add_item(loc_id, location_item)
|
||||||
await enqueue_next_simulation_item()
|
await enqueue_next_simulation_item()
|
||||||
@@ -854,6 +859,49 @@ class TunneldRunnerSio:
|
|||||||
"message": "Invalid location data", "data": data}
|
"message": "Invalid location data", "data": data}
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
async def delete_location_from_simulation_queue(data):
|
||||||
|
loc_id = (
|
||||||
|
data.get("loc_id")
|
||||||
|
if isinstance(data, dict)
|
||||||
|
else getattr(data, "loc_id", None)
|
||||||
|
)
|
||||||
|
if loc_id is not None:
|
||||||
|
if not loc_id in self.context.simulation_queue_order:
|
||||||
|
resp = {
|
||||||
|
"command_status": "ERROR",
|
||||||
|
"command_class": "simulation_control",
|
||||||
|
"command": "delete",
|
||||||
|
"message": f"Location {loc_id} not found in the queue",
|
||||||
|
"data": {
|
||||||
|
"simulation_queue": get_simulation_status(),
|
||||||
|
"location_item": self.context.simulation_queue_data[loc_id],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
logger.info("Deleting location %s from the queue", loc_id)
|
||||||
|
await delete_item(loc_id)
|
||||||
|
resp = {
|
||||||
|
"command_status": "OK",
|
||||||
|
"command_class": "simulation_control",
|
||||||
|
"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],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
resp = {
|
||||||
|
"command_status": "ERROR",
|
||||||
|
"command_class": "simulation_control",
|
||||||
|
"command": "delete",
|
||||||
|
"message": "Invalid location data",
|
||||||
|
"data": {
|
||||||
|
"simulation_queue:": get_simulation_status(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return resp
|
||||||
|
|
||||||
async def pause_simulation_queue():
|
async def pause_simulation_queue():
|
||||||
"""Pauses asyncio.Queue playback"""
|
"""Pauses asyncio.Queue playback"""
|
||||||
self.context.simulation_queue_state = "PAUSED"
|
self.context.simulation_queue_state = "PAUSED"
|
||||||
@@ -864,7 +912,8 @@ class TunneldRunnerSio:
|
|||||||
await update_queue_times()
|
await update_queue_times()
|
||||||
|
|
||||||
async def advance_simulation_queue():
|
async def advance_simulation_queue():
|
||||||
self.context.simulation_queue_state = "NEXT"
|
current_loc_id = self.context.get_current_loc_id()
|
||||||
|
self.context.simulation_queue_data[current_loc_id]["delay"] = 0
|
||||||
await update_queue_times()
|
await update_queue_times()
|
||||||
|
|
||||||
async def update_queue_times():
|
async def update_queue_times():
|
||||||
@@ -885,23 +934,12 @@ class TunneldRunnerSio:
|
|||||||
await update_queue_data()
|
await update_queue_data()
|
||||||
|
|
||||||
async def update_queue_data():
|
async def update_queue_data():
|
||||||
data = {
|
await self.context.sio.emit("queue_data_update", get_simulation_status(), namespace="/")
|
||||||
"simulation_queue": {
|
|
||||||
"active": self.context.simulation_active,
|
|
||||||
"data": self.context.simulation_queue_data,
|
|
||||||
"order": self.context.simulation_queue_order,
|
|
||||||
"state": self.context.simulation_queue_state,
|
|
||||||
"worker_task": self.context.simulation_task.get_name() if self.context.simulation_task else None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await self.context.sio.emit("queue_data_update", {
|
|
||||||
"data": data}, namespace="/")
|
|
||||||
|
|
||||||
async def empty_simulation_queue():
|
async def empty_simulation_queue():
|
||||||
"""Empties all items from an asyncio.Queue."""
|
"""Empties all items from an asyncio.Queue."""
|
||||||
logger.info("Clearing location simulation queue...")
|
logger.info("Clearing location simulation queue...")
|
||||||
q = self.context.simulation_queue
|
q = self.context.simulation_queue
|
||||||
self.context.set_location_enabled = False
|
|
||||||
while not q.empty():
|
while not q.empty():
|
||||||
try:
|
try:
|
||||||
item = q.get_nowait()
|
item = q.get_nowait()
|
||||||
@@ -926,6 +964,7 @@ class TunneldRunnerSio:
|
|||||||
def reset_queue():
|
def reset_queue():
|
||||||
self.context.simulation_queue_data = {}
|
self.context.simulation_queue_data = {}
|
||||||
self.context.simulation_queue_order = []
|
self.context.simulation_queue_order = []
|
||||||
|
self.context.simulation_queue_deleted_items = []
|
||||||
self.context.set_current_loc_id(None)
|
self.context.set_current_loc_id(None)
|
||||||
|
|
||||||
def remove_future_items():
|
def remove_future_items():
|
||||||
@@ -938,12 +977,16 @@ class TunneldRunnerSio:
|
|||||||
else:
|
else:
|
||||||
self.context.simulation_queue_data = {}
|
self.context.simulation_queue_data = {}
|
||||||
self.context.simulation_queue_order = []
|
self.context.simulation_queue_order = []
|
||||||
|
self.context.simulation_queue_deleted_items = []
|
||||||
self.context.set_current_loc_id(None)
|
self.context.set_current_loc_id(None)
|
||||||
|
|
||||||
|
|
||||||
def clear_item(item_id):
|
async def delete_item(item_id):
|
||||||
if item_id in self.context.simulation_queue_order:
|
if item_id in self.context.simulation_queue_order:
|
||||||
self.context.simulation_queue_data[item_id]["status"] = "deleted"
|
self.context.simulation_queue_data[item_id]["status"] = "deleted"
|
||||||
|
self.context.simulation_queue_order.remove(item_id)
|
||||||
|
self.context.simulation_queue_deleted_items.append(item_id)
|
||||||
|
await update_queue_times()
|
||||||
|
|
||||||
def clear_future_items():
|
def clear_future_items():
|
||||||
current_loc_id = self.context.get_current_loc_id()
|
current_loc_id = self.context.get_current_loc_id()
|
||||||
@@ -951,6 +994,8 @@ class TunneldRunnerSio:
|
|||||||
current_loc_id) if current_loc_id else 0
|
current_loc_id) if current_loc_id else 0
|
||||||
for item in self.context.simulation_queue_order[current_index + 1:]:
|
for item in self.context.simulation_queue_order[current_index + 1:]:
|
||||||
self.context.simulation_queue_data[item]["status"] = "deleted"
|
self.context.simulation_queue_data[item]["status"] = "deleted"
|
||||||
|
self.context.simulation_queue_order.remove(item)
|
||||||
|
self.context.simulation_queue_deleted_items.append(item)
|
||||||
|
|
||||||
def get_item(item_id):
|
def get_item(item_id):
|
||||||
return self.context.simulation_queue_data[item_id]
|
return self.context.simulation_queue_data[item_id]
|
||||||
@@ -1006,20 +1051,13 @@ class TunneldRunnerSio:
|
|||||||
end_simulation_worker(), name="end-simulation-worker"
|
end_simulation_worker(), name="end-simulation-worker"
|
||||||
)
|
)
|
||||||
result = await end_task
|
result = await end_task
|
||||||
data = {
|
return result
|
||||||
"command_status": "OK",
|
|
||||||
"command_class": "simulation_control",
|
|
||||||
"command": "end",
|
|
||||||
"message": "Simulation ended"
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
|
|
||||||
async def end_simulation_worker() -> bool:
|
async def end_simulation_worker() -> bool:
|
||||||
"""Ends asyncio.Queue playback and closes tunnel"""
|
"""Ends asyncio.Queue playback and closes tunnel"""
|
||||||
logger.info("End location simulation request")
|
logger.info("End location simulation request")
|
||||||
try:
|
try:
|
||||||
q = self.context.simulation_queue
|
q = self.context.simulation_queue
|
||||||
self.context.set_location_enabled = False
|
|
||||||
self.context.simulation_queue_state = "SHUTDOWN"
|
self.context.simulation_queue_state = "SHUTDOWN"
|
||||||
|
|
||||||
# Drain pending queue entries.
|
# Drain pending queue entries.
|
||||||
@@ -1056,7 +1094,6 @@ class TunneldRunnerSio:
|
|||||||
await locate_simulation.clear()
|
await locate_simulation.clear()
|
||||||
self.context.simulation_active = False
|
self.context.simulation_active = False
|
||||||
self.context.simulation_task = None
|
self.context.simulation_task = None
|
||||||
self.context.set_location_enabled = True
|
|
||||||
self.context.next_move = None
|
self.context.next_move = None
|
||||||
self.context.set_current_loc_id(None)
|
self.context.set_current_loc_id(None)
|
||||||
self.context.simulation_queue_state = "STOPPED"
|
self.context.simulation_queue_state = "STOPPED"
|
||||||
@@ -1079,6 +1116,19 @@ class TunneldRunnerSio:
|
|||||||
self.context.simulation_noise = not self.context.simulation_noise
|
self.context.simulation_noise = not self.context.simulation_noise
|
||||||
return {"simulation_noise": self.context.simulation_noise}
|
return {"simulation_noise": self.context.simulation_noise}
|
||||||
|
|
||||||
|
def get_simulation_status() -> dict:
|
||||||
|
resp = {
|
||||||
|
"active": self.context.simulation_active,
|
||||||
|
"data": self.context.simulation_queue_data,
|
||||||
|
"order": self.context.simulation_queue_order,
|
||||||
|
"deleted_items": self.context.simulation_queue_deleted_items,
|
||||||
|
"state": self.context.simulation_queue_state,
|
||||||
|
"gps_noise": self.context.simulation_noise,
|
||||||
|
"worker_task": self.context.simulation_task.get_name() if self.context.simulation_task else None,
|
||||||
|
"test_mode": self.context.test_mode,
|
||||||
|
}
|
||||||
|
return resp
|
||||||
|
|
||||||
def get_status() -> dict:
|
def get_status() -> dict:
|
||||||
current_loc_id = self.context.get_current_loc_id()
|
current_loc_id = self.context.get_current_loc_id()
|
||||||
current_item = self.context.simulation_queue_data.get(
|
current_item = self.context.simulation_queue_data.get(
|
||||||
@@ -1111,16 +1161,7 @@ class TunneldRunnerSio:
|
|||||||
},
|
},
|
||||||
"tunnel_watcher_running": True if self.context.tunnel_watcher_task and not self.context.tunnel_watcher_task.done() else False,
|
"tunnel_watcher_running": True if self.context.tunnel_watcher_task and not self.context.tunnel_watcher_task.done() else False,
|
||||||
"next_move": self.context.next_move,
|
"next_move": self.context.next_move,
|
||||||
"simulation_queue": {
|
"simulation_queue": get_simulation_status(),
|
||||||
"active": self.context.simulation_active,
|
|
||||||
"data": self.context.simulation_queue_data,
|
|
||||||
"order": self.context.simulation_queue_order,
|
|
||||||
"state": self.context.simulation_queue_state,
|
|
||||||
"gps_noise": self.context.simulation_noise,
|
|
||||||
"worker_task": self.context.simulation_task.get_name() if self.context.simulation_task else None,
|
|
||||||
},
|
|
||||||
"set_location_enable": self.context.set_location_enabled,
|
|
||||||
"test_mode": self.context.test_mode,
|
|
||||||
"tunnel": self.context.tunnel.service.address[0] if self.context.tunnel else None,
|
"tunnel": self.context.tunnel.service.address[0] if self.context.tunnel else None,
|
||||||
"udid": self.context.udid,
|
"udid": self.context.udid,
|
||||||
}
|
}
|
||||||
@@ -1648,58 +1689,96 @@ class TunneldRunnerSio:
|
|||||||
try:
|
try:
|
||||||
match command:
|
match command:
|
||||||
case "next":
|
case "next":
|
||||||
resp = await advance_simulation_queue()
|
await advance_simulation_queue()
|
||||||
|
resp = {
|
||||||
|
"command": command,
|
||||||
|
"command_class": "simulation_control",
|
||||||
|
"command_status": "OK",
|
||||||
|
"message": "Advanced simulation queue",
|
||||||
|
"data": {
|
||||||
|
"simulation_queue": get_simulation_status(),
|
||||||
|
}
|
||||||
|
}
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
case "test-mode":
|
case "test-mode":
|
||||||
data = toggle_test_mode()
|
toggle_test_mode()
|
||||||
return {
|
resp = {
|
||||||
"command": command,
|
"command": command,
|
||||||
"command_class": "simulation_control",
|
"command_class": "simulation_control",
|
||||||
"command_status": "OK",
|
"command_status": "OK",
|
||||||
"message": "test-mode toggled",
|
"message": "test-mode toggled",
|
||||||
"data": data
|
"data": {
|
||||||
|
"simulation_queue": get_simulation_status(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return resp
|
||||||
|
|
||||||
case "add":
|
case "add":
|
||||||
""" Add a location to the simulation queue"""
|
""" Add a location to the simulation queue"""
|
||||||
resp = await add_location_to_simulation_queue(data)
|
resp = await add_location_to_simulation_queue(data)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
case "delete":
|
||||||
|
""" Delete a location to the simulation queue"""
|
||||||
|
resp = await delete_location_from_simulation_queue(data)
|
||||||
|
return resp
|
||||||
|
|
||||||
case "clear":
|
case "clear":
|
||||||
""" Clear the simulation queue"""
|
""" Clear the simulation queue"""
|
||||||
clear_future_items()
|
clear_future_items()
|
||||||
return {
|
resp = {
|
||||||
"command": command,
|
"command": command,
|
||||||
"command_class": "simulation_control",
|
"command_class": "simulation_control",
|
||||||
"command_status": "OK",
|
"command_status": "OK",
|
||||||
"message": "Simulation cleared",
|
"message": "Simulation cleared",
|
||||||
|
"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()
|
||||||
return {
|
resp = {
|
||||||
"command": command,
|
"command": command,
|
||||||
"command_class": "simulation_control",
|
"command_class": "simulation_control",
|
||||||
"command_status": "OK",
|
"command_status": "OK",
|
||||||
"message": "Simulation paused",
|
"message": "Simulation paused",
|
||||||
|
"data": {
|
||||||
|
"simulation_queue": get_simulation_status(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return resp
|
||||||
case "resume":
|
case "resume":
|
||||||
""" Resume the simulation queue"""
|
""" Resume the simulation queue"""
|
||||||
await resume_simulation_queue()
|
await resume_simulation_queue()
|
||||||
return {
|
resp = {
|
||||||
"command": command,
|
"command": command,
|
||||||
"command_status": "OK",
|
"command_status": "OK",
|
||||||
"command_class": "simulation_control",
|
"command_class": "simulation_control",
|
||||||
"message": "Simulation resumed",
|
"message": "Simulation resumed",
|
||||||
|
"data": {
|
||||||
|
"simulation_queue": get_simulation_status(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return resp
|
||||||
case "end":
|
case "end":
|
||||||
""" End the simulation queue"""
|
""" End the simulation queue"""
|
||||||
logger.info(
|
logger.info(
|
||||||
"End location simulation request from %s", sid)
|
"End location simulation request from %s", sid)
|
||||||
data = await end_simulation_queue()
|
cstat = "OK" if await end_simulation_queue() else "ERROR"
|
||||||
return data
|
resp = {
|
||||||
|
"command_status": cstat,
|
||||||
|
"command_class": "simulation_control",
|
||||||
|
"command": command,
|
||||||
|
"message": "Simulation ended",
|
||||||
|
"data": {
|
||||||
|
"simulation_queue": get_simulation_status(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp
|
||||||
case "start":
|
case "start":
|
||||||
""" Start the simulation queue"""
|
""" Start the simulation queue"""
|
||||||
logger.info(
|
logger.info(
|
||||||
@@ -1709,19 +1788,24 @@ class TunneldRunnerSio:
|
|||||||
case "gps-noise":
|
case "gps-noise":
|
||||||
""" Toggle GPS noise"""
|
""" Toggle GPS noise"""
|
||||||
before_toggle = self.context.simulation_noise
|
before_toggle = self.context.simulation_noise
|
||||||
data = toggle_gps_noise()
|
toggle_gps_noise()
|
||||||
data['command_status'] = "OK"
|
resp = {
|
||||||
data['command_class'] = "simulation_control"
|
"command_status": "OK",
|
||||||
data['message'] = f"GPS noise toggled from {
|
"command_class": "simulation_control",
|
||||||
before_toggle} to {self.context.simulation_noise}"
|
"command": command,
|
||||||
data['command'] = command
|
"message": f"GPS noise toggled from {before_toggle} to {self.context.simulation_noise}",
|
||||||
return data
|
"data": {
|
||||||
|
"simulation_queue": get_simulation_status(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp
|
||||||
case _:
|
case _:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Invalid command received from %s: %s", sid, command
|
"Invalid command received from %s: %s", sid, command
|
||||||
)
|
)
|
||||||
return {"command_status": "ERROR", "message": "Invalid command"}
|
return {"command_status": "ERROR", "message": "Invalid command"}
|
||||||
finally:
|
finally:
|
||||||
|
logger.info("Simulation Control command: %s completed, sending status update...", command)
|
||||||
await sio_send_status(sid)
|
await sio_send_status(sid)
|
||||||
|
|
||||||
@self.context.sio.event
|
@self.context.sio.event
|
||||||
@@ -1754,6 +1838,37 @@ class TunneldRunnerSio:
|
|||||||
else:
|
else:
|
||||||
return {"command_status": "ERROR", "command": "update", "command_class": "location_item", "message": "Invalid request, Location Item Unchanged", "data": self.context.simulation_queue_data[loc_id]}
|
return {"command_status": "ERROR", "command": "update", "command_class": "location_item", "message": "Invalid request, Location Item Unchanged", "data": self.context.simulation_queue_data[loc_id]}
|
||||||
|
|
||||||
|
@self.context.sio.event
|
||||||
|
async def queue_order_update(sid, data):
|
||||||
|
logger.info("Queue order update received: %s", data)
|
||||||
|
new_simulation_queue_order = []
|
||||||
|
new_order = (
|
||||||
|
data.get("newOrder")
|
||||||
|
if isinstance(data, dict)
|
||||||
|
else getattr(data, "newOrder", None)
|
||||||
|
)
|
||||||
|
if new_order:
|
||||||
|
for item in new_order:
|
||||||
|
if item in self.context.simulation_queue_data:
|
||||||
|
new_simulation_queue_order.append(item)
|
||||||
|
self.context.simulation_queue_order = new_simulation_queue_order
|
||||||
|
resp = {
|
||||||
|
"command_status": "OK",
|
||||||
|
"command": "queue_order_update",
|
||||||
|
"command_class": "queue_order",
|
||||||
|
"message": "Queue Order Updated",
|
||||||
|
"data": self.context.simulation_queue_order
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
resp = {
|
||||||
|
"command_status": "ERROR",
|
||||||
|
"command": "queue_order_update",
|
||||||
|
"command_class": "queue_order",
|
||||||
|
"message": "Invalid request, Queue Order Unchanged",
|
||||||
|
"data": self.context.simulation_queue_order
|
||||||
|
}
|
||||||
|
return resp
|
||||||
|
|
||||||
@self.context.sio.event
|
@self.context.sio.event
|
||||||
async def icloud_monitor_control(sid, data):
|
async def icloud_monitor_control(sid, data):
|
||||||
command = (
|
command = (
|
||||||
@@ -1961,7 +2076,10 @@ class TunneldRunnerSio:
|
|||||||
|
|
||||||
class LocationSimulationQueue(LocationSimulation):
|
class LocationSimulationQueue(LocationSimulation):
|
||||||
def __init__(self, dvt, context: LocationSimulationState):
|
def __init__(self, dvt, context: LocationSimulationState):
|
||||||
super().__init__(dvt)
|
if dvt is None:
|
||||||
|
LocationSimulationBase.__init__(self)
|
||||||
|
else:
|
||||||
|
super().__init__(dvt)
|
||||||
self.context = context
|
self.context = context
|
||||||
self._dt_simulate_location = None
|
self._dt_simulate_location = None
|
||||||
self._prefer_dt_simulate_location = False
|
self._prefer_dt_simulate_location = False
|
||||||
@@ -1981,6 +2099,10 @@ class LocationSimulationQueue(LocationSimulation):
|
|||||||
return self._dt_simulate_location
|
return self._dt_simulate_location
|
||||||
|
|
||||||
async def set(self, latitude: float, longitude: float) -> None:
|
async def set(self, latitude: float, longitude: float) -> None:
|
||||||
|
if self.context.test_mode:
|
||||||
|
await asyncio.sleep(0.1)
|
||||||
|
logger.info("Test mode enabled, simulated location set to %s, %s", latitude, longitude)
|
||||||
|
return
|
||||||
if not self._prefer_dt_simulate_location:
|
if not self._prefer_dt_simulate_location:
|
||||||
try:
|
try:
|
||||||
await super().set(latitude, longitude)
|
await super().set(latitude, longitude)
|
||||||
@@ -1994,6 +2116,9 @@ class LocationSimulationQueue(LocationSimulation):
|
|||||||
await fallback.set(latitude, longitude)
|
await fallback.set(latitude, longitude)
|
||||||
|
|
||||||
async def clear(self) -> None:
|
async def clear(self) -> None:
|
||||||
|
if self.context.test_mode:
|
||||||
|
logger.info("Test mode enabled, skipping location clear")
|
||||||
|
return
|
||||||
dvt_clear_error = None
|
dvt_clear_error = None
|
||||||
if not self._prefer_dt_simulate_location:
|
if not self._prefer_dt_simulate_location:
|
||||||
try:
|
try:
|
||||||
@@ -2036,8 +2161,6 @@ class LocationSimulationQueue(LocationSimulation):
|
|||||||
break
|
break
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
if self.context.simulation_queue_state == "SHUTDOWN":
|
||||||
break
|
break
|
||||||
if not self.context.set_location_enabled:
|
|
||||||
continue
|
|
||||||
if not self.context.simulation_noise:
|
if not self.context.simulation_noise:
|
||||||
continue
|
continue
|
||||||
if self.context.get_current_loc_id() != loc_id:
|
if self.context.get_current_loc_id() != loc_id:
|
||||||
@@ -2064,16 +2187,16 @@ class LocationSimulationQueue(LocationSimulation):
|
|||||||
|
|
||||||
async def _update_queue_data(self):
|
async def _update_queue_data(self):
|
||||||
data = {
|
data = {
|
||||||
"simulation_queue": {
|
|
||||||
"active": self.context.simulation_active,
|
"active": self.context.simulation_active,
|
||||||
"data": self.context.simulation_queue_data,
|
"data": self.context.simulation_queue_data,
|
||||||
"order": self.context.simulation_queue_order,
|
"order": self.context.simulation_queue_order,
|
||||||
|
"deleted_items": self.context.simulation_queue_deleted_items,
|
||||||
"state": self.context.simulation_queue_state,
|
"state": self.context.simulation_queue_state,
|
||||||
"worker_task": self.context.simulation_task.get_name() if self.context.simulation_task else None,
|
"worker_task": self.context.simulation_task.get_name() if self.context.simulation_task else None,
|
||||||
|
"gps_noise": self.context.simulation_noise,
|
||||||
|
"test_mode": self.context.test_mode,
|
||||||
}
|
}
|
||||||
}
|
await self.context.sio.emit("queue_data_update", data, namespace="/")
|
||||||
await self.context.sio.emit("queue_data_update", {
|
|
||||||
"data": data}, namespace="/")
|
|
||||||
|
|
||||||
async def _update_location_item(self, loc_id: str) -> None:
|
async def _update_location_item(self, loc_id: str) -> None:
|
||||||
await self.context.sio.emit(
|
await self.context.sio.emit(
|
||||||
@@ -2085,6 +2208,18 @@ class LocationSimulationQueue(LocationSimulation):
|
|||||||
namespace="/",
|
namespace="/",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def _update_current_location(self, active_loc_id, new_latitude, new_longitude) -> None:
|
||||||
|
await self.context.sio.emit(
|
||||||
|
"simulation_status",
|
||||||
|
{
|
||||||
|
"status": self.context.simulation_active,
|
||||||
|
"loc_id": active_loc_id,
|
||||||
|
"latitude": new_latitude,
|
||||||
|
"longitude": new_longitude
|
||||||
|
},
|
||||||
|
namespace="/",
|
||||||
|
)
|
||||||
|
|
||||||
async def _enqueue_next_queue_item(self) -> Optional[str]:
|
async def _enqueue_next_queue_item(self) -> Optional[str]:
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
if self.context.simulation_queue_state == "SHUTDOWN":
|
||||||
return None
|
return None
|
||||||
@@ -2156,321 +2291,30 @@ class LocationSimulationQueue(LocationSimulation):
|
|||||||
if isinstance(current_location_item, dict)
|
if isinstance(current_location_item, dict)
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
while self.context.simulation_queue_data[loc_id]["delay"] > 0:
|
||||||
if self.context.set_location_enabled:
|
|
||||||
while self.context.simulation_queue_data[loc_id]["delay"] > 0:
|
|
||||||
if self.context.simulation_queue_state == "NEXT":
|
|
||||||
self.context.simulation_queue_state = "RUNNING"
|
|
||||||
break
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
|
||||||
break
|
|
||||||
while self.context.simulation_queue_state == "PAUSED":
|
|
||||||
await asyncio.sleep(0.1)
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
|
||||||
break
|
|
||||||
if self.context.simulation_queue_state == "NEXT":
|
|
||||||
self.context.simulation_queue_state = "RUNNING"
|
|
||||||
break
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
|
||||||
break
|
|
||||||
self.context.next_move = location_item.get("delay") - 1
|
|
||||||
self.context.simulation_queue_data[loc_id]["delay"] -= 1
|
|
||||||
# await self.context.sio.emit(
|
|
||||||
# "simulation_status",
|
|
||||||
# {
|
|
||||||
# "status": self.context.simulation_active,
|
|
||||||
# "loc_id": current_loc_id,
|
|
||||||
# "latitude": current_latitude,
|
|
||||||
# "longitude": current_longitude,
|
|
||||||
# "start": current_start,
|
|
||||||
# "next_move": self.context.next_move,
|
|
||||||
# },
|
|
||||||
# namespace="/",
|
|
||||||
# )
|
|
||||||
await self._update_location_item(loc_id)
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
if self.context.simulation_queue_state == "SHUTDOWN":
|
||||||
self.context.simulation_queue_pending_ids.discard(loc_id)
|
|
||||||
self.context.simulation_queue.task_done()
|
|
||||||
break
|
break
|
||||||
self.context.simulation_queue_data[loc_id]["start"] = datetime.now(
|
while self.context.simulation_queue_state == "PAUSED":
|
||||||
timezone.utc).isoformat()
|
await asyncio.sleep(0.1)
|
||||||
if current_loc_id is not None:
|
if self.context.simulation_queue_state == "SHUTDOWN":
|
||||||
self.context.simulation_queue_data[current_loc_id]["status"] = "done"
|
break
|
||||||
self.context.simulation_queue_data[current_loc_id]["end"] = datetime.now(
|
if self.context.simulation_queue_state == "SHUTDOWN":
|
||||||
timezone.utc).isoformat()
|
break
|
||||||
await self._update_location_item(current_loc_id)
|
self.context.next_move = location_item.get("delay") - 1
|
||||||
await self._update_queue_data()
|
self.context.simulation_queue_data[loc_id]["delay"] -= 1
|
||||||
await self._stop_noise_task()
|
await self._update_location_item(loc_id)
|
||||||
await self.set(new_latitude, new_longitude)
|
await asyncio.sleep(1)
|
||||||
self.context.simulation_queue_data[loc_id]["status"] = "set"
|
|
||||||
self.context.set_current_loc_id(loc_id)
|
|
||||||
if self.context.simulation_noise:
|
|
||||||
self._start_noise_task(
|
|
||||||
loc_id, new_latitude, new_longitude)
|
|
||||||
active_loc_id = self.context.get_current_loc_id()
|
|
||||||
# await self.context.sio.emit(
|
|
||||||
# "simulation_status",
|
|
||||||
# {
|
|
||||||
# "status": self.context.simulation_active,
|
|
||||||
# "loc_id": active_loc_id,
|
|
||||||
# "latitude": new_latitude,
|
|
||||||
# "longitude": new_longitude,
|
|
||||||
# "start": new_start,
|
|
||||||
# "next_move": None,
|
|
||||||
# },
|
|
||||||
# namespace="/",
|
|
||||||
# )
|
|
||||||
logger.info(
|
|
||||||
"Set simulated location to %s, %s after %ss delay",
|
|
||||||
new_latitude,
|
|
||||||
new_longitude,
|
|
||||||
new_delay,
|
|
||||||
)
|
|
||||||
await self._update_queue_data()
|
|
||||||
self.context.simulation_queue_pending_ids.discard(loc_id)
|
|
||||||
self.context.simulation_queue.task_done()
|
|
||||||
await self._enqueue_next_queue_item()
|
|
||||||
finally:
|
|
||||||
await self._stop_noise_task()
|
|
||||||
|
|
||||||
|
|
||||||
class LocationSimulationTestQueue(LocationSimulationBase):
|
|
||||||
def __init__(self, context: LocationSimulationState):
|
|
||||||
super().__init__()
|
|
||||||
self.context = context
|
|
||||||
self._noise_task: Optional[asyncio.Task] = None
|
|
||||||
self._noise_loc_id: Optional[str] = None
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __exit__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def set(self, latitude: float, longitude: float) -> None:
|
|
||||||
await asyncio.sleep(0.1)
|
|
||||||
logger.info("Simulated location set to %s, %s", latitude, longitude)
|
|
||||||
|
|
||||||
async def clear(self) -> None:
|
|
||||||
q = self.context.simulation_queue
|
|
||||||
self.context.set_location_enabled = False
|
|
||||||
self.context.simulation_queue_state = "SHUTDOWN"
|
|
||||||
while not q.empty():
|
|
||||||
try:
|
|
||||||
item = q.get_nowait()
|
|
||||||
if isinstance(item, str):
|
|
||||||
self.context.simulation_queue_pending_ids.discard(item)
|
|
||||||
q.task_done()
|
|
||||||
logger.info("Discarding item from queue: %s", item)
|
|
||||||
except asyncio.QueueEmpty:
|
|
||||||
break
|
|
||||||
self.context.simulation_queue_pending_ids.clear()
|
|
||||||
await q.put(None)
|
|
||||||
|
|
||||||
if self.context.simulation_task is not None and not self.context.simulation_task.done():
|
|
||||||
try:
|
|
||||||
await asyncio.wait_for(self.context.simulation_task, timeout=5)
|
|
||||||
except TimeoutError:
|
|
||||||
self.context.simulation_task.cancel()
|
|
||||||
with suppress(asyncio.CancelledError):
|
|
||||||
await self.context.simulation_task
|
|
||||||
self.context.simulation_active = False
|
|
||||||
self.context.simulation_queue_state = "SHUTDOWN"
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _add_gps_noise(lat: float, lon: float, std_dev_meters: float = 5.0) -> tuple[float, float]:
|
|
||||||
"""Apply Gaussian jitter in meters and convert to lat/lon deltas."""
|
|
||||||
earth_radius = 6378137.0
|
|
||||||
lat_sigma_deg = (std_dev_meters / earth_radius) * (180.0 / math.pi)
|
|
||||||
cos_lat = math.cos(math.radians(lat))
|
|
||||||
if abs(cos_lat) < 1e-6:
|
|
||||||
cos_lat = 1e-6
|
|
||||||
lon_sigma_deg = (std_dev_meters / (earth_radius *
|
|
||||||
cos_lat)) * (180.0 / math.pi)
|
|
||||||
noised_lat = lat + random.gauss(0.0, lat_sigma_deg)
|
|
||||||
noised_lon = lon + random.gauss(0.0, lon_sigma_deg)
|
|
||||||
return noised_lat, noised_lon
|
|
||||||
|
|
||||||
async def _stop_noise_task(self) -> None:
|
|
||||||
if self._noise_task is not None:
|
|
||||||
self._noise_task.cancel()
|
|
||||||
with suppress(asyncio.CancelledError):
|
|
||||||
await self._noise_task
|
|
||||||
self._noise_task = None
|
|
||||||
self._noise_loc_id = None
|
|
||||||
|
|
||||||
async def _noise_loop(self, loc_id: str, base_latitude: float, base_longitude: float) -> None:
|
|
||||||
while True:
|
|
||||||
await asyncio.sleep(random.randint(45, 180))
|
|
||||||
if not self.context.simulation_active:
|
|
||||||
break
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
|
||||||
break
|
|
||||||
if not self.context.set_location_enabled:
|
|
||||||
continue
|
|
||||||
if not self.context.simulation_noise:
|
|
||||||
continue
|
|
||||||
if self.context.get_current_loc_id() != loc_id:
|
|
||||||
break
|
|
||||||
noised_latitude, noised_longitude = self._add_gps_noise(
|
|
||||||
base_latitude, base_longitude
|
|
||||||
)
|
|
||||||
await self.set(noised_latitude, noised_longitude)
|
|
||||||
logger.info(
|
|
||||||
"Applied simulation noise to active location loc_id=%s sent=%s,%s base=%s,%s",
|
|
||||||
loc_id,
|
|
||||||
noised_latitude,
|
|
||||||
noised_longitude,
|
|
||||||
base_latitude,
|
|
||||||
base_longitude,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _start_noise_task(self, loc_id: str, base_latitude: float, base_longitude: float) -> None:
|
|
||||||
self._noise_loc_id = loc_id
|
|
||||||
self._noise_task = asyncio.create_task(
|
|
||||||
self._noise_loop(loc_id, base_latitude, base_longitude),
|
|
||||||
name=f"simulation-noise-{loc_id}",
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _update_queue_data(self):
|
|
||||||
data = {
|
|
||||||
"simulation_queue": {
|
|
||||||
"active": self.context.simulation_active,
|
|
||||||
"data": self.context.simulation_queue_data,
|
|
||||||
"order": self.context.simulation_queue_order,
|
|
||||||
"state": self.context.simulation_queue_state,
|
|
||||||
"worker_task": self.context.simulation_task.get_name() if self.context.simulation_task else None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await self.context.sio.emit("queue_data_update", {
|
|
||||||
"data": data}, namespace="/")
|
|
||||||
|
|
||||||
async def _update_location_item(self, loc_id: str) -> None:
|
|
||||||
await self.context.sio.emit(
|
|
||||||
"location_item_update",
|
|
||||||
{
|
|
||||||
"loc_id": loc_id,
|
|
||||||
"data": self.context.simulation_queue_data[loc_id]
|
|
||||||
},
|
|
||||||
namespace="/",
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _enqueue_next_queue_item(self) -> Optional[str]:
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
|
||||||
return None
|
|
||||||
for item_id in self.context.simulation_queue_order:
|
|
||||||
if item_id in self.context.simulation_queue_pending_ids:
|
|
||||||
continue
|
|
||||||
item = self.context.simulation_queue_data.get(item_id)
|
|
||||||
if not isinstance(item, dict):
|
|
||||||
continue
|
|
||||||
if item.get("status") != "queued":
|
|
||||||
continue
|
|
||||||
self.context.simulation_queue_pending_ids.add(item_id)
|
|
||||||
await self.context.simulation_queue.put(item_id)
|
|
||||||
logger.info("Worker scheduled queue item %s", item_id)
|
|
||||||
return item_id
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def play_queue(
|
|
||||||
self, disable_sleep: bool = False, timing_randomness_range: int = 0
|
|
||||||
) -> None:
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
if self.context.simulation_queue_state == "PAUSED":
|
|
||||||
await asyncio.sleep(0.1)
|
|
||||||
continue
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
if self.context.simulation_queue_state == "SHUTDOWN":
|
||||||
break
|
|
||||||
await self._enqueue_next_queue_item()
|
|
||||||
loc_id = await self.context.simulation_queue.get()
|
|
||||||
if loc_id is None:
|
|
||||||
self.context.simulation_queue.task_done()
|
|
||||||
break
|
|
||||||
location_item = self.context.simulation_queue_data.get(loc_id)
|
|
||||||
if location_item is None:
|
|
||||||
logger.warning(
|
|
||||||
"Test simulation queue item missing for loc_id=%s; skipping stale entry",
|
|
||||||
loc_id,
|
|
||||||
)
|
|
||||||
self.context.simulation_queue_pending_ids.discard(loc_id)
|
self.context.simulation_queue_pending_ids.discard(loc_id)
|
||||||
self.context.simulation_queue.task_done()
|
self.context.simulation_queue.task_done()
|
||||||
await self._enqueue_next_queue_item()
|
break
|
||||||
continue
|
|
||||||
new_status = location_item.get("status")
|
|
||||||
if new_status == "deleted":
|
|
||||||
self.context.simulation_queue_pending_ids.discard(loc_id)
|
|
||||||
self.context.simulation_queue.task_done()
|
|
||||||
await self._enqueue_next_queue_item()
|
|
||||||
continue
|
|
||||||
new_latitude = location_item.get("latitude")
|
|
||||||
new_longitude = location_item.get("longitude")
|
|
||||||
new_delay = location_item.get("delay")
|
|
||||||
new_delay = 0 if new_delay is None else new_delay
|
|
||||||
new_start = location_item.get("start")
|
|
||||||
current_loc_id = self.context.get_current_loc_id()
|
|
||||||
current_location_item = self.context.simulation_queue_data.get(
|
|
||||||
current_loc_id) if current_loc_id else None
|
|
||||||
current_latitude = (
|
|
||||||
current_location_item.get("latitude")
|
|
||||||
if isinstance(current_location_item, dict)
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
current_longitude = (
|
|
||||||
current_location_item.get("longitude")
|
|
||||||
if isinstance(current_location_item, dict)
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
current_start = (
|
|
||||||
current_location_item.get("start")
|
|
||||||
if isinstance(current_location_item, dict)
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
if self.context.set_location_enabled:
|
|
||||||
while self.context.simulation_queue_data[loc_id]["delay"] > 0:
|
|
||||||
if self.context.simulation_queue_state == "NEXT":
|
|
||||||
self.context.simulation_queue_state = "RUNNING"
|
|
||||||
break
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
|
||||||
break
|
|
||||||
while self.context.simulation_queue_state == "PAUSED":
|
|
||||||
await asyncio.sleep(0.1)
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
|
||||||
break
|
|
||||||
if self.context.simulation_queue_state == "NEXT":
|
|
||||||
self.context.simulation_queue_state = "RUNNING"
|
|
||||||
break
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
|
||||||
break
|
|
||||||
self.context.next_move = location_item.get("delay") - 1
|
|
||||||
self.context.simulation_queue_data[loc_id]["delay"] -= 1
|
|
||||||
|
|
||||||
# await self.context.sio.emit(
|
|
||||||
# "simulation_status",
|
|
||||||
# {
|
|
||||||
# "status": self.context.simulation_active,
|
|
||||||
# "loc_id": current_loc_id,
|
|
||||||
# "latitude": current_latitude,
|
|
||||||
# "longitude": current_longitude,
|
|
||||||
# "start": current_start,
|
|
||||||
# "next_move": self.context.next_move,
|
|
||||||
# },
|
|
||||||
# namespace="/",
|
|
||||||
# )
|
|
||||||
|
|
||||||
await self._update_location_item(loc_id)
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
if self.context.simulation_queue_state == "SHUTDOWN":
|
|
||||||
self.context.simulation_queue_pending_ids.discard(loc_id)
|
|
||||||
self.context.simulation_queue.task_done()
|
|
||||||
break
|
|
||||||
self.context.simulation_queue_data[loc_id]["start"] = datetime.now(
|
self.context.simulation_queue_data[loc_id]["start"] = datetime.now(
|
||||||
timezone.utc).isoformat()
|
timezone.utc).isoformat()
|
||||||
if current_loc_id is not None:
|
if current_loc_id is not None:
|
||||||
self.context.simulation_queue_data[current_loc_id]["status"] = "done"
|
self.context.simulation_queue_data[current_loc_id]["status"] = "done"
|
||||||
self.context.simulation_queue_data[current_loc_id]["end"] = datetime.now(
|
self.context.simulation_queue_data[current_loc_id]["end"] = datetime.now(
|
||||||
timezone.utc).isoformat()
|
timezone.utc).isoformat()
|
||||||
|
self.context.simulation_queue_data[current_loc_id]["delay"] = new_delay
|
||||||
await self._update_location_item(current_loc_id)
|
await self._update_location_item(current_loc_id)
|
||||||
await self._update_queue_data()
|
await self._update_queue_data()
|
||||||
await self._stop_noise_task()
|
await self._stop_noise_task()
|
||||||
@@ -2478,22 +2322,11 @@ class LocationSimulationTestQueue(LocationSimulationBase):
|
|||||||
self.context.simulation_queue_data[loc_id]["status"] = "set"
|
self.context.simulation_queue_data[loc_id]["status"] = "set"
|
||||||
await self._update_location_item(loc_id)
|
await self._update_location_item(loc_id)
|
||||||
self.context.set_current_loc_id(loc_id)
|
self.context.set_current_loc_id(loc_id)
|
||||||
|
active_loc_id = self.context.get_current_loc_id()
|
||||||
|
await self._update_current_location(active_loc_id, new_latitude, new_longitude)
|
||||||
if self.context.simulation_noise:
|
if self.context.simulation_noise:
|
||||||
self._start_noise_task(
|
self._start_noise_task(
|
||||||
loc_id, new_latitude, new_longitude)
|
loc_id, new_latitude, new_longitude)
|
||||||
active_loc_id = self.context.get_current_loc_id()
|
|
||||||
# await self.context.sio.emit(
|
|
||||||
# "simulation_status",
|
|
||||||
# {
|
|
||||||
# "status": self.context.simulation_active,
|
|
||||||
# "loc_id": active_loc_id,
|
|
||||||
# "latitude": new_latitude,
|
|
||||||
# "longitude": new_longitude,
|
|
||||||
# "start": new_start,
|
|
||||||
# "next_move": None,
|
|
||||||
# },
|
|
||||||
# namespace="/",
|
|
||||||
# )
|
|
||||||
logger.info(
|
logger.info(
|
||||||
"Set simulated location to %s, %s after %ss delay",
|
"Set simulated location to %s, %s after %ss delay",
|
||||||
new_latitude,
|
new_latitude,
|
||||||
|
|||||||
Reference in New Issue
Block a user