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.
- kaa/application/core/feedback_service.py +121 -0
- kaa/application/core/misc_core.py +4 -1
- kaa/application/core/update_service.py +208 -0
- kaa/config/schema.py +6 -0
- kaa/errors.py +60 -0
- kaa/main/gr.py +106 -516
- kaa/main/kaa.py +11 -3
- kaa/metadata.py +10 -0
- kaa/resources/__pycache__/__init__.cpython-310.pyc +0 -0
- kaa/resources/game.db +0 -0
- kaa/resources/game_ver.txt +0 -0
- kaa/resources/idol_cards/i_card-skin-amao-3-014_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-amao-3-015_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-atbm-1-000_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-atbm-1-000_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-atbm-2-000_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-atbm-2-000_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-atbm-3-000_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-atbm-3-000_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-fktn-3-016_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-fktn-3-016_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hmsz-3-003_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hmsz-3-003_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hmsz-3-009_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hmsz-3-009_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hmsz-3-013_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hmsz-3-013_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hrnm-3-015_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hrnm-3-015_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hski-3-015_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hski-3-015_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hume-3-009_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hume-3-009_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hume-3-015_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-hume-3-015_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-jsna-3-009_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-jsna-3-009_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-jsna-3-014_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-jsna-3-014_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-kcna-3-014_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-kcna-3-015_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-kcna-3-015_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-kllj-3-014_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-kllj-3-014_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-shro-3-015_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-shro-3-015_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-ssmk-3-015_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-ssmk-3-015_1.png +0 -0
- kaa/resources/idol_cards/i_card-skin-ttmr-3-015_0.png +0 -0
- kaa/resources/idol_cards/i_card-skin-ttmr-3-015_1.png +0 -0
- kaa/sprites/19513e9f-2cbb-4f66-84b7-2ad2faed252d.png +0 -0
- kaa/sprites/1ef5fa52-b6e1-42d0-947a-ce970eba057d.png +0 -0
- kaa/sprites/318abb8a-5950-4d22-ac42-77219b5bc1a0.png +0 -0
- kaa/sprites/321b7040-87d7-4f87-9b44-ad2972584a11.png +0 -0
- kaa/sprites/3ae72684-1d40-43cf-9508-511c010de64f.png +0 -0
- kaa/sprites/3e669188-5933-4502-b039-38f4d4649664.png +0 -0
- kaa/sprites/4370013d-f052-4314-94ff-a342d70754c3.png +0 -0
- kaa/sprites/4fb1d36c-5fb6-4fe5-9ba3-07e056eb1dfc.png +0 -0
- kaa/sprites/5247b052-5b45-4e64-b7fc-d566f5d4bc82.png +0 -0
- kaa/sprites/545a9032-a676-4d9d-ac74-2b2c9b330d1a.png +0 -0
- kaa/sprites/57741798-65dd-47eb-b4b1-b3f0e3c3e318.png +0 -0
- kaa/sprites/5e2b4bb9-f200-4723-96ac-5f907e28eaaa.png +0 -0
- kaa/sprites/5f6fafd9-43aa-443e-994e-f2688af5e238.png +0 -0
- kaa/sprites/61229c71-303b-4dc9-ba4e-6a14e5ab161e.png +0 -0
- kaa/sprites/62f93327-5946-4a48-aff8-a203483b0562.png +0 -0
- kaa/sprites/64dfeb35-61ad-4e9b-9847-a18530f02584.png +0 -0
- kaa/sprites/64f8ef99-4766-471b-aeb0-b109704d9615.png +0 -0
- kaa/sprites/677933e9-1481-4f01-95b4-d55bea51db8c.png +0 -0
- kaa/sprites/67edcd91-d2c1-418b-987a-e60263626f56.png +0 -0
- kaa/sprites/6c032aa7-20e3-4e2e-b1a4-1585141ba22b.png +0 -0
- kaa/sprites/6fadb00b-e32e-4c45-a738-f21b8f48c139.png +0 -0
- kaa/sprites/719297ec-82be-4820-8ecf-8bf6322b81fe.png +0 -0
- kaa/sprites/76970b91-7864-4413-bfc7-79c04a48dce7.png +0 -0
- kaa/sprites/7c62081d-097a-4514-a69d-69e96201e816.png +0 -0
- kaa/sprites/7e16af89-bb51-4889-8a7e-25715ff5faa1.png +0 -0
- kaa/sprites/7efce7bc-12a5-4a53-9a0a-9fa755649ebd.png +0 -0
- kaa/sprites/803fb770-6982-4460-8fe0-f9ccd67367c2.png +0 -0
- kaa/sprites/82200c8c-0916-4601-839a-945f96cc4ebc.png +0 -0
- kaa/sprites/8299e3e2-cfd5-4380-adce-a46c93b1be4d.png +0 -0
- kaa/sprites/83c27159-36d2-4ccf-ace7-e5d2169e7e52.png +0 -0
- kaa/sprites/8661bc83-9b0a-4555-8b21-2258b31c7f57.png +0 -0
- kaa/sprites/89437aca-7339-4795-b848-ec529b1e5e8d.png +0 -0
- kaa/sprites/8a0260f5-b32e-430e-bc98-7b5a77cab6ab.png +0 -0
- kaa/sprites/8c3bc157-022a-4bb1-be74-af1ad254e67f.png +0 -0
- kaa/sprites/8d09178a-251e-4f74-b023-12233417621b.png +0 -0
- kaa/sprites/8fbee6fe-9409-407e-8f55-d2d36ab37f6a.png +0 -0
- kaa/sprites/8fdc102b-d8f3-4d16-b8ef-1d804f5aff07.png +0 -0
- kaa/sprites/93e91dd0-0050-48b4-8bf8-c732cd76f0e3.png +0 -0
- kaa/sprites/993a33ac-994b-4eb0-9c1e-b9412d499d67.png +0 -0
- kaa/sprites/99a27ff1-bc1c-48a2-9f9b-0803338d1bd8.png +0 -0
- kaa/sprites/9a9a1f40-d308-4aa5-8d91-60342bc6a4e0.png +0 -0
- kaa/sprites/9f573ac2-9d28-4d92-8e3f-1b78031220dd.png +0 -0
- kaa/sprites/__pycache__/__init__.cpython-310.pyc +0 -0
- kaa/sprites/a2545c5c-b5cc-4fd2-93c1-04c74c17ee16.png +0 -0
- kaa/sprites/a2dd125b-9868-4e01-9a46-3b552c2ebdc9.png +0 -0
- kaa/sprites/a7f25aeb-d91b-47e0-ba1a-0c6382380102.png +0 -0
- kaa/sprites/a888e87e-49fe-405d-b074-3dda30304808.png +0 -0
- kaa/sprites/a9ba2741-38da-4448-ab80-f0e5b3c3847f.png +0 -0
- kaa/sprites/a9c5aeb0-c0c9-47da-8793-ffe8d172bea0.png +0 -0
- kaa/sprites/aba47934-f264-49f9-a72c-6ed90b112701.png +0 -0
- kaa/sprites/abe2757f-84f3-4967-bd05-79c17cb1f32c.png +0 -0
- kaa/sprites/acd741da-d4ab-4b76-a6a3-4a2fd25870ef.png +0 -0
- kaa/sprites/ad17ae00-f6ce-4f32-9386-9a8073b5e79a.png +0 -0
- kaa/sprites/ae73d26b-2d47-4921-a6ec-5bbea32773a3.png +0 -0
- kaa/sprites/b10281ae-cfaf-4400-b2fb-c8c2b432c8e7.png +0 -0
- kaa/sprites/b40bebbf-2800-40fb-b7a2-1c2d5995e747.png +0 -0
- kaa/sprites/b76add75-2187-428c-9ede-fb43086bacb6.png +0 -0
- kaa/sprites/b77a7e97-dc59-493d-9d76-4ea9c2876978.png +0 -0
- kaa/sprites/b9770cd2-b55f-44dc-965f-f29686fba7da.png +0 -0
- kaa/sprites/ba8ee2cd-f662-440c-90b3-1e4bfe7bab6b.png +0 -0
- kaa/sprites/bb3990c8-4618-4d96-9365-a4d1213b59f7.png +0 -0
- kaa/sprites/bbe59f62-c3e7-404c-a313-b50db70de7b5.png +0 -0
- kaa/sprites/bdb1460e-c5db-494a-a58a-688f72b6bdba.png +0 -0
- kaa/sprites/bdb72f31-5808-4451-827f-fffc3b616083.png +0 -0
- kaa/sprites/bf3ff37e-d4fc-42ee-87d6-db1e2040aed5.png +0 -0
- kaa/sprites/bff753bb-b02e-441b-89e5-14845f18c6f6.png +0 -0
- kaa/sprites/c035ac76-39e9-466b-a606-28bc52bc73e8.png +0 -0
- kaa/sprites/c05a600a-d79e-432d-a49f-5b2443d67bd4.png +0 -0
- kaa/sprites/c0801be3-f07a-4afc-ab0d-7f5d3c4afbd3.png +0 -0
- kaa/sprites/c2100faf-1234-49db-b6d4-5a08a4b08272.png +0 -0
- kaa/sprites/c6b0f9ba-a976-474b-b22d-6fe4391d9373.png +0 -0
- kaa/sprites/c78fb143-18e3-4697-a0c1-6151514f2a7c.png +0 -0
- kaa/sprites/c8c17304-e949-4dfc-b07d-9e7133483e31.png +0 -0
- kaa/sprites/c91874f4-363f-4997-a38e-3e486dfd8043.png +0 -0
- kaa/sprites/c9245201-4d29-4088-a5e0-f4e93d4494b5.png +0 -0
- kaa/sprites/cb0bbf0f-a25b-4ec4-99bd-f5742270a062.png +0 -0
- kaa/sprites/ccfab3e2-7b6d-4ae3-998b-4e5c1863884a.png +0 -0
- kaa/sprites/cdf310f0-b917-4f92-95a9-893af76e3c3a.png +0 -0
- kaa/sprites/cea8f98d-ba68-498f-bd3d-cc10f0d4575b.png +0 -0
- kaa/sprites/cec36685-85a7-4e84-bbbc-4df70b4f7bac.png +0 -0
- kaa/sprites/cf49878d-a1c5-4b9f-9502-1e0d9eaadc49.png +0 -0
- kaa/sprites/d23a600a-7002-4268-96a4-18dc54928ec6.png +0 -0
- kaa/sprites/d57f792a-f086-4fbe-b4d9-5db629a78d42.png +0 -0
- kaa/sprites/d6dd92b3-310f-4f5d-a8ef-b941c3659c0c.png +0 -0
- kaa/sprites/d8967770-c64a-4609-a0a5-f46ba81edceb.png +0 -0
- kaa/sprites/d91483a2-83fa-4664-8eda-52498c0e77bc.png +0 -0
- kaa/sprites/d9a636be-a017-4ef5-a70c-c374827008a0.png +0 -0
- kaa/sprites/dae37bd7-6a34-4eb4-8cd0-3c0c03b4575a.png +0 -0
- kaa/sprites/dc51eccf-9470-495a-9e38-59d4481adbd4.png +0 -0
- kaa/sprites/dcea5aae-322e-4cd4-b218-0eac48690755.png +0 -0
- kaa/sprites/dcf465c6-ad64-48e7-9c3c-7bc7cfc13a44.png +0 -0
- kaa/sprites/ddb59f04-91a0-4fbd-8921-be13acdab291.png +0 -0
- kaa/sprites/de81f919-4d01-4a4e-bdc1-ffe6e23a5c22.png +0 -0
- kaa/sprites/e05f2c16-926f-48be-bdd0-16182e879394.png +0 -0
- kaa/sprites/e2a0c1a6-c0cf-400e-99be-1ed0d35c6ed8.png +0 -0
- kaa/sprites/e30922ed-a02f-4ede-9968-1656be5a05b2.png +0 -0
- kaa/sprites/e388db01-0870-412d-b8bc-5a512ec997c8.png +0 -0
- kaa/sprites/e392856d-ac59-4414-8fb8-df93a1a99be4.png +0 -0
- kaa/sprites/e57db8c2-c050-43fb-8205-339aeb5875e8.png +0 -0
- kaa/sprites/e687c2ba-2c30-4fc8-804f-fea5815f6765.png +0 -0
- kaa/sprites/e6e66204-8a2f-4377-8674-b7d663ff0081.png +0 -0
- kaa/sprites/e79a2a08-3b58-4ab0-8c2b-769f30cc8591.png +0 -0
- kaa/sprites/ebe22aea-0318-49d8-ab07-ce2eef34265f.png +0 -0
- kaa/sprites/ed6df33a-c7aa-4542-a87b-9cc9cae0465c.png +0 -0
- kaa/sprites/ed854df1-878c-4e0b-8138-9b28d314ede6.png +0 -0
- kaa/sprites/ed98a341-5dff-4af7-a194-d28232d481a4.png +0 -0
- kaa/sprites/f0ed1dd3-b227-48c1-8c8c-858dbd84fcc7.png +0 -0
- kaa/sprites/f1eb4089-8cd1-4830-b00e-40535ddcd116.png +0 -0
- kaa/sprites/f237d88e-92ac-4ebf-85e1-80a696b5203a.png +0 -0
- kaa/sprites/f2f818c9-b0cf-436d-9d3e-6544c5399063.png +0 -0
- kaa/sprites/f333118a-81c2-417f-b54f-64dc4e8df613.png +0 -0
- kaa/sprites/f34e8026-bdfc-47e6-a0ed-49e587ef0f40.png +0 -0
- kaa/sprites/f3a5992b-dabf-4c2b-83e9-4c91c3b7aac8.png +0 -0
- kaa/sprites/f4195ceb-586a-4a8c-9424-4962239d2120.png +0 -0
- kaa/sprites/f485db66-2159-4d31-ba53-0fbb726e7f64.png +0 -0
- kaa/sprites/f7264cee-fea6-47b5-9f9b-8f3f31c03ea0.png +0 -0
- kaa/sprites/f7e34403-a53c-4d3f-935b-25b4acb7f7a5.png +0 -0
- kaa/sprites/f8d8c943-1b36-4391-a7fc-2a49f8966d53.png +0 -0
- kaa/sprites/f9157db8-d70b-4d46-9800-5a833ce7eda8.png +0 -0
- kaa/sprites/f9a353b2-958d-4aae-ade4-66bdc6481e35.png +0 -0
- kaa/sprites/fa5b5b92-9c60-4811-a44c-8e897c9632c3.png +0 -0
- kaa/sprites/fac7b90a-1174-477b-803b-28798647c307.png +0 -0
- kaa/sprites/fbbb73f9-880e-4c7f-9ec9-276bdab4b394.png +0 -0
- kaa/sprites/fce4a481-e71c-4dab-aeac-59ff8b18201b.png +0 -0
- kaa/sprites/fd8a7a5d-f021-4bfd-83f7-a2dd33325837.png +0 -0
- kaa/sprites/fda4b3eb-e31a-448b-8cb3-9126e1ab7deb.png +0 -0
- kaa/sprites/fda78372-04b4-4d55-92b1-aedec20d0913.png +0 -0
- kaa/sprites/fe993a91-1a49-488e-b7ff-c1b05b8f2b5f.png +0 -0
- kaa/sprites/ff8efb8f-e1a4-4202-a6e1-680eb44f58da.png +0 -0
- kaa/tasks/R.py +128 -128
- kaa/tasks/common.py +5 -0
- kaa/tasks/daily/contest.py +2 -1
- kaa/tasks/produce/cards.py +5 -4
- kaa/tasks/produce/common.py +201 -105
- kaa/tasks/produce/in_purodyuusu.py +14 -10
- kaa/tasks/produce/non_lesson_actions.py +10 -33
- kaa/tasks/produce/p_drink.py +5 -1
- kaa/tasks/produce/produce.py +2 -1
- kaa/tasks/start_game.py +2 -1
- {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/METADATA +9 -6
- {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/RECORD +323 -177
- /kaa/sprites/{fdf0da06-f088-424f-9941-8c883fea3db3.png → 03d0acec-15fd-4c21-82ce-122764def185.png} +0 -0
- /kaa/sprites/{68d9f340-a3d2-4708-8eb1-c1ed857decda.png → 03d22cb3-0193-4dcb-8a0d-98b7ca9c2b4c.png} +0 -0
- /kaa/sprites/{dce410ee-fa56-41c4-b75e-e1bff79cd94f.png → 0455e229-75c9-44ba-8729-745799746979.png} +0 -0
- /kaa/sprites/{ad94041c-f30b-40b9-b11a-1a26e9962274.png → 049ecbf6-d434-46fa-a42c-a447475269bb.png} +0 -0
- /kaa/sprites/{f6b042a8-a91e-4811-99f9-18bbb5197468.png → 04ea8503-cdd5-4b3e-a33b-63893b92f6ba.png} +0 -0
- /kaa/sprites/{847226a3-b7d2-4156-b732-9215a3e14f3a.png → 05251a85-2883-4098-842e-6544391de919.png} +0 -0
- /kaa/sprites/{9008fbb2-f23f-424f-9be7-5bae6a3697ab.png → 054db45e-1434-4604-91ec-7ac586ca11b5.png} +0 -0
- /kaa/sprites/{ae1e70bc-f735-4749-8c23-95735b91897a.png → 06cf74aa-635f-48ab-b965-36981f2063d3.png} +0 -0
- /kaa/sprites/{3b4f90c9-6de7-4ac3-8e41-5f8757bf3f3e.png → 0814c0fd-6f89-47d3-8089-e8cfde569750.png} +0 -0
- /kaa/sprites/{2cec1d6a-9e8c-49b3-b885-0b0d7c4b95ee.png → 08bde3ff-7554-4bdb-a7f0-193323489d5b.png} +0 -0
- /kaa/sprites/{91b30f5e-31b2-4756-a3f7-f0f82a335442.png → 09222fb0-78a6-4663-8c1f-1d44e881513d.png} +0 -0
- /kaa/sprites/{5431dc38-c257-40b3-8f7b-8bceaa7fe587.png → 0b436edb-8f6a-429d-87b7-5d4250f651ac.png} +0 -0
- /kaa/sprites/{338d7e71-98ce-4cd1-9954-bf7155150780.png → 0c266b0e-de7a-49c1-9709-b01fb5086f75.png} +0 -0
- /kaa/sprites/{8e019262-ad23-4cbb-84da-86b34775a91e.png → 0db579bf-d555-4468-8104-c2d2e68d33b1.png} +0 -0
- /kaa/sprites/{8be81341-a74d-42c8-8231-5d1854bc08e7.png → 114730f6-eddd-4381-b723-aee18cde0d90.png} +0 -0
- /kaa/sprites/{31f2de0a-567b-425a-9be6-536e4532d813.png → 11870372-dc78-4a80-8320-15bb24da6f25.png} +0 -0
- /kaa/sprites/{3fa5f81c-9223-44ba-bf07-71932350e845.png → 11bc7d35-e58d-4301-a0b0-f557dbd73c7b.png} +0 -0
- /kaa/sprites/{92c3de1b-eed1-45b9-82e0-c9e97bb479e7.png → 12455dbd-7d70-4435-a3ba-f40654e75c37.png} +0 -0
- /kaa/sprites/{aa1624ff-88b0-447b-8e2b-8a50fd9e4062.png → 12f330a6-4eab-4015-b0e3-4e1a35a7b676.png} +0 -0
- /kaa/sprites/{9991b19c-7330-42c4-9d7d-db3cb00103b7.png → 14a697d4-0b58-4644-bb2d-8823d2fefcb8.png} +0 -0
- /kaa/sprites/{49bde219-f9a3-41b5-84b8-e417160a0f40.png → 15605f7a-2206-436c-8a71-011d9f95cf4e.png} +0 -0
- /kaa/sprites/{ea430652-e263-4a15-bb6f-8a8807be6c8f.png → 15dd89cc-53ed-4c77-a355-62e3bd7a15dd.png} +0 -0
- /kaa/sprites/{5c310fe5-7e92-4167-9eba-6e8e14a2863a.png → 18b13508-c46f-4134-b991-975c0a1b9a74.png} +0 -0
- /kaa/sprites/{cd00a2d7-af48-48b1-b2e1-5360ceed249f.png → 1a5c147b-e28e-42ad-893a-7430d8f4fc35.png} +0 -0
- /kaa/sprites/{94d54ba7-0ccf-4fd9-a5bf-488bac1364c8.png → 1b3c84c5-16d1-43a7-8513-719bd7a10450.png} +0 -0
- /kaa/sprites/{2289d38f-dc98-4310-9f34-4cf5023f8545.png → 1b847790-90e2-44f8-b6d9-4814812006bd.png} +0 -0
- /kaa/sprites/{6c926e92-9af9-402d-8512-6417ca116928.png → 1e57ab88-9962-4024-81df-746529a758f9.png} +0 -0
- /kaa/sprites/{30e12bf1-8fa5-4de1-8d7b-28fa0fec0cb6.png → 205e03de-46d9-4983-a2ea-a7f7500d508f.png} +0 -0
- /kaa/sprites/{e4dc3b35-195c-415f-9484-c2459bd8675a.png → 20bd834e-c99c-4e80-92db-0740e5bbe746.png} +0 -0
- /kaa/sprites/{68e20ebf-02fd-46a1-88d7-b4472824e7bc.png → 218a6ab3-93f6-4bb1-9848-8c97ff695945.png} +0 -0
- /kaa/sprites/{ec3cad5f-e0c9-4577-8499-79b50248344e.png → 22071c63-a1bc-4163-8d5a-973b3d579c76.png} +0 -0
- /kaa/sprites/{e933cd55-e47a-4327-89d7-b25995cb4a3f.png → 2460d0c9-50e2-451b-b609-ad466b574395.png} +0 -0
- /kaa/sprites/{0af1d573-1dc7-427e-997d-173308ea3649.png → 264d021a-b322-4472-8a7b-5f1322aba993.png} +0 -0
- /kaa/sprites/{57c81080-7b53-4286-8fa5-848ad63e4774.png → 28335ba3-9a0f-46cd-b66d-047781773264.png} +0 -0
- /kaa/sprites/{d7750f81-de10-4d6f-9cc7-35223bda9d70.png → 28df544b-72f2-4ed8-8bf3-609ff99633d9.png} +0 -0
- /kaa/sprites/{81686816-c723-47d1-9824-a68d9ebe1bd4.png → 2a82e2d6-0722-433a-87fa-f1752ce0b9b7.png} +0 -0
- /kaa/sprites/{5ffd3f29-db4f-4f66-b9ed-be5a70b7ebf9.png → 2abce6a4-111f-42bb-9255-f98d544108de.png} +0 -0
- /kaa/sprites/{23b9cda9-8be8-438e-8e54-57d91a4bd875.png → 2d8e6464-aceb-41fd-9e78-7523738d5720.png} +0 -0
- /kaa/sprites/{1ad89ee4-1bb1-41d2-a92c-79caf6baa38a.png → 2f9e2dbb-66a1-4b13-9b9e-d62e10efa6d3.png} +0 -0
- /kaa/sprites/{c69dcdcf-42a7-420e-aa8e-bb8639ea80b6.png → 307b58f0-20c1-41bd-9eaa-1337fd0e6563.png} +0 -0
- /kaa/sprites/{55c3af20-58dc-4407-a383-312a57417c39.png → 3192a62f-224d-44b1-a0b9-b1fc22de8ec1.png} +0 -0
- /kaa/sprites/{645909d7-b960-46c7-b208-db44b6b7feec.png → 31b4c370-696f-4dfc-a918-839495520266.png} +0 -0
- /kaa/sprites/{7daaca55-e3fd-4e12-bf31-872105ceb726.png → 330c2207-af32-453b-8db7-889cda83e7cc.png} +0 -0
- /kaa/sprites/{5734e48a-1e58-42de-be7b-b7db67db4a01.png → 38186efc-850c-4d83-97bc-9417f1494b94.png} +0 -0
- /kaa/sprites/{8ed51be4-815c-4a3d-805e-030fdfa341e2.png → 38426696-ff13-4f20-9f74-b05855990153.png} +0 -0
- /kaa/sprites/{cfe3563d-a24b-4197-a0cb-5628bd990c08.png → 3a211792-1243-496a-b41e-0e3fd121cd5b.png} +0 -0
- /kaa/sprites/{179c0fff-ebd2-4a16-8db2-297552cca218.png → 3a4e2d8a-deca-4980-b6c2-37bfc17d2720.png} +0 -0
- /kaa/sprites/{2d0e9d49-365a-4bcb-a416-38b87defaa3c.png → 3a4ec054-2c48-4359-afb9-fa5ea8191d16.png} +0 -0
- /kaa/sprites/{51b95c81-4ff9-434c-ade2-3518e63337cb.png → 3c490171-6810-44f0-b28d-c6b664347a3c.png} +0 -0
- /kaa/sprites/{35341839-4469-4ab6-aa40-33642fe43e82.png → 3cda578a-fa75-4bbd-9cff-be4bc4355a58.png} +0 -0
- /kaa/sprites/{72634cb3-4c76-4ca2-8898-ebb837ec19e3.png → 3ea03db7-4de9-45c4-a07b-a9bbc2c63e70.png} +0 -0
- /kaa/sprites/{da48db0d-09d9-47c3-9e08-8b69ad547be6.png → 3ea8e354-2684-46f3-9f5a-43f094717c95.png} +0 -0
- /kaa/sprites/{3e087b8d-420d-48ff-b526-29c4a65d8cbe.png → 3eb9b21b-abbe-49fd-a3a9-6e1c1a6e91d9.png} +0 -0
- /kaa/sprites/{2234f709-1703-4589-905c-175f4db09b1b.png → 3fb84a71-ed15-4989-9598-34e7342f38f5.png} +0 -0
- /kaa/sprites/{39f6d657-3b3e-40aa-849b-7ad87a0be1d0.png → 3ffd2992-fa55-499c-8c3b-193518ebbe07.png} +0 -0
- /kaa/sprites/{464b1dd8-ca2e-41e9-a5b5-90545c584db7.png → 41ff9641-d200-4caa-bcfa-d8389a3438eb.png} +0 -0
- /kaa/sprites/{70768479-5d7a-4941-8774-ad556c47bee2.png → 455dcf19-63f5-4b0a-99e6-b23d3876d199.png} +0 -0
- /kaa/sprites/{694879e8-ecca-45e2-8ea4-1b447fd43ace.png → 45f09e08-53ea-4e08-97dc-70f689bab002.png} +0 -0
- /kaa/sprites/{dd873ac0-ffba-4335-9cf2-2162c6835ed8.png → 4729b509-0f4a-4e96-b186-ec56c680c9e6.png} +0 -0
- /kaa/sprites/{7d7df15f-707e-4e27-826f-21e42af1dae0.png → 4eb665ef-7741-40f9-8174-7b6ca66d045b.png} +0 -0
- /kaa/sprites/{8e5e968b-edad-4c03-abc8-3f2a7e8879ae.png → 4f370ff6-61d1-405a-b29e-e6d0b3072194.png} +0 -0
- /kaa/sprites/{f0462447-5226-4819-a39b-19ab90583f83.png → 504e4927-bfeb-43ee-aa5c-35cec664a4c8.png} +0 -0
- /kaa/sprites/{756f4ca7-acac-48e1-8bcd-1c5cd8937e3a.png → 51eb4be2-22fa-4683-82c7-513f5934f7b9.png} +0 -0
- /kaa/sprites/{87f3c1ae-5117-4871-a7d6-3f5ff0c9f9fb.png → 568608bd-a1fa-4faf-ae15-179563a7e84f.png} +0 -0
- /kaa/sprites/{978873bb-e4d0-451b-9126-6977144f5395.png → 56ac84af-4c85-4b69-b449-98981c1df292.png} +0 -0
- /kaa/sprites/{db6707a2-2964-4919-9992-4d801fa43dae.png → 5a49b6d2-2bcb-49bc-a28f-b8bd1441f60a.png} +0 -0
- /kaa/sprites/{01256311-237c-476f-96ce-4136dc4bfbd3.png → 5a677634-99cf-45b5-bc0c-94120872a518.png} +0 -0
- /kaa/sprites/{8e4d8a0f-4a9d-4562-9234-63806b11d85f.png → 5ec51718-1403-4a79-bd85-46e1fe04d8c9.png} +0 -0
- /kaa/sprites/{dc97fea3-898f-4135-9c40-ad41570ab4ae.png → 5f2d0b2b-8425-4dd8-8b85-d62f4b75286c.png} +0 -0
- /kaa/sprites/{f32a41a2-c482-41ba-b718-28f048f5148c.png → 5f4abae0-a1f0-4c8c-9d93-a8525caa9dd0.png} +0 -0
- /kaa/sprites/{31e3ac2b-ecd4-4c37-88bc-985ef32e73a3.png → 6005bf30-fd7c-401e-8efd-050fa97ad7f3.png} +0 -0
- /kaa/sprites/{3b4dc708-1d34-4a88-9fe3-d8de2ec1d5c8.png → 6069f8bc-2a06-45a4-95ca-1ac9d8fa3b04.png} +0 -0
- /kaa/sprites/{962aa0b9-1dd3-4260-a4fb-c069c26e5a84.png → 60896822-de58-4e07-b2d9-86a7f4068de1.png} +0 -0
- /kaa/sprites/{889a4153-b713-49cb-a4d5-e302bcdd002d.png → 622d700e-0fd8-4a92-a286-1e8143c70570.png} +0 -0
- /kaa/sprites/{b59c0e9b-1f20-4194-ab37-286f505fa656.png → 63b74752-73ce-4020-a7c8-0a71a9f67415.png} +0 -0
- /kaa/sprites/{4a081370-b0a1-4067-8470-e3007cc68a12.png → 648d43f6-b251-4d6f-a808-ae7325c91a59.png} +0 -0
- /kaa/sprites/{bfdc9b53-2fe5-43f1-8588-7ab71217d31c.png → 65f79941-1c78-496a-a67c-c50f4227bd34.png} +0 -0
- /kaa/sprites/{9e7eaa8e-3178-44da-a5ec-34b889f8facf.png → 6f50cd3b-6e46-46c5-99ed-26728d3212ad.png} +0 -0
- /kaa/sprites/{ab237c6d-c4d8-4716-8ef7-99b8e995c9a7.png → 6f6d7af3-8380-439b-9d26-3fbd5a103b49.png} +0 -0
- /kaa/sprites/{1befe09b-cb77-417a-b21e-7746804d4e03.png → 71913fde-c3db-463d-800d-e1b35fa2c8b4.png} +0 -0
- /kaa/sprites/{e7f2734f-9fdc-4521-8d7e-8b0fe270a223.png → 71976c1a-5df9-44a5-b4ea-08b5d617d813.png} +0 -0
- /kaa/sprites/{9f7150bc-c0b8-48d6-862c-456aaf518b2b.png → 72a8bcd2-3f32-4ee5-8295-eedf441d6a1a.png} +0 -0
- /kaa/sprites/{cd0e8663-2ea1-436a-b9fb-3caa0c3ed9e8.png → 73b6f3aa-5179-41d6-a82e-22e14aa8cd6a.png} +0 -0
- /kaa/sprites/{cba0646d-dffe-4c5b-a44d-1f8d827624a6.png → 7a74b5f5-7a04-4678-8e6e-57b5de127182.png} +0 -0
- /kaa/sprites/{5930140e-effe-4bcf-b0be-c20d3990d833.png → 7b4c3a81-8f09-4a00-90ee-d4df3f57e863.png} +0 -0
- /kaa/sprites/{cb6dffd9-6474-4d09-aee6-26352ea51d31.png → 7c4ca388-5167-478a-a32b-0e108edad888.png} +0 -0
- /kaa/sprites/{96704aa3-b5ad-4e34-bb88-fad766415362.png → 7d4709f8-6d0d-493f-819e-74cb0f7c166b.png} +0 -0
- /kaa/sprites/{fcc72120-2a77-4c26-a27e-e1027c6088c0.png → 7e8904fd-5863-471f-8e9a-d69d9ca72f8f.png} +0 -0
- /kaa/sprites/{023b8f4c-15ab-4845-b141-446c861ad475.png → 80800c2e-417d-4118-b726-93aaabfc08bd.png} +0 -0
- /kaa/sprites/{f0aef696-2106-46a4-8b7f-9f16b6c89d3f.png → 81b1b160-2d0f-42ad-924a-9572a54f343a.png} +0 -0
- /kaa/sprites/{13cb0309-b713-4725-b10b-26afe46eb9c0.png → 82259f79-2bef-442b-bf16-78cb4f22e3be.png} +0 -0
- /kaa/sprites/{43a367e1-91dd-495e-8c30-41903f75a99a.png → 861a4faa-2522-41e9-8e20-7bd9180bea5a.png} +0 -0
- /kaa/sprites/{01247ebe-8d63-4573-90f4-d8dc2b7ca14c.png → 87ed135a-2eb1-4e21-8928-d0307a22ea66.png} +0 -0
- /kaa/sprites/{1cf03f98-63e9-467c-804d-c74dd97b69bd.png → 8805fead-f7e2-4905-a42e-05ebba2fbe21.png} +0 -0
- /kaa/sprites/{16a0fd47-e85b-4848-8894-9d071ea993ac.png → 88be2dcc-68ca-4596-9b2c-544a196cab64.png} +0 -0
- /kaa/sprites/{a5694c76-3c5d-462e-81d5-1e0e6cef0ec9.png → 89841ff0-e834-4a7e-b9d5-00a9490b6b7f.png} +0 -0
- /kaa/sprites/{84cabff2-7a1b-4018-b74b-46f4db06304f.png → 8bf08bab-7c55-45e1-8433-c2213a323480.png} +0 -0
- /kaa/sprites/{e5e49b44-dcc2-4e77-9180-0d2beaa3f9ad.png → 8d416e23-04ef-47bd-8cc8-7f18d1bab736.png} +0 -0
- /kaa/sprites/{c1d502eb-c77f-45cb-86b5-11b4a8a3aef5.png → 8f9dd0f0-f9af-4eec-a89e-8f2c92f88a98.png} +0 -0
- /kaa/sprites/{424a0ef5-102d-4734-a731-2b3b3c7c9682.png → 9088f8c0-59f8-41c6-994c-ae283ac94c24.png} +0 -0
- /kaa/sprites/{91a50322-52d9-4516-9e46-bc121f20667d.png → 922af7d1-75e9-4ac8-a4e7-2dad8bb1ca87.png} +0 -0
- /kaa/sprites/{d81b1325-e57a-4f22-93e1-6ad4baa28935.png → 94ed55fe-3ef8-46bc-855a-a7b1dedab801.png} +0 -0
- /kaa/sprites/{913dbd4e-ebb1-4c9f-b145-9960cde59c17.png → 95d715c3-d569-48b5-be7b-c21cd2a160db.png} +0 -0
- /kaa/sprites/{dd7bd6cd-90f1-4773-9b68-5df7f2f84da5.png → 97a3791d-fa9d-453d-8081-c574fe88b823.png} +0 -0
- /kaa/sprites/{2204967a-a0ee-4dd3-aecb-4d531e8e954c.png → 9acd9a59-004f-4e1d-a208-0c293f2702d5.png} +0 -0
- /kaa/sprites/{572a921d-633f-4465-b177-7a0d9ad7e099.png → 9f3bfe36-8462-404f-94da-9bc324b1beed.png} +0 -0
- /kaa/sprites/{799fe395-2264-4bc5-b515-813dadda8fe1.png → 9f46f543-d7dc-4836-a210-125d686475f9.png} +0 -0
- /kaa/sprites/{5bf2a814-df85-4d0a-b4b5-8883ac2ee434.png → a34502b4-10bd-42ca-9ada-a9cdb57097dc.png} +0 -0
- /kaa/sprites/{043e753e-db15-45ba-8513-53c3fc9c7f3c.png → a3fe5859-62ba-403e-9367-65db0ad15943.png} +0 -0
- /kaa/sprites/{8f7b55d8-0143-4d27-bef8-560d4d510500.png → a42ac612-acbd-45cc-88fb-104ff9b7d2d8.png} +0 -0
- /kaa/sprites/{736a9daf-05d6-46ba-810b-5a8f509152d1.png → a4c6d967-0251-4b33-acb3-81d24f82d5a4.png} +0 -0
- /kaa/sprites/{edcec31d-d5de-4f22-b666-3e3c656e06d8.png → a6ed21f0-4da4-4065-bb59-062a70e132ca.png} +0 -0
- /kaa/sprites/{e9310e38-a418-4561-bf33-eb3e6dccf477.png → a97e2840-1575-4f2c-97df-6a720c644969.png} +0 -0
- /kaa/sprites/{d644faa3-ff16-417f-928c-4c62b040bfdb.png → ae0ce964-eb8f-45a1-aa4d-f47a5c8c720f.png} +0 -0
- /kaa/sprites/{256ffeba-8e9e-4cc5-8a1c-9eaee427f1a5.png → ae106b38-da4f-4b0d-b9c3-541fd58f4de7.png} +0 -0
- /kaa/sprites/{802db04f-77c2-46a4-a6eb-f81d48ea03ce.png → aeab8f9a-fe61-4c2d-a494-ffc19a9cae91.png} +0 -0
- /kaa/sprites/{37215a56-f8e1-4f22-a148-9894136f6ab1.png → affc87db-2f63-4e4a-855e-6ff608226f1e.png} +0 -0
- /kaa/sprites/{d1ea0ea6-4a6a-4036-b140-922c95a648b5.png → b02c15b5-04b4-40d9-bb13-267786e8e049.png} +0 -0
- /kaa/sprites/{22dc4cfe-8c66-4461-8660-e2d11bbe6154.png → b7f62cab-cc24-480e-bf4c-25c43a1e801e.png} +0 -0
- /kaa/sprites/{5906d986-d0e5-452d-a7c4-ddeb7af8751d.png → bd4cd421-f702-47c0-9f8b-77914973108c.png} +0 -0
- /kaa/sprites/{8bd22fe1-b544-4d2e-b74a-34f3cf0eb512.png → c4505a31-74c5-4b3d-bfcf-a67c3ef0039e.png} +0 -0
- /kaa/sprites/{e13fc34b-accc-4986-865d-f8d8410b45e9.png → c6b6b77b-2ec7-4fb7-8033-f4d061f4e9c8.png} +0 -0
- /kaa/sprites/{2b6d2eb0-bcf7-4bea-b037-6293d9c6d728.png → c76c6ccb-d099-4c3c-9eda-13be33aa48ae.png} +0 -0
- /kaa/sprites/{0562f69f-0300-4a2b-8252-63f3e7180e4c.png → cb15d9a3-78fe-4f03-bd23-90ba6169ddff.png} +0 -0
- /kaa/sprites/{2a8626df-056c-46a2-aaf3-0060a5aef6a3.png → d1bdfa3b-34df-488d-9f9b-8c7b04dd4ab3.png} +0 -0
- /kaa/sprites/{3aed50a2-d640-4178-9b8a-4dd7973eebf1.png → d8ba1932-978c-451c-a717-d7d2b6db35d9.png} +0 -0
- /kaa/sprites/{f635499a-943d-47da-952a-1feb58daa25b.png → e7630ccb-6824-49e3-986f-2a65a2c4a948.png} +0 -0
- /kaa/sprites/{847eb5c0-0350-4b7c-9c9c-43c796709795.png → ec35a0b8-1afa-48ff-ae66-9c1ef966348d.png} +0 -0
- {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/WHEEL +0 -0
- {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/entry_points.txt +0 -0
- {ksaa-2025.11b1.dist-info → ksaa-2025.11b3.dist-info}/licenses/LICENSE +0 -0
- {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.
|
|
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
|
+
)
|