ksaa 2025.11b1__py3-none-any.whl → 2025.11b3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. kaa/application/core/feedback_service.py +121 -0
  2. kaa/application/core/misc_core.py +4 -1
  3. kaa/application/core/update_service.py +208 -0
  4. kaa/config/schema.py +6 -0
  5. kaa/errors.py +60 -0
  6. kaa/main/gr.py +106 -516
  7. kaa/main/kaa.py +11 -3
  8. kaa/metadata.py +10 -0
  9. kaa/resources/__pycache__/__init__.cpython-310.pyc +0 -0
  10. kaa/resources/game.db +0 -0
  11. kaa/resources/game_ver.txt +0 -0
  12. kaa/resources/idol_cards/i_card-skin-amao-3-014_1.png +0 -0
  13. kaa/resources/idol_cards/i_card-skin-amao-3-015_0.png +0 -0
  14. kaa/resources/idol_cards/i_card-skin-atbm-1-000_0.png +0 -0
  15. kaa/resources/idol_cards/i_card-skin-atbm-1-000_1.png +0 -0
  16. kaa/resources/idol_cards/i_card-skin-atbm-2-000_0.png +0 -0
  17. kaa/resources/idol_cards/i_card-skin-atbm-2-000_1.png +0 -0
  18. kaa/resources/idol_cards/i_card-skin-atbm-3-000_0.png +0 -0
  19. kaa/resources/idol_cards/i_card-skin-atbm-3-000_1.png +0 -0
  20. kaa/resources/idol_cards/i_card-skin-fktn-3-016_0.png +0 -0
  21. kaa/resources/idol_cards/i_card-skin-fktn-3-016_1.png +0 -0
  22. kaa/resources/idol_cards/i_card-skin-hmsz-3-003_0.png +0 -0
  23. kaa/resources/idol_cards/i_card-skin-hmsz-3-003_1.png +0 -0
  24. kaa/resources/idol_cards/i_card-skin-hmsz-3-009_0.png +0 -0
  25. kaa/resources/idol_cards/i_card-skin-hmsz-3-009_1.png +0 -0
  26. kaa/resources/idol_cards/i_card-skin-hmsz-3-013_0.png +0 -0
  27. kaa/resources/idol_cards/i_card-skin-hmsz-3-013_1.png +0 -0
  28. kaa/resources/idol_cards/i_card-skin-hrnm-3-015_0.png +0 -0
  29. kaa/resources/idol_cards/i_card-skin-hrnm-3-015_1.png +0 -0
  30. kaa/resources/idol_cards/i_card-skin-hski-3-015_0.png +0 -0
  31. kaa/resources/idol_cards/i_card-skin-hski-3-015_1.png +0 -0
  32. kaa/resources/idol_cards/i_card-skin-hume-3-009_0.png +0 -0
  33. kaa/resources/idol_cards/i_card-skin-hume-3-009_1.png +0 -0
  34. kaa/resources/idol_cards/i_card-skin-hume-3-015_0.png +0 -0
  35. kaa/resources/idol_cards/i_card-skin-hume-3-015_1.png +0 -0
  36. kaa/resources/idol_cards/i_card-skin-jsna-3-009_0.png +0 -0
  37. kaa/resources/idol_cards/i_card-skin-jsna-3-009_1.png +0 -0
  38. kaa/resources/idol_cards/i_card-skin-jsna-3-014_0.png +0 -0
  39. kaa/resources/idol_cards/i_card-skin-jsna-3-014_1.png +0 -0
  40. kaa/resources/idol_cards/i_card-skin-kcna-3-014_1.png +0 -0
  41. kaa/resources/idol_cards/i_card-skin-kcna-3-015_0.png +0 -0
  42. kaa/resources/idol_cards/i_card-skin-kcna-3-015_1.png +0 -0
  43. kaa/resources/idol_cards/i_card-skin-kllj-3-014_0.png +0 -0
  44. kaa/resources/idol_cards/i_card-skin-kllj-3-014_1.png +0 -0
  45. kaa/resources/idol_cards/i_card-skin-shro-3-015_0.png +0 -0
  46. kaa/resources/idol_cards/i_card-skin-shro-3-015_1.png +0 -0
  47. kaa/resources/idol_cards/i_card-skin-ssmk-3-015_0.png +0 -0
  48. kaa/resources/idol_cards/i_card-skin-ssmk-3-015_1.png +0 -0
  49. kaa/resources/idol_cards/i_card-skin-ttmr-3-015_0.png +0 -0
  50. kaa/resources/idol_cards/i_card-skin-ttmr-3-015_1.png +0 -0
  51. kaa/sprites/19513e9f-2cbb-4f66-84b7-2ad2faed252d.png +0 -0
  52. kaa/sprites/1ef5fa52-b6e1-42d0-947a-ce970eba057d.png +0 -0
  53. kaa/sprites/318abb8a-5950-4d22-ac42-77219b5bc1a0.png +0 -0
  54. kaa/sprites/321b7040-87d7-4f87-9b44-ad2972584a11.png +0 -0
  55. kaa/sprites/3ae72684-1d40-43cf-9508-511c010de64f.png +0 -0
  56. kaa/sprites/3e669188-5933-4502-b039-38f4d4649664.png +0 -0
  57. kaa/sprites/4370013d-f052-4314-94ff-a342d70754c3.png +0 -0
  58. kaa/sprites/4fb1d36c-5fb6-4fe5-9ba3-07e056eb1dfc.png +0 -0
  59. kaa/sprites/5247b052-5b45-4e64-b7fc-d566f5d4bc82.png +0 -0
  60. kaa/sprites/545a9032-a676-4d9d-ac74-2b2c9b330d1a.png +0 -0
  61. kaa/sprites/57741798-65dd-47eb-b4b1-b3f0e3c3e318.png +0 -0
  62. kaa/sprites/5e2b4bb9-f200-4723-96ac-5f907e28eaaa.png +0 -0
  63. kaa/sprites/5f6fafd9-43aa-443e-994e-f2688af5e238.png +0 -0
  64. kaa/sprites/61229c71-303b-4dc9-ba4e-6a14e5ab161e.png +0 -0
  65. kaa/sprites/62f93327-5946-4a48-aff8-a203483b0562.png +0 -0
  66. kaa/sprites/64dfeb35-61ad-4e9b-9847-a18530f02584.png +0 -0
  67. kaa/sprites/64f8ef99-4766-471b-aeb0-b109704d9615.png +0 -0
  68. kaa/sprites/677933e9-1481-4f01-95b4-d55bea51db8c.png +0 -0
  69. kaa/sprites/67edcd91-d2c1-418b-987a-e60263626f56.png +0 -0
  70. kaa/sprites/6c032aa7-20e3-4e2e-b1a4-1585141ba22b.png +0 -0
  71. kaa/sprites/6fadb00b-e32e-4c45-a738-f21b8f48c139.png +0 -0
  72. kaa/sprites/719297ec-82be-4820-8ecf-8bf6322b81fe.png +0 -0
  73. kaa/sprites/76970b91-7864-4413-bfc7-79c04a48dce7.png +0 -0
  74. kaa/sprites/7c62081d-097a-4514-a69d-69e96201e816.png +0 -0
  75. kaa/sprites/7e16af89-bb51-4889-8a7e-25715ff5faa1.png +0 -0
  76. kaa/sprites/7efce7bc-12a5-4a53-9a0a-9fa755649ebd.png +0 -0
  77. kaa/sprites/803fb770-6982-4460-8fe0-f9ccd67367c2.png +0 -0
  78. kaa/sprites/82200c8c-0916-4601-839a-945f96cc4ebc.png +0 -0
  79. kaa/sprites/8299e3e2-cfd5-4380-adce-a46c93b1be4d.png +0 -0
  80. kaa/sprites/83c27159-36d2-4ccf-ace7-e5d2169e7e52.png +0 -0
  81. kaa/sprites/8661bc83-9b0a-4555-8b21-2258b31c7f57.png +0 -0
  82. kaa/sprites/89437aca-7339-4795-b848-ec529b1e5e8d.png +0 -0
  83. kaa/sprites/8a0260f5-b32e-430e-bc98-7b5a77cab6ab.png +0 -0
  84. kaa/sprites/8c3bc157-022a-4bb1-be74-af1ad254e67f.png +0 -0
  85. kaa/sprites/8d09178a-251e-4f74-b023-12233417621b.png +0 -0
  86. kaa/sprites/8fbee6fe-9409-407e-8f55-d2d36ab37f6a.png +0 -0
  87. kaa/sprites/8fdc102b-d8f3-4d16-b8ef-1d804f5aff07.png +0 -0
  88. kaa/sprites/93e91dd0-0050-48b4-8bf8-c732cd76f0e3.png +0 -0
  89. kaa/sprites/993a33ac-994b-4eb0-9c1e-b9412d499d67.png +0 -0
  90. kaa/sprites/99a27ff1-bc1c-48a2-9f9b-0803338d1bd8.png +0 -0
  91. kaa/sprites/9a9a1f40-d308-4aa5-8d91-60342bc6a4e0.png +0 -0
  92. kaa/sprites/9f573ac2-9d28-4d92-8e3f-1b78031220dd.png +0 -0
  93. kaa/sprites/__pycache__/__init__.cpython-310.pyc +0 -0
  94. kaa/sprites/a2545c5c-b5cc-4fd2-93c1-04c74c17ee16.png +0 -0
  95. kaa/sprites/a2dd125b-9868-4e01-9a46-3b552c2ebdc9.png +0 -0
  96. kaa/sprites/a7f25aeb-d91b-47e0-ba1a-0c6382380102.png +0 -0
  97. kaa/sprites/a888e87e-49fe-405d-b074-3dda30304808.png +0 -0
  98. kaa/sprites/a9ba2741-38da-4448-ab80-f0e5b3c3847f.png +0 -0
  99. kaa/sprites/a9c5aeb0-c0c9-47da-8793-ffe8d172bea0.png +0 -0
  100. kaa/sprites/aba47934-f264-49f9-a72c-6ed90b112701.png +0 -0
  101. kaa/sprites/abe2757f-84f3-4967-bd05-79c17cb1f32c.png +0 -0
  102. kaa/sprites/acd741da-d4ab-4b76-a6a3-4a2fd25870ef.png +0 -0
  103. kaa/sprites/ad17ae00-f6ce-4f32-9386-9a8073b5e79a.png +0 -0
  104. kaa/sprites/ae73d26b-2d47-4921-a6ec-5bbea32773a3.png +0 -0
  105. kaa/sprites/b10281ae-cfaf-4400-b2fb-c8c2b432c8e7.png +0 -0
  106. kaa/sprites/b40bebbf-2800-40fb-b7a2-1c2d5995e747.png +0 -0
  107. kaa/sprites/b76add75-2187-428c-9ede-fb43086bacb6.png +0 -0
  108. kaa/sprites/b77a7e97-dc59-493d-9d76-4ea9c2876978.png +0 -0
  109. kaa/sprites/b9770cd2-b55f-44dc-965f-f29686fba7da.png +0 -0
  110. kaa/sprites/ba8ee2cd-f662-440c-90b3-1e4bfe7bab6b.png +0 -0
  111. kaa/sprites/bb3990c8-4618-4d96-9365-a4d1213b59f7.png +0 -0
  112. kaa/sprites/bbe59f62-c3e7-404c-a313-b50db70de7b5.png +0 -0
  113. kaa/sprites/bdb1460e-c5db-494a-a58a-688f72b6bdba.png +0 -0
  114. kaa/sprites/bdb72f31-5808-4451-827f-fffc3b616083.png +0 -0
  115. kaa/sprites/bf3ff37e-d4fc-42ee-87d6-db1e2040aed5.png +0 -0
  116. kaa/sprites/bff753bb-b02e-441b-89e5-14845f18c6f6.png +0 -0
  117. kaa/sprites/c035ac76-39e9-466b-a606-28bc52bc73e8.png +0 -0
  118. kaa/sprites/c05a600a-d79e-432d-a49f-5b2443d67bd4.png +0 -0
  119. kaa/sprites/c0801be3-f07a-4afc-ab0d-7f5d3c4afbd3.png +0 -0
  120. kaa/sprites/c2100faf-1234-49db-b6d4-5a08a4b08272.png +0 -0
  121. kaa/sprites/c6b0f9ba-a976-474b-b22d-6fe4391d9373.png +0 -0
  122. kaa/sprites/c78fb143-18e3-4697-a0c1-6151514f2a7c.png +0 -0
  123. kaa/sprites/c8c17304-e949-4dfc-b07d-9e7133483e31.png +0 -0
  124. kaa/sprites/c91874f4-363f-4997-a38e-3e486dfd8043.png +0 -0
  125. kaa/sprites/c9245201-4d29-4088-a5e0-f4e93d4494b5.png +0 -0
  126. kaa/sprites/cb0bbf0f-a25b-4ec4-99bd-f5742270a062.png +0 -0
  127. kaa/sprites/ccfab3e2-7b6d-4ae3-998b-4e5c1863884a.png +0 -0
  128. kaa/sprites/cdf310f0-b917-4f92-95a9-893af76e3c3a.png +0 -0
  129. kaa/sprites/cea8f98d-ba68-498f-bd3d-cc10f0d4575b.png +0 -0
  130. kaa/sprites/cec36685-85a7-4e84-bbbc-4df70b4f7bac.png +0 -0
  131. kaa/sprites/cf49878d-a1c5-4b9f-9502-1e0d9eaadc49.png +0 -0
  132. kaa/sprites/d23a600a-7002-4268-96a4-18dc54928ec6.png +0 -0
  133. kaa/sprites/d57f792a-f086-4fbe-b4d9-5db629a78d42.png +0 -0
  134. kaa/sprites/d6dd92b3-310f-4f5d-a8ef-b941c3659c0c.png +0 -0
  135. kaa/sprites/d8967770-c64a-4609-a0a5-f46ba81edceb.png +0 -0
  136. kaa/sprites/d91483a2-83fa-4664-8eda-52498c0e77bc.png +0 -0
  137. kaa/sprites/d9a636be-a017-4ef5-a70c-c374827008a0.png +0 -0
  138. kaa/sprites/dae37bd7-6a34-4eb4-8cd0-3c0c03b4575a.png +0 -0
  139. kaa/sprites/dc51eccf-9470-495a-9e38-59d4481adbd4.png +0 -0
  140. kaa/sprites/dcea5aae-322e-4cd4-b218-0eac48690755.png +0 -0
  141. kaa/sprites/dcf465c6-ad64-48e7-9c3c-7bc7cfc13a44.png +0 -0
  142. kaa/sprites/ddb59f04-91a0-4fbd-8921-be13acdab291.png +0 -0
  143. kaa/sprites/de81f919-4d01-4a4e-bdc1-ffe6e23a5c22.png +0 -0
  144. kaa/sprites/e05f2c16-926f-48be-bdd0-16182e879394.png +0 -0
  145. kaa/sprites/e2a0c1a6-c0cf-400e-99be-1ed0d35c6ed8.png +0 -0
  146. kaa/sprites/e30922ed-a02f-4ede-9968-1656be5a05b2.png +0 -0
  147. kaa/sprites/e388db01-0870-412d-b8bc-5a512ec997c8.png +0 -0
  148. kaa/sprites/e392856d-ac59-4414-8fb8-df93a1a99be4.png +0 -0
  149. kaa/sprites/e57db8c2-c050-43fb-8205-339aeb5875e8.png +0 -0
  150. kaa/sprites/e687c2ba-2c30-4fc8-804f-fea5815f6765.png +0 -0
  151. kaa/sprites/e6e66204-8a2f-4377-8674-b7d663ff0081.png +0 -0
  152. kaa/sprites/e79a2a08-3b58-4ab0-8c2b-769f30cc8591.png +0 -0
  153. kaa/sprites/ebe22aea-0318-49d8-ab07-ce2eef34265f.png +0 -0
  154. kaa/sprites/ed6df33a-c7aa-4542-a87b-9cc9cae0465c.png +0 -0
  155. kaa/sprites/ed854df1-878c-4e0b-8138-9b28d314ede6.png +0 -0
  156. kaa/sprites/ed98a341-5dff-4af7-a194-d28232d481a4.png +0 -0
  157. kaa/sprites/f0ed1dd3-b227-48c1-8c8c-858dbd84fcc7.png +0 -0
  158. kaa/sprites/f1eb4089-8cd1-4830-b00e-40535ddcd116.png +0 -0
  159. kaa/sprites/f237d88e-92ac-4ebf-85e1-80a696b5203a.png +0 -0
  160. kaa/sprites/f2f818c9-b0cf-436d-9d3e-6544c5399063.png +0 -0
  161. kaa/sprites/f333118a-81c2-417f-b54f-64dc4e8df613.png +0 -0
  162. kaa/sprites/f34e8026-bdfc-47e6-a0ed-49e587ef0f40.png +0 -0
  163. kaa/sprites/f3a5992b-dabf-4c2b-83e9-4c91c3b7aac8.png +0 -0
  164. kaa/sprites/f4195ceb-586a-4a8c-9424-4962239d2120.png +0 -0
  165. kaa/sprites/f485db66-2159-4d31-ba53-0fbb726e7f64.png +0 -0
  166. kaa/sprites/f7264cee-fea6-47b5-9f9b-8f3f31c03ea0.png +0 -0
  167. kaa/sprites/f7e34403-a53c-4d3f-935b-25b4acb7f7a5.png +0 -0
  168. kaa/sprites/f8d8c943-1b36-4391-a7fc-2a49f8966d53.png +0 -0
  169. kaa/sprites/f9157db8-d70b-4d46-9800-5a833ce7eda8.png +0 -0
  170. kaa/sprites/f9a353b2-958d-4aae-ade4-66bdc6481e35.png +0 -0
  171. kaa/sprites/fa5b5b92-9c60-4811-a44c-8e897c9632c3.png +0 -0
  172. kaa/sprites/fac7b90a-1174-477b-803b-28798647c307.png +0 -0
  173. kaa/sprites/fbbb73f9-880e-4c7f-9ec9-276bdab4b394.png +0 -0
  174. kaa/sprites/fce4a481-e71c-4dab-aeac-59ff8b18201b.png +0 -0
  175. kaa/sprites/fd8a7a5d-f021-4bfd-83f7-a2dd33325837.png +0 -0
  176. kaa/sprites/fda4b3eb-e31a-448b-8cb3-9126e1ab7deb.png +0 -0
  177. kaa/sprites/fda78372-04b4-4d55-92b1-aedec20d0913.png +0 -0
  178. kaa/sprites/fe993a91-1a49-488e-b7ff-c1b05b8f2b5f.png +0 -0
  179. kaa/sprites/ff8efb8f-e1a4-4202-a6e1-680eb44f58da.png +0 -0
  180. kaa/tasks/R.py +128 -128
  181. kaa/tasks/common.py +5 -0
  182. kaa/tasks/daily/contest.py +2 -1
  183. kaa/tasks/produce/cards.py +5 -4
  184. kaa/tasks/produce/common.py +201 -105
  185. kaa/tasks/produce/in_purodyuusu.py +14 -10
  186. kaa/tasks/produce/non_lesson_actions.py +10 -33
  187. kaa/tasks/produce/p_drink.py +5 -1
  188. kaa/tasks/produce/produce.py +2 -1
  189. kaa/tasks/start_game.py +2 -1
  190. {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/METADATA +9 -6
  191. {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/RECORD +323 -177
  192. /kaa/sprites/{fdf0da06-f088-424f-9941-8c883fea3db3.png → 03d0acec-15fd-4c21-82ce-122764def185.png} +0 -0
  193. /kaa/sprites/{68d9f340-a3d2-4708-8eb1-c1ed857decda.png → 03d22cb3-0193-4dcb-8a0d-98b7ca9c2b4c.png} +0 -0
  194. /kaa/sprites/{dce410ee-fa56-41c4-b75e-e1bff79cd94f.png → 0455e229-75c9-44ba-8729-745799746979.png} +0 -0
  195. /kaa/sprites/{ad94041c-f30b-40b9-b11a-1a26e9962274.png → 049ecbf6-d434-46fa-a42c-a447475269bb.png} +0 -0
  196. /kaa/sprites/{f6b042a8-a91e-4811-99f9-18bbb5197468.png → 04ea8503-cdd5-4b3e-a33b-63893b92f6ba.png} +0 -0
  197. /kaa/sprites/{847226a3-b7d2-4156-b732-9215a3e14f3a.png → 05251a85-2883-4098-842e-6544391de919.png} +0 -0
  198. /kaa/sprites/{9008fbb2-f23f-424f-9be7-5bae6a3697ab.png → 054db45e-1434-4604-91ec-7ac586ca11b5.png} +0 -0
  199. /kaa/sprites/{ae1e70bc-f735-4749-8c23-95735b91897a.png → 06cf74aa-635f-48ab-b965-36981f2063d3.png} +0 -0
  200. /kaa/sprites/{3b4f90c9-6de7-4ac3-8e41-5f8757bf3f3e.png → 0814c0fd-6f89-47d3-8089-e8cfde569750.png} +0 -0
  201. /kaa/sprites/{2cec1d6a-9e8c-49b3-b885-0b0d7c4b95ee.png → 08bde3ff-7554-4bdb-a7f0-193323489d5b.png} +0 -0
  202. /kaa/sprites/{91b30f5e-31b2-4756-a3f7-f0f82a335442.png → 09222fb0-78a6-4663-8c1f-1d44e881513d.png} +0 -0
  203. /kaa/sprites/{5431dc38-c257-40b3-8f7b-8bceaa7fe587.png → 0b436edb-8f6a-429d-87b7-5d4250f651ac.png} +0 -0
  204. /kaa/sprites/{338d7e71-98ce-4cd1-9954-bf7155150780.png → 0c266b0e-de7a-49c1-9709-b01fb5086f75.png} +0 -0
  205. /kaa/sprites/{8e019262-ad23-4cbb-84da-86b34775a91e.png → 0db579bf-d555-4468-8104-c2d2e68d33b1.png} +0 -0
  206. /kaa/sprites/{8be81341-a74d-42c8-8231-5d1854bc08e7.png → 114730f6-eddd-4381-b723-aee18cde0d90.png} +0 -0
  207. /kaa/sprites/{31f2de0a-567b-425a-9be6-536e4532d813.png → 11870372-dc78-4a80-8320-15bb24da6f25.png} +0 -0
  208. /kaa/sprites/{3fa5f81c-9223-44ba-bf07-71932350e845.png → 11bc7d35-e58d-4301-a0b0-f557dbd73c7b.png} +0 -0
  209. /kaa/sprites/{92c3de1b-eed1-45b9-82e0-c9e97bb479e7.png → 12455dbd-7d70-4435-a3ba-f40654e75c37.png} +0 -0
  210. /kaa/sprites/{aa1624ff-88b0-447b-8e2b-8a50fd9e4062.png → 12f330a6-4eab-4015-b0e3-4e1a35a7b676.png} +0 -0
  211. /kaa/sprites/{9991b19c-7330-42c4-9d7d-db3cb00103b7.png → 14a697d4-0b58-4644-bb2d-8823d2fefcb8.png} +0 -0
  212. /kaa/sprites/{49bde219-f9a3-41b5-84b8-e417160a0f40.png → 15605f7a-2206-436c-8a71-011d9f95cf4e.png} +0 -0
  213. /kaa/sprites/{ea430652-e263-4a15-bb6f-8a8807be6c8f.png → 15dd89cc-53ed-4c77-a355-62e3bd7a15dd.png} +0 -0
  214. /kaa/sprites/{5c310fe5-7e92-4167-9eba-6e8e14a2863a.png → 18b13508-c46f-4134-b991-975c0a1b9a74.png} +0 -0
  215. /kaa/sprites/{cd00a2d7-af48-48b1-b2e1-5360ceed249f.png → 1a5c147b-e28e-42ad-893a-7430d8f4fc35.png} +0 -0
  216. /kaa/sprites/{94d54ba7-0ccf-4fd9-a5bf-488bac1364c8.png → 1b3c84c5-16d1-43a7-8513-719bd7a10450.png} +0 -0
  217. /kaa/sprites/{2289d38f-dc98-4310-9f34-4cf5023f8545.png → 1b847790-90e2-44f8-b6d9-4814812006bd.png} +0 -0
  218. /kaa/sprites/{6c926e92-9af9-402d-8512-6417ca116928.png → 1e57ab88-9962-4024-81df-746529a758f9.png} +0 -0
  219. /kaa/sprites/{30e12bf1-8fa5-4de1-8d7b-28fa0fec0cb6.png → 205e03de-46d9-4983-a2ea-a7f7500d508f.png} +0 -0
  220. /kaa/sprites/{e4dc3b35-195c-415f-9484-c2459bd8675a.png → 20bd834e-c99c-4e80-92db-0740e5bbe746.png} +0 -0
  221. /kaa/sprites/{68e20ebf-02fd-46a1-88d7-b4472824e7bc.png → 218a6ab3-93f6-4bb1-9848-8c97ff695945.png} +0 -0
  222. /kaa/sprites/{ec3cad5f-e0c9-4577-8499-79b50248344e.png → 22071c63-a1bc-4163-8d5a-973b3d579c76.png} +0 -0
  223. /kaa/sprites/{e933cd55-e47a-4327-89d7-b25995cb4a3f.png → 2460d0c9-50e2-451b-b609-ad466b574395.png} +0 -0
  224. /kaa/sprites/{0af1d573-1dc7-427e-997d-173308ea3649.png → 264d021a-b322-4472-8a7b-5f1322aba993.png} +0 -0
  225. /kaa/sprites/{57c81080-7b53-4286-8fa5-848ad63e4774.png → 28335ba3-9a0f-46cd-b66d-047781773264.png} +0 -0
  226. /kaa/sprites/{d7750f81-de10-4d6f-9cc7-35223bda9d70.png → 28df544b-72f2-4ed8-8bf3-609ff99633d9.png} +0 -0
  227. /kaa/sprites/{81686816-c723-47d1-9824-a68d9ebe1bd4.png → 2a82e2d6-0722-433a-87fa-f1752ce0b9b7.png} +0 -0
  228. /kaa/sprites/{5ffd3f29-db4f-4f66-b9ed-be5a70b7ebf9.png → 2abce6a4-111f-42bb-9255-f98d544108de.png} +0 -0
  229. /kaa/sprites/{23b9cda9-8be8-438e-8e54-57d91a4bd875.png → 2d8e6464-aceb-41fd-9e78-7523738d5720.png} +0 -0
  230. /kaa/sprites/{1ad89ee4-1bb1-41d2-a92c-79caf6baa38a.png → 2f9e2dbb-66a1-4b13-9b9e-d62e10efa6d3.png} +0 -0
  231. /kaa/sprites/{c69dcdcf-42a7-420e-aa8e-bb8639ea80b6.png → 307b58f0-20c1-41bd-9eaa-1337fd0e6563.png} +0 -0
  232. /kaa/sprites/{55c3af20-58dc-4407-a383-312a57417c39.png → 3192a62f-224d-44b1-a0b9-b1fc22de8ec1.png} +0 -0
  233. /kaa/sprites/{645909d7-b960-46c7-b208-db44b6b7feec.png → 31b4c370-696f-4dfc-a918-839495520266.png} +0 -0
  234. /kaa/sprites/{7daaca55-e3fd-4e12-bf31-872105ceb726.png → 330c2207-af32-453b-8db7-889cda83e7cc.png} +0 -0
  235. /kaa/sprites/{5734e48a-1e58-42de-be7b-b7db67db4a01.png → 38186efc-850c-4d83-97bc-9417f1494b94.png} +0 -0
  236. /kaa/sprites/{8ed51be4-815c-4a3d-805e-030fdfa341e2.png → 38426696-ff13-4f20-9f74-b05855990153.png} +0 -0
  237. /kaa/sprites/{cfe3563d-a24b-4197-a0cb-5628bd990c08.png → 3a211792-1243-496a-b41e-0e3fd121cd5b.png} +0 -0
  238. /kaa/sprites/{179c0fff-ebd2-4a16-8db2-297552cca218.png → 3a4e2d8a-deca-4980-b6c2-37bfc17d2720.png} +0 -0
  239. /kaa/sprites/{2d0e9d49-365a-4bcb-a416-38b87defaa3c.png → 3a4ec054-2c48-4359-afb9-fa5ea8191d16.png} +0 -0
  240. /kaa/sprites/{51b95c81-4ff9-434c-ade2-3518e63337cb.png → 3c490171-6810-44f0-b28d-c6b664347a3c.png} +0 -0
  241. /kaa/sprites/{35341839-4469-4ab6-aa40-33642fe43e82.png → 3cda578a-fa75-4bbd-9cff-be4bc4355a58.png} +0 -0
  242. /kaa/sprites/{72634cb3-4c76-4ca2-8898-ebb837ec19e3.png → 3ea03db7-4de9-45c4-a07b-a9bbc2c63e70.png} +0 -0
  243. /kaa/sprites/{da48db0d-09d9-47c3-9e08-8b69ad547be6.png → 3ea8e354-2684-46f3-9f5a-43f094717c95.png} +0 -0
  244. /kaa/sprites/{3e087b8d-420d-48ff-b526-29c4a65d8cbe.png → 3eb9b21b-abbe-49fd-a3a9-6e1c1a6e91d9.png} +0 -0
  245. /kaa/sprites/{2234f709-1703-4589-905c-175f4db09b1b.png → 3fb84a71-ed15-4989-9598-34e7342f38f5.png} +0 -0
  246. /kaa/sprites/{39f6d657-3b3e-40aa-849b-7ad87a0be1d0.png → 3ffd2992-fa55-499c-8c3b-193518ebbe07.png} +0 -0
  247. /kaa/sprites/{464b1dd8-ca2e-41e9-a5b5-90545c584db7.png → 41ff9641-d200-4caa-bcfa-d8389a3438eb.png} +0 -0
  248. /kaa/sprites/{70768479-5d7a-4941-8774-ad556c47bee2.png → 455dcf19-63f5-4b0a-99e6-b23d3876d199.png} +0 -0
  249. /kaa/sprites/{694879e8-ecca-45e2-8ea4-1b447fd43ace.png → 45f09e08-53ea-4e08-97dc-70f689bab002.png} +0 -0
  250. /kaa/sprites/{dd873ac0-ffba-4335-9cf2-2162c6835ed8.png → 4729b509-0f4a-4e96-b186-ec56c680c9e6.png} +0 -0
  251. /kaa/sprites/{7d7df15f-707e-4e27-826f-21e42af1dae0.png → 4eb665ef-7741-40f9-8174-7b6ca66d045b.png} +0 -0
  252. /kaa/sprites/{8e5e968b-edad-4c03-abc8-3f2a7e8879ae.png → 4f370ff6-61d1-405a-b29e-e6d0b3072194.png} +0 -0
  253. /kaa/sprites/{f0462447-5226-4819-a39b-19ab90583f83.png → 504e4927-bfeb-43ee-aa5c-35cec664a4c8.png} +0 -0
  254. /kaa/sprites/{756f4ca7-acac-48e1-8bcd-1c5cd8937e3a.png → 51eb4be2-22fa-4683-82c7-513f5934f7b9.png} +0 -0
  255. /kaa/sprites/{87f3c1ae-5117-4871-a7d6-3f5ff0c9f9fb.png → 568608bd-a1fa-4faf-ae15-179563a7e84f.png} +0 -0
  256. /kaa/sprites/{978873bb-e4d0-451b-9126-6977144f5395.png → 56ac84af-4c85-4b69-b449-98981c1df292.png} +0 -0
  257. /kaa/sprites/{db6707a2-2964-4919-9992-4d801fa43dae.png → 5a49b6d2-2bcb-49bc-a28f-b8bd1441f60a.png} +0 -0
  258. /kaa/sprites/{01256311-237c-476f-96ce-4136dc4bfbd3.png → 5a677634-99cf-45b5-bc0c-94120872a518.png} +0 -0
  259. /kaa/sprites/{8e4d8a0f-4a9d-4562-9234-63806b11d85f.png → 5ec51718-1403-4a79-bd85-46e1fe04d8c9.png} +0 -0
  260. /kaa/sprites/{dc97fea3-898f-4135-9c40-ad41570ab4ae.png → 5f2d0b2b-8425-4dd8-8b85-d62f4b75286c.png} +0 -0
  261. /kaa/sprites/{f32a41a2-c482-41ba-b718-28f048f5148c.png → 5f4abae0-a1f0-4c8c-9d93-a8525caa9dd0.png} +0 -0
  262. /kaa/sprites/{31e3ac2b-ecd4-4c37-88bc-985ef32e73a3.png → 6005bf30-fd7c-401e-8efd-050fa97ad7f3.png} +0 -0
  263. /kaa/sprites/{3b4dc708-1d34-4a88-9fe3-d8de2ec1d5c8.png → 6069f8bc-2a06-45a4-95ca-1ac9d8fa3b04.png} +0 -0
  264. /kaa/sprites/{962aa0b9-1dd3-4260-a4fb-c069c26e5a84.png → 60896822-de58-4e07-b2d9-86a7f4068de1.png} +0 -0
  265. /kaa/sprites/{889a4153-b713-49cb-a4d5-e302bcdd002d.png → 622d700e-0fd8-4a92-a286-1e8143c70570.png} +0 -0
  266. /kaa/sprites/{b59c0e9b-1f20-4194-ab37-286f505fa656.png → 63b74752-73ce-4020-a7c8-0a71a9f67415.png} +0 -0
  267. /kaa/sprites/{4a081370-b0a1-4067-8470-e3007cc68a12.png → 648d43f6-b251-4d6f-a808-ae7325c91a59.png} +0 -0
  268. /kaa/sprites/{bfdc9b53-2fe5-43f1-8588-7ab71217d31c.png → 65f79941-1c78-496a-a67c-c50f4227bd34.png} +0 -0
  269. /kaa/sprites/{9e7eaa8e-3178-44da-a5ec-34b889f8facf.png → 6f50cd3b-6e46-46c5-99ed-26728d3212ad.png} +0 -0
  270. /kaa/sprites/{ab237c6d-c4d8-4716-8ef7-99b8e995c9a7.png → 6f6d7af3-8380-439b-9d26-3fbd5a103b49.png} +0 -0
  271. /kaa/sprites/{1befe09b-cb77-417a-b21e-7746804d4e03.png → 71913fde-c3db-463d-800d-e1b35fa2c8b4.png} +0 -0
  272. /kaa/sprites/{e7f2734f-9fdc-4521-8d7e-8b0fe270a223.png → 71976c1a-5df9-44a5-b4ea-08b5d617d813.png} +0 -0
  273. /kaa/sprites/{9f7150bc-c0b8-48d6-862c-456aaf518b2b.png → 72a8bcd2-3f32-4ee5-8295-eedf441d6a1a.png} +0 -0
  274. /kaa/sprites/{cd0e8663-2ea1-436a-b9fb-3caa0c3ed9e8.png → 73b6f3aa-5179-41d6-a82e-22e14aa8cd6a.png} +0 -0
  275. /kaa/sprites/{cba0646d-dffe-4c5b-a44d-1f8d827624a6.png → 7a74b5f5-7a04-4678-8e6e-57b5de127182.png} +0 -0
  276. /kaa/sprites/{5930140e-effe-4bcf-b0be-c20d3990d833.png → 7b4c3a81-8f09-4a00-90ee-d4df3f57e863.png} +0 -0
  277. /kaa/sprites/{cb6dffd9-6474-4d09-aee6-26352ea51d31.png → 7c4ca388-5167-478a-a32b-0e108edad888.png} +0 -0
  278. /kaa/sprites/{96704aa3-b5ad-4e34-bb88-fad766415362.png → 7d4709f8-6d0d-493f-819e-74cb0f7c166b.png} +0 -0
  279. /kaa/sprites/{fcc72120-2a77-4c26-a27e-e1027c6088c0.png → 7e8904fd-5863-471f-8e9a-d69d9ca72f8f.png} +0 -0
  280. /kaa/sprites/{023b8f4c-15ab-4845-b141-446c861ad475.png → 80800c2e-417d-4118-b726-93aaabfc08bd.png} +0 -0
  281. /kaa/sprites/{f0aef696-2106-46a4-8b7f-9f16b6c89d3f.png → 81b1b160-2d0f-42ad-924a-9572a54f343a.png} +0 -0
  282. /kaa/sprites/{13cb0309-b713-4725-b10b-26afe46eb9c0.png → 82259f79-2bef-442b-bf16-78cb4f22e3be.png} +0 -0
  283. /kaa/sprites/{43a367e1-91dd-495e-8c30-41903f75a99a.png → 861a4faa-2522-41e9-8e20-7bd9180bea5a.png} +0 -0
  284. /kaa/sprites/{01247ebe-8d63-4573-90f4-d8dc2b7ca14c.png → 87ed135a-2eb1-4e21-8928-d0307a22ea66.png} +0 -0
  285. /kaa/sprites/{1cf03f98-63e9-467c-804d-c74dd97b69bd.png → 8805fead-f7e2-4905-a42e-05ebba2fbe21.png} +0 -0
  286. /kaa/sprites/{16a0fd47-e85b-4848-8894-9d071ea993ac.png → 88be2dcc-68ca-4596-9b2c-544a196cab64.png} +0 -0
  287. /kaa/sprites/{a5694c76-3c5d-462e-81d5-1e0e6cef0ec9.png → 89841ff0-e834-4a7e-b9d5-00a9490b6b7f.png} +0 -0
  288. /kaa/sprites/{84cabff2-7a1b-4018-b74b-46f4db06304f.png → 8bf08bab-7c55-45e1-8433-c2213a323480.png} +0 -0
  289. /kaa/sprites/{e5e49b44-dcc2-4e77-9180-0d2beaa3f9ad.png → 8d416e23-04ef-47bd-8cc8-7f18d1bab736.png} +0 -0
  290. /kaa/sprites/{c1d502eb-c77f-45cb-86b5-11b4a8a3aef5.png → 8f9dd0f0-f9af-4eec-a89e-8f2c92f88a98.png} +0 -0
  291. /kaa/sprites/{424a0ef5-102d-4734-a731-2b3b3c7c9682.png → 9088f8c0-59f8-41c6-994c-ae283ac94c24.png} +0 -0
  292. /kaa/sprites/{91a50322-52d9-4516-9e46-bc121f20667d.png → 922af7d1-75e9-4ac8-a4e7-2dad8bb1ca87.png} +0 -0
  293. /kaa/sprites/{d81b1325-e57a-4f22-93e1-6ad4baa28935.png → 94ed55fe-3ef8-46bc-855a-a7b1dedab801.png} +0 -0
  294. /kaa/sprites/{913dbd4e-ebb1-4c9f-b145-9960cde59c17.png → 95d715c3-d569-48b5-be7b-c21cd2a160db.png} +0 -0
  295. /kaa/sprites/{dd7bd6cd-90f1-4773-9b68-5df7f2f84da5.png → 97a3791d-fa9d-453d-8081-c574fe88b823.png} +0 -0
  296. /kaa/sprites/{2204967a-a0ee-4dd3-aecb-4d531e8e954c.png → 9acd9a59-004f-4e1d-a208-0c293f2702d5.png} +0 -0
  297. /kaa/sprites/{572a921d-633f-4465-b177-7a0d9ad7e099.png → 9f3bfe36-8462-404f-94da-9bc324b1beed.png} +0 -0
  298. /kaa/sprites/{799fe395-2264-4bc5-b515-813dadda8fe1.png → 9f46f543-d7dc-4836-a210-125d686475f9.png} +0 -0
  299. /kaa/sprites/{5bf2a814-df85-4d0a-b4b5-8883ac2ee434.png → a34502b4-10bd-42ca-9ada-a9cdb57097dc.png} +0 -0
  300. /kaa/sprites/{043e753e-db15-45ba-8513-53c3fc9c7f3c.png → a3fe5859-62ba-403e-9367-65db0ad15943.png} +0 -0
  301. /kaa/sprites/{8f7b55d8-0143-4d27-bef8-560d4d510500.png → a42ac612-acbd-45cc-88fb-104ff9b7d2d8.png} +0 -0
  302. /kaa/sprites/{736a9daf-05d6-46ba-810b-5a8f509152d1.png → a4c6d967-0251-4b33-acb3-81d24f82d5a4.png} +0 -0
  303. /kaa/sprites/{edcec31d-d5de-4f22-b666-3e3c656e06d8.png → a6ed21f0-4da4-4065-bb59-062a70e132ca.png} +0 -0
  304. /kaa/sprites/{e9310e38-a418-4561-bf33-eb3e6dccf477.png → a97e2840-1575-4f2c-97df-6a720c644969.png} +0 -0
  305. /kaa/sprites/{d644faa3-ff16-417f-928c-4c62b040bfdb.png → ae0ce964-eb8f-45a1-aa4d-f47a5c8c720f.png} +0 -0
  306. /kaa/sprites/{256ffeba-8e9e-4cc5-8a1c-9eaee427f1a5.png → ae106b38-da4f-4b0d-b9c3-541fd58f4de7.png} +0 -0
  307. /kaa/sprites/{802db04f-77c2-46a4-a6eb-f81d48ea03ce.png → aeab8f9a-fe61-4c2d-a494-ffc19a9cae91.png} +0 -0
  308. /kaa/sprites/{37215a56-f8e1-4f22-a148-9894136f6ab1.png → affc87db-2f63-4e4a-855e-6ff608226f1e.png} +0 -0
  309. /kaa/sprites/{d1ea0ea6-4a6a-4036-b140-922c95a648b5.png → b02c15b5-04b4-40d9-bb13-267786e8e049.png} +0 -0
  310. /kaa/sprites/{22dc4cfe-8c66-4461-8660-e2d11bbe6154.png → b7f62cab-cc24-480e-bf4c-25c43a1e801e.png} +0 -0
  311. /kaa/sprites/{5906d986-d0e5-452d-a7c4-ddeb7af8751d.png → bd4cd421-f702-47c0-9f8b-77914973108c.png} +0 -0
  312. /kaa/sprites/{8bd22fe1-b544-4d2e-b74a-34f3cf0eb512.png → c4505a31-74c5-4b3d-bfcf-a67c3ef0039e.png} +0 -0
  313. /kaa/sprites/{e13fc34b-accc-4986-865d-f8d8410b45e9.png → c6b6b77b-2ec7-4fb7-8033-f4d061f4e9c8.png} +0 -0
  314. /kaa/sprites/{2b6d2eb0-bcf7-4bea-b037-6293d9c6d728.png → c76c6ccb-d099-4c3c-9eda-13be33aa48ae.png} +0 -0
  315. /kaa/sprites/{0562f69f-0300-4a2b-8252-63f3e7180e4c.png → cb15d9a3-78fe-4f03-bd23-90ba6169ddff.png} +0 -0
  316. /kaa/sprites/{2a8626df-056c-46a2-aaf3-0060a5aef6a3.png → d1bdfa3b-34df-488d-9f9b-8c7b04dd4ab3.png} +0 -0
  317. /kaa/sprites/{3aed50a2-d640-4178-9b8a-4dd7973eebf1.png → d8ba1932-978c-451c-a717-d7d2b6db35d9.png} +0 -0
  318. /kaa/sprites/{f635499a-943d-47da-952a-1feb58daa25b.png → e7630ccb-6824-49e3-986f-2a65a2c4a948.png} +0 -0
  319. /kaa/sprites/{847eb5c0-0350-4b7c-9c9c-43c796709795.png → ec35a0b8-1afa-48ff-ae66-9c1ef966348d.png} +0 -0
  320. {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/WHEEL +0 -0
  321. {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/entry_points.txt +0 -0
  322. {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/licenses/LICENSE +0 -0
  323. {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,121 @@
1
+ import logging
2
+ import os
3
+ import re
4
+ import zipfile
5
+ from datetime import datetime, timedelta
6
+ from typing import Optional, Callable, Dict, Any
7
+
8
+ import cv2
9
+ from pydantic import BaseModel
10
+
11
+ from kaa.errors import ReportCreationError, UploadError
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class BugReportResult(BaseModel):
17
+ """错误报告创建结果的模型"""
18
+ file_path: str
19
+ upload_url: Optional[str] = None
20
+ message: str
21
+
22
+
23
+ def _sanitize_filename(s: str) -> str:
24
+ """过滤掉文件名中的非法字符"""
25
+ return re.sub(r'[\\/:*?"<>|]', '_', s)
26
+
27
+
28
+ class FeedbackService:
29
+ """处理反馈和错误报告的逻辑"""
30
+
31
+ def report(self, title: str, description: str, version: str, upload: bool, on_progress: Optional[Callable[[Dict[str, Any]], None]] = None) -> BugReportResult:
32
+ """
33
+ 创建并可能上传一个错误报告。
34
+
35
+ :param title: 报告标题。
36
+ :param description: 报告描述。
37
+ :param version: 当前版本。
38
+ :param upload: 是否上传报告。
39
+ :param on_progress: 进度回调函数,用于实时回报进度。
40
+ :return: 一个 BugReportResult 对象。
41
+ :raises ReportCreationError: 如果报告创建失败。
42
+ :raises UploadError: 如果报告上传失败。
43
+ """
44
+ from kotonebot import device
45
+ from kotonebot.backend.context import ContextStackVars
46
+
47
+ total_steps = 6 if upload else 5
48
+ def _progress(data: Dict[str, Any]):
49
+ if on_progress:
50
+ on_progress(data)
51
+
52
+ os.makedirs('logs', exist_ok=True)
53
+ os.makedirs('reports', exist_ok=True)
54
+
55
+ safe_title = _sanitize_filename(title)[:30] or "无标题"
56
+ timestamp = datetime.now().strftime("%y-%m-%d-%H-%M-%S")
57
+ path = f'./reports/bug_{timestamp}_{safe_title}.zip'
58
+
59
+ try:
60
+ with zipfile.ZipFile(path, 'w', zipfile.ZIP_DEFLATED, compresslevel=9) as zipf:
61
+ _progress({'type': 'packing', 'item': '描述文件', 'step': 1, 'total_steps': total_steps})
62
+ description_content = f"标题:{title}\n类型:bug\n内容:\n{description}"
63
+ zipf.writestr('description.txt', description_content.encode('utf-8'))
64
+
65
+ _progress({'type': 'packing', 'item': '上次截图', 'step': 2, 'total_steps': total_steps})
66
+ try:
67
+ stack = ContextStackVars.current()
68
+ if stack and stack._screenshot is not None:
69
+ img = cv2.imencode('.png', stack._screenshot)[1].tobytes()
70
+ zipf.writestr('last_screenshot.png', img)
71
+ except Exception as e:
72
+ logger.warning(f"保存上次截图失败: {e}")
73
+
74
+ _progress({'type': 'packing', 'item': '当前截图', 'step': 3, 'total_steps': total_steps})
75
+ try:
76
+ screenshot = device.screenshot()
77
+ img = cv2.imencode('.png', screenshot)[1].tobytes()
78
+ zipf.writestr('current_screenshot.png', img)
79
+ except Exception as e:
80
+ logger.warning(f"保存当前截图失败: {e}")
81
+
82
+ _progress({'type': 'packing', 'item': '配置文件', 'step': 4, 'total_steps': total_steps})
83
+ if os.path.exists('config.json'):
84
+ zipf.write('config.json')
85
+
86
+ _progress({'type': 'packing', 'item': '日志', 'step': 5, 'total_steps': total_steps})
87
+ if os.path.exists('logs'):
88
+ for root, _, files in os.walk('logs'):
89
+ for file in files:
90
+ file_path = os.path.join(root, file)
91
+ arcname = os.path.join('logs', os.path.relpath(file_path, 'logs'))
92
+ zipf.write(file_path, arcname)
93
+
94
+ zipf.writestr('version.txt', version)
95
+ except Exception as e:
96
+ raise ReportCreationError(str(e)) from e
97
+
98
+ file_path = os.path.abspath(path)
99
+
100
+ if not upload:
101
+ message = f"报告已保存至 {file_path}"
102
+ _progress({'type': 'done', 'file_path': file_path, 'step': 5, 'total_steps': total_steps})
103
+ return BugReportResult(file_path=file_path, message=message)
104
+
105
+ # 上传报告
106
+ from kotonebot.ui.file_host.sensio import upload as upload_file
107
+ _progress({'type': 'uploading', 'item': '报告', 'step': 6, 'total_steps': total_steps})
108
+ try:
109
+ url = upload_file(file_path)
110
+ except Exception as e:
111
+ raise UploadError(str(e)) from e
112
+
113
+ expire_time = datetime.now() + timedelta(days=7)
114
+ final_msg = (
115
+ f"报告导出成功:{url}\n\n"
116
+ f"此链接将于 {expire_time.strftime('%Y-%m-%d %H:%M:%S')}(7 天后)过期\n\n"
117
+ '复制以上文本并反馈给开发者'
118
+ )
119
+ _progress({'type': 'done', 'url': url, 'step': 6, 'total_steps': total_steps})
120
+ return BugReportResult(file_path=file_path, upload_url=url, message=final_msg)
121
+
@@ -1,11 +1,14 @@
1
1
  import os
2
2
  import sys
3
3
 
4
- from kotonebot.interop.win.shortcut import create_shortcut
4
+ from kotonebot.util import is_windows, require_windows
5
+ if is_windows():
6
+ from kotonebot.interop.win.shortcut import create_shortcut
5
7
  from kaa.errors import LauncherNotFoundError
6
8
 
7
9
 
8
10
  def create_desktop_shortcut(start_immediately: bool):
11
+ require_windows('create_desktop_shortcut')
9
12
  exe_path = os.path.abspath('./kaa.exe')
10
13
  if not os.path.exists(exe_path):
11
14
  raise LauncherNotFoundError()
@@ -0,0 +1,208 @@
1
+ import logging
2
+ import os
3
+ import subprocess
4
+ import sys
5
+ import json
6
+ import zipfile
7
+ import threading
8
+ import time
9
+ from typing import Optional, List
10
+ from pydantic import BaseModel, Field
11
+
12
+ from kaa.errors import (
13
+ UpdateFetchListError, CompatibilityError, UpdateInstallError
14
+ )
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ class VersionInfo(BaseModel):
19
+ """存储版本信息的 Pydantic 模型"""
20
+ versions: List[str] = Field(default_factory=list)
21
+ latest: Optional[str] = None
22
+ installed_version: Optional[str] = None
23
+ launcher_version: Optional[str] = None
24
+
25
+ def _compare_versions(version1: str, version2: str) -> int:
26
+ """
27
+ 比较两个版本字符串。
28
+
29
+ :param version1: 第一个版本号
30
+ :param version2: 第二个版本号
31
+ :return: -1 表示 version1 < version2, 0 表示 version1 == version2, 1 表示 version1 > version2
32
+ """
33
+ if version1 == "0.4.x":
34
+ version1 = "0.4.0"
35
+
36
+ def parse(v):
37
+ v = v.lstrip('v')
38
+ parts = v.split('.')
39
+ base = []
40
+ pre_release = ''
41
+ for part in parts:
42
+ if 'b' in part:
43
+ base.append(int(part.split('b')[0]))
44
+ pre_release = ('b', int(part.split('b')[1]))
45
+ break
46
+ elif 'a' in part:
47
+ base.append(int(part.split('a')[0]))
48
+ pre_release = ('a', int(part.split('a')[1]))
49
+ break
50
+ elif 'rc' in part:
51
+ base.append(int(part.split('rc')[0]))
52
+ pre_release = ('rc', int(part.split('rc')[1]))
53
+ break
54
+ else:
55
+ base.append(int(part))
56
+
57
+ pre_map = {'a': -2, 'b': -1, 'rc': -0.5}
58
+ if pre_release:
59
+ return tuple(base) + (pre_map[pre_release[0]], pre_release[1])
60
+ return tuple(base) + (0, 0)
61
+
62
+ v1_parsed = parse(version1)
63
+ v2_parsed = parse(version2)
64
+
65
+ if v1_parsed < v2_parsed:
66
+ return -1
67
+ if v1_parsed > v2_parsed:
68
+ return 1
69
+ return 0
70
+
71
+ class UpdateService:
72
+ """处理应用程序更新逻辑"""
73
+
74
+ def __init__(self, repo_name: str = "ksaa"):
75
+ self.repo_name = repo_name
76
+ self.bootstrap_pyz_path = os.path.join(os.getcwd(), "bootstrap.pyz")
77
+
78
+ def _get_launcher_version(self) -> Optional[str]:
79
+ """
80
+ 从 bootstrap.pyz/meta.py 读取启动器版本。
81
+
82
+ :return: 启动器版本字符串,如果无法确定则返回 None。
83
+ """
84
+ if not os.path.exists(self.bootstrap_pyz_path):
85
+ logger.warning("bootstrap.pyz not found.")
86
+ return None
87
+
88
+ try:
89
+ with zipfile.ZipFile(self.bootstrap_pyz_path, 'r') as zf:
90
+ if 'meta.py' not in zf.namelist():
91
+ logger.warning("meta.py not found in bootstrap.pyz, assuming legacy launcher.")
92
+ return "0.4.x"
93
+
94
+ meta_content = zf.read('meta.py').decode('utf-8')
95
+ exec_globals = {}
96
+ exec_locals = {}
97
+ exec(meta_content, exec_globals, exec_locals)
98
+
99
+ version = exec_locals.get('VERSION')
100
+ if version and isinstance(version, str):
101
+ logger.info(f"Launcher version from meta.py: {version}")
102
+ return version.lstrip('v')
103
+ else:
104
+ logger.warning("VERSION not found in meta.py.")
105
+ return None
106
+ except zipfile.BadZipFile:
107
+ logger.info("bootstrap.pyz is not a valid zip file, assuming legacy launcher.")
108
+ return "0.4.x"
109
+ except Exception as e:
110
+ logger.error(f"Failed to read launcher version: {e}", exc_info=True)
111
+ return None
112
+
113
+ def list_remote_versions(self) -> VersionInfo:
114
+ """
115
+ 从 PyPI 获取可用版本。
116
+
117
+ :return: 包含版本数据的 VersionInfo 对象。
118
+ :raises UpdateFetchListError: 如果无法获取或解析版本列表。
119
+ """
120
+ cmd = [
121
+ sys.executable, "-m", "pip", "index", "versions", self.repo_name,
122
+ "--json", "--pre",
123
+ "--index-url", "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple",
124
+ "--trusted-host", "mirrors.tuna.tsinghua.edu.cn"
125
+ ]
126
+ logger.info(f"Executing: {' '.join(cmd)}")
127
+
128
+ try:
129
+ result = subprocess.run(
130
+ cmd,
131
+ capture_output=True,
132
+ text=True,
133
+ timeout=30,
134
+ check=False
135
+ )
136
+
137
+ if result.returncode != 0:
138
+ raise UpdateFetchListError(result.stderr)
139
+
140
+ data = json.loads(result.stdout)
141
+ version_info = VersionInfo(
142
+ versions=data.get("versions", []),
143
+ latest=data.get("latest"),
144
+ installed_version=data.get("installed_version")
145
+ )
146
+ version_info.launcher_version = self._get_launcher_version()
147
+ logger.info(f"Found {len(version_info.versions)} available versions.")
148
+ return version_info
149
+
150
+ except (subprocess.TimeoutExpired, json.JSONDecodeError, Exception) as e:
151
+ raise UpdateFetchListError(str(e)) from e
152
+
153
+ def _check_compatibility(self, target_version: str) -> Optional[str]:
154
+ """
155
+ 检查启动器是否与目标版本兼容。
156
+
157
+ :raises CompatibilityError: 如果启动器不兼容。
158
+ :return: 如果有潜在问题,则返回警告消息,否则返回 None。
159
+ """
160
+ launcher_version = self._get_launcher_version()
161
+ if not launcher_version:
162
+ return "无法获取启动器版本,可以继续安装但可能存在兼容性问题"
163
+
164
+ logger.info(f"Launcher version: {launcher_version}, Target version: {target_version}")
165
+
166
+ if _compare_versions(launcher_version, "0.5.0") < 0:
167
+ if _compare_versions(target_version, "2025.9b1") >= 0:
168
+ raise CompatibilityError(launcher_version, target_version)
169
+ else:
170
+ return "启动器版本较低,建议升级到 v0.5.0 以上"
171
+ return None
172
+
173
+ def install_version(self, version: str):
174
+ """
175
+ 安装应用程序的特定版本。
176
+
177
+ :param version: 要安装的版本。
178
+ :raises CompatibilityError: 如果启动器不兼容。
179
+ :raises UpdateInstallError: 如果安装过程启动失败。
180
+ """
181
+ if not version:
182
+ raise ValueError("A version must be selected to install.")
183
+
184
+ warning = self._check_compatibility(version)
185
+ if warning:
186
+ logger.warning(warning)
187
+
188
+ def _install_and_exit():
189
+ try:
190
+ time.sleep(1)
191
+ cmd = [sys.executable, self.bootstrap_pyz_path, f"--install-version={version}"]
192
+ logger.info(f"Starting installation via launcher: {' '.join(cmd)}")
193
+
194
+ subprocess.Popen(
195
+ cmd,
196
+ cwd=os.getcwd(),
197
+ creationflags=subprocess.CREATE_NEW_CONSOLE if os.name == 'nt' else 0
198
+ )
199
+ logger.info("Installation process started. Exiting current application.")
200
+ os._exit(0)
201
+ except Exception as e:
202
+ logger.critical(f"Failed to launch installation process: {e}", exc_info=True)
203
+
204
+ try:
205
+ install_thread = threading.Thread(target=_install_and_exit, daemon=True)
206
+ install_thread.start()
207
+ except Exception as e:
208
+ raise UpdateInstallError(str(e)) from e
kaa/config/schema.py CHANGED
@@ -78,6 +78,8 @@ class ProduceConfig(ConfigBaseModel):
78
78
  """培育的次数。"""
79
79
  produce_timeout_cd: int = 60
80
80
  """推荐卡检测用时上限;若超时,则随机选择卡片打出。单位为秒,最少为20sec,DMM用户可以设置为30sec"""
81
+ interrupt_timeout: int = 90
82
+ """检测超时时间。单位秒。"""
81
83
  enable_fever_month: Literal['on', 'off', 'ignore'] = 'ignore'
82
84
  """
83
85
  是否自动启用强化月间。
@@ -200,6 +202,10 @@ class MiscConfig(ConfigBaseModel):
200
202
  * release: 只使用稳定版。
201
203
  * beta: 包含预发布版本(如 alpha/beta/rc)。
202
204
  """
205
+ log_level: Literal['debug', 'verbose'] = 'debug'
206
+ """
207
+ 日志等级。
208
+ """
203
209
 
204
210
  class IdleModeConfig(ConfigBaseModel):
205
211
  enabled: bool = False
kaa/errors.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import platform
2
3
  from kotonebot.errors import UserFriendlyError
3
4
 
4
5
 
@@ -19,6 +20,58 @@ class KaaUserFriendlyError(UserFriendlyError, KaaError):
19
20
  def __str__(self):
20
21
  return f'【发生错误】{self.message}。访问 {self.help_link} 以获取更多帮助。'
21
22
 
23
+ class ServiceError(KaaUserFriendlyError):
24
+ """Base class for service-related errors."""
25
+ def __init__(self, message: str, help_link: str):
26
+ super().__init__(message, help_link)
27
+
28
+ class UpdateServiceError(ServiceError):
29
+ """Base class for update service errors."""
30
+ pass
31
+
32
+ class UpdateFetchListError(UpdateServiceError):
33
+ def __init__(self, reason: str):
34
+ super().__init__(
35
+ f'Failed to fetch version list: {reason}',
36
+ '' # TODO
37
+ )
38
+
39
+ class CompatibilityError(UpdateServiceError):
40
+ def __init__(self, launcher_version: str, target_version: str):
41
+ super().__init__(
42
+ f"❌ 版本兼容性错误\n\n"
43
+ f"启动器版本: {launcher_version}\n"
44
+ f"要安装的版本: {target_version}\n\n"
45
+ f"v2025.9b1 及以上版本需要**启动器 v0.5.0*** 或更高版本支持。\n"
46
+ f"请先升级启动器到 v0.5.0 以上版本。",
47
+ ''
48
+ )
49
+
50
+ class UpdateInstallError(UpdateServiceError):
51
+ def __init__(self, reason: str):
52
+ super().__init__(
53
+ f'Failed to start installation process: {reason}',
54
+ 'https://www.kdocs.cn/l/cetCY8mGKHLj?linkname=some-link' # TODO
55
+ )
56
+
57
+ class FeedbackServiceError(ServiceError):
58
+ """Base class for feedback service errors."""
59
+ pass
60
+
61
+ class ReportCreationError(FeedbackServiceError):
62
+ def __init__(self, reason: str):
63
+ super().__init__(
64
+ f'Failed to create bug report: {reason}',
65
+ 'https://www.kdocs.cn/l/cetCY8mGKHLj?linkname=some-link' # TODO
66
+ )
67
+
68
+ class UploadError(FeedbackServiceError):
69
+ def __init__(self, reason: str):
70
+ super().__init__(
71
+ f'Failed to upload bug report: {reason}',
72
+ 'https://www.kdocs.cn/l/cetCY8mGKHLj?linkname=some-link' # TODO
73
+ )
74
+
22
75
  class ProduceSolutionNotFoundError(KaaUserFriendlyError):
23
76
  def __init__(self, solution_id: str):
24
77
  self.solution_id = solution_id
@@ -79,3 +132,10 @@ class DmmGameLaunchError(KaaUserFriendlyError):
79
132
  f'绕过 DMM 启动器失败,原因:{reason}',
80
133
  'https://www.kdocs.cn/l/cetCY8mGKHLj?linkname=pSw7QcH1Kx'
81
134
  )
135
+
136
+ class WindowsOnlyError(KaaUserFriendlyError):
137
+ def __init__(self, feature_name: str):
138
+ super().__init__(
139
+ f'此功能({feature_name})仅在 Windows 上可用。当前系统为 {platform.system()}。请不要使用此功能,或在 Windows 上运行 kaa。',
140
+ 'https://www.kdocs.cn/l/cetCY8mGKHLj?linkname=LbvACPfiCw'
141
+ )