Initial release
This commit is contained in:
parent
bb5d2e2510
commit
592087fea9
|
@ -0,0 +1,20 @@
|
|||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
pywinauto = "*"
|
||||
pillow = "*"
|
||||
psutil = "*"
|
||||
pytesseract = "*"
|
||||
pyinstaller = "*"
|
||||
httpx = {extras = ["brotli", "http2"], version = "*"}
|
||||
tqdm = "*"
|
||||
rapidfuzz = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.11"
|
||||
python_full_version = "3.11.5"
|
|
@ -0,0 +1,524 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "cd3f12ab9e04f6f3f5949a12cd0ff2221ba1a12584ad3096659443a37e92ea79"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_full_version": "3.11.5",
|
||||
"python_version": "3.11"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"altgraph": {
|
||||
"hashes": [
|
||||
"sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406",
|
||||
"sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"
|
||||
],
|
||||
"version": "==0.17.4"
|
||||
},
|
||||
"anyio": {
|
||||
"hashes": [
|
||||
"sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f",
|
||||
"sha256:f7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==4.0.0"
|
||||
},
|
||||
"brotli": {
|
||||
"hashes": [
|
||||
"sha256:03d20af184290887bdea3f0f78c4f737d126c74dc2f3ccadf07e54ceca3bf208",
|
||||
"sha256:0541e747cce78e24ea12d69176f6a7ddb690e62c425e01d31cc065e69ce55b48",
|
||||
"sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354",
|
||||
"sha256:0b63b949ff929fbc2d6d3ce0e924c9b93c9785d877a21a1b678877ffbbc4423a",
|
||||
"sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128",
|
||||
"sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c",
|
||||
"sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088",
|
||||
"sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9",
|
||||
"sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a",
|
||||
"sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3",
|
||||
"sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438",
|
||||
"sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578",
|
||||
"sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b",
|
||||
"sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b",
|
||||
"sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68",
|
||||
"sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d",
|
||||
"sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd",
|
||||
"sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409",
|
||||
"sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da",
|
||||
"sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50",
|
||||
"sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0",
|
||||
"sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180",
|
||||
"sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d",
|
||||
"sha256:4d4a848d1837973bf0f4b5e54e3bec977d99be36a7895c61abb659301b02c112",
|
||||
"sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc",
|
||||
"sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265",
|
||||
"sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327",
|
||||
"sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95",
|
||||
"sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd",
|
||||
"sha256:5eeb539606f18a0b232d4ba45adccde4125592f3f636a6182b4a8a436548b914",
|
||||
"sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0",
|
||||
"sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a",
|
||||
"sha256:6172447e1b368dcbc458925e5ddaf9113477b0ed542df258d84fa28fc45ceea7",
|
||||
"sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0",
|
||||
"sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451",
|
||||
"sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f",
|
||||
"sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e",
|
||||
"sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248",
|
||||
"sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91",
|
||||
"sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724",
|
||||
"sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966",
|
||||
"sha256:890b5a14ce214389b2cc36ce82f3093f96f4cc730c1cffdbefff77a7c71f2a97",
|
||||
"sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d",
|
||||
"sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf",
|
||||
"sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac",
|
||||
"sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951",
|
||||
"sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74",
|
||||
"sha256:929811df5462e182b13920da56c6e0284af407d1de637d8e536c5cd00a7daf60",
|
||||
"sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c",
|
||||
"sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1",
|
||||
"sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8",
|
||||
"sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d",
|
||||
"sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc",
|
||||
"sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61",
|
||||
"sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460",
|
||||
"sha256:a743e5a28af5f70f9c080380a5f908d4d21d40e8f0e0c8901604d15cfa9ba751",
|
||||
"sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9",
|
||||
"sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1",
|
||||
"sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474",
|
||||
"sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2",
|
||||
"sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6",
|
||||
"sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9",
|
||||
"sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2",
|
||||
"sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467",
|
||||
"sha256:cdbc1fc1bc0bff1cef838eafe581b55bfbffaed4ed0318b724d0b71d4d377619",
|
||||
"sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf",
|
||||
"sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408",
|
||||
"sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579",
|
||||
"sha256:d192f0f30804e55db0d0e0a35d83a9fead0e9a359a9ed0285dbacea60cc10a84",
|
||||
"sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b",
|
||||
"sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59",
|
||||
"sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752",
|
||||
"sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80",
|
||||
"sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0",
|
||||
"sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2",
|
||||
"sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3",
|
||||
"sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64",
|
||||
"sha256:f296c40e23065d0d6650c4aefe7470d2a25fffda489bcc3eb66083f3ac9f6643",
|
||||
"sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e",
|
||||
"sha256:f733d788519c7e3e71f0855c96618720f5d3d60c3cb829d8bbb722dddce37985",
|
||||
"sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596",
|
||||
"sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2",
|
||||
"sha256:fdc3ff3bfccdc6b9cc7c342c03aa2400683f0cb891d46e94b64a197910dc4064"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082",
|
||||
"sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2023.7.22"
|
||||
},
|
||||
"colorama": {
|
||||
"hashes": [
|
||||
"sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44",
|
||||
"sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"
|
||||
],
|
||||
"markers": "platform_system == 'Windows'",
|
||||
"version": "==0.4.6"
|
||||
},
|
||||
"comtypes": {
|
||||
"hashes": [
|
||||
"sha256:26f261b1eed6972d5cdaa3af1fadb3fa76fc59877d0a1293835327a76573380d",
|
||||
"sha256:c8f2f0e995d73baf0bd899a948d62adeb9ab908c8270c66a67ff09dfcf4872b7"
|
||||
],
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"h11": {
|
||||
"hashes": [
|
||||
"sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d",
|
||||
"sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.14.0"
|
||||
},
|
||||
"h2": {
|
||||
"hashes": [
|
||||
"sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d",
|
||||
"sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"
|
||||
],
|
||||
"version": "==4.1.0"
|
||||
},
|
||||
"hpack": {
|
||||
"hashes": [
|
||||
"sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c",
|
||||
"sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.1'",
|
||||
"version": "==4.0.0"
|
||||
},
|
||||
"httpcore": {
|
||||
"hashes": [
|
||||
"sha256:13b5e5cd1dca1a6636a6aaea212b19f4f85cd88c366a2b82304181b769aab3c9",
|
||||
"sha256:adc5398ee0a476567bf87467063ee63584a8bce86078bf748e48754f60202ced"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==0.18.0"
|
||||
},
|
||||
"httpx": {
|
||||
"extras": [
|
||||
"brotli",
|
||||
"http2"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:181ea7f8ba3a82578be86ef4171554dd45fec26a02556a744db029a0a27b7100",
|
||||
"sha256:47ecda285389cb32bb2691cc6e069e3ab0205956f681c5b2ad2325719751d875"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==0.25.0"
|
||||
},
|
||||
"hyperframe": {
|
||||
"hashes": [
|
||||
"sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15",
|
||||
"sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.1'",
|
||||
"version": "==6.0.1"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4",
|
||||
"sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==3.4"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
|
||||
"sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==23.2"
|
||||
},
|
||||
"pefile": {
|
||||
"hashes": [
|
||||
"sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc",
|
||||
"sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"
|
||||
],
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==2023.2.7"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:0462b1496505a3462d0f35dc1c4d7b54069747d65d00ef48e736acda2c8cbdff",
|
||||
"sha256:186f7e04248103482ea6354af6d5bcedb62941ee08f7f788a1c7707bc720c66f",
|
||||
"sha256:19e9adb3f22d4c416e7cd79b01375b17159d6990003633ff1d8377e21b7f1b21",
|
||||
"sha256:28444cb6ad49726127d6b340217f0627abc8732f1194fd5352dec5e6a0105635",
|
||||
"sha256:2872f2d7846cf39b3dbff64bc1104cc48c76145854256451d33c5faa55c04d1a",
|
||||
"sha256:2cc6b86ece42a11f16f55fe8903595eff2b25e0358dec635d0a701ac9586588f",
|
||||
"sha256:2d7e91b4379f7a76b31c2dda84ab9e20c6220488e50f7822e59dac36b0cd92b1",
|
||||
"sha256:2fa6dd2661838c66f1a5473f3b49ab610c98a128fc08afbe81b91a1f0bf8c51d",
|
||||
"sha256:32bec7423cdf25c9038fef614a853c9d25c07590e1a870ed471f47fb80b244db",
|
||||
"sha256:3855447d98cced8670aaa63683808df905e956f00348732448b5a6df67ee5849",
|
||||
"sha256:3a04359f308ebee571a3127fdb1bd01f88ba6f6fb6d087f8dd2e0d9bff43f2a7",
|
||||
"sha256:3a0d3e54ab1df9df51b914b2233cf779a5a10dfd1ce339d0421748232cea9876",
|
||||
"sha256:44e7e4587392953e5e251190a964675f61e4dae88d1e6edbe9f36d6243547ff3",
|
||||
"sha256:459307cacdd4138edee3875bbe22a2492519e060660eaf378ba3b405d1c66317",
|
||||
"sha256:4ce90f8a24e1c15465048959f1e94309dfef93af272633e8f37361b824532e91",
|
||||
"sha256:50bd5f1ebafe9362ad622072a1d2f5850ecfa44303531ff14353a4059113b12d",
|
||||
"sha256:522ff4ac3aaf839242c6f4e5b406634bfea002469656ae8358644fc6c4856a3b",
|
||||
"sha256:552912dbca585b74d75279a7570dd29fa43b6d93594abb494ebb31ac19ace6bd",
|
||||
"sha256:5d6c9049c6274c1bb565021367431ad04481ebb54872edecfcd6088d27edd6ed",
|
||||
"sha256:697a06bdcedd473b35e50a7e7506b1d8ceb832dc238a336bd6f4f5aa91a4b500",
|
||||
"sha256:71671503e3015da1b50bd18951e2f9daf5b6ffe36d16f1eb2c45711a301521a7",
|
||||
"sha256:723bd25051454cea9990203405fa6b74e043ea76d4968166dfd2569b0210886a",
|
||||
"sha256:764d2c0daf9c4d40ad12fbc0abd5da3af7f8aa11daf87e4fa1b834000f4b6b0a",
|
||||
"sha256:787bb0169d2385a798888e1122c980c6eff26bf941a8ea79747d35d8f9210ca0",
|
||||
"sha256:7f771e7219ff04b79e231d099c0a28ed83aa82af91fd5fa9fdb28f5b8d5addaf",
|
||||
"sha256:847e8d1017c741c735d3cd1883fa7b03ded4f825a6e5fcb9378fd813edee995f",
|
||||
"sha256:84efb46e8d881bb06b35d1d541aa87f574b58e87f781cbba8d200daa835b42e1",
|
||||
"sha256:898f1d306298ff40dc1b9ca24824f0488f6f039bc0e25cfb549d3195ffa17088",
|
||||
"sha256:8b451d6ead6e3500b6ce5c7916a43d8d8d25ad74b9102a629baccc0808c54971",
|
||||
"sha256:8f06be50669087250f319b706decf69ca71fdecd829091a37cc89398ca4dc17a",
|
||||
"sha256:92a23b0431941a33242b1f0ce6c88a952e09feeea9af4e8be48236a68ffe2205",
|
||||
"sha256:93139acd8109edcdeffd85e3af8ae7d88b258b3a1e13a038f542b79b6d255c54",
|
||||
"sha256:98533fd7fa764e5f85eebe56c8e4094db912ccbe6fbf3a58778d543cadd0db08",
|
||||
"sha256:9f665d1e6474af9f9da5e86c2a3a2d2d6204e04d5af9c06b9d42afa6ebde3f21",
|
||||
"sha256:b059ac2c4c7a97daafa7dc850b43b2d3667def858a4f112d1aa082e5c3d6cf7d",
|
||||
"sha256:b1be1c872b9b5fcc229adeadbeb51422a9633abd847c0ff87dc4ef9bb184ae08",
|
||||
"sha256:b7cf63d2c6928b51d35dfdbda6f2c1fddbe51a6bc4a9d4ee6ea0e11670dd981e",
|
||||
"sha256:bc2e3069569ea9dbe88d6b8ea38f439a6aad8f6e7a6283a38edf61ddefb3a9bf",
|
||||
"sha256:bcf1207e2f2385a576832af02702de104be71301c2696d0012b1b93fe34aaa5b",
|
||||
"sha256:ca26ba5767888c84bf5a0c1a32f069e8204ce8c21d00a49c90dabeba00ce0145",
|
||||
"sha256:cbe68deb8580462ca0d9eb56a81912f59eb4542e1ef8f987405e35a0179f4ea2",
|
||||
"sha256:d6caf3cd38449ec3cd8a68b375e0c6fe4b6fd04edb6c9766b55ef84a6e8ddf2d",
|
||||
"sha256:d72967b06be9300fed5cfbc8b5bafceec48bf7cdc7dab66b1d2549035287191d",
|
||||
"sha256:d889b53ae2f030f756e61a7bff13684dcd77e9af8b10c6048fb2c559d6ed6eaf",
|
||||
"sha256:de596695a75496deb3b499c8c4f8e60376e0516e1a774e7bc046f0f48cd620ad",
|
||||
"sha256:e6a90167bcca1216606223a05e2cf991bb25b14695c518bc65639463d7db722d",
|
||||
"sha256:ed2d9c0704f2dc4fa980b99d565c0c9a543fe5101c25b3d60488b8ba80f0cce1",
|
||||
"sha256:ee7810cf7c83fa227ba9125de6084e5e8b08c59038a7b2c9045ef4dde61663b4",
|
||||
"sha256:f0b4b06da13275bc02adfeb82643c4a6385bd08d26f03068c2796f60d125f6f2",
|
||||
"sha256:f11c9102c56ffb9ca87134bd025a43d2aba3f1155f508eff88f694b33a9c6d19",
|
||||
"sha256:f5bb289bb835f9fe1a1e9300d011eef4d69661bb9b34d5e196e5e82c4cb09b37",
|
||||
"sha256:f6d3d4c905e26354e8f9d82548475c46d8e0889538cb0657aa9c6f0872a37aa4",
|
||||
"sha256:fcb59711009b0168d6ee0bd8fb5eb259c4ab1717b2f538bbf36bacf207ef7a68",
|
||||
"sha256:fd2a5403a75b54661182b75ec6132437a181209b901446ee5724b589af8edef1"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==10.0.1"
|
||||
},
|
||||
"psutil": {
|
||||
"hashes": [
|
||||
"sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d",
|
||||
"sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217",
|
||||
"sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4",
|
||||
"sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c",
|
||||
"sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f",
|
||||
"sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da",
|
||||
"sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4",
|
||||
"sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42",
|
||||
"sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5",
|
||||
"sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4",
|
||||
"sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9",
|
||||
"sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f",
|
||||
"sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30",
|
||||
"sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==5.9.5"
|
||||
},
|
||||
"pyinstaller": {
|
||||
"hashes": [
|
||||
"sha256:0ad7cc3776ca17d0bededcc352cba2b1c89eb4817bfabaf05972b9da8c424935",
|
||||
"sha256:16a473065291dd7879bf596fa20e65bd9d1e8aafc2cef1bffa3e42e707e2e68e",
|
||||
"sha256:438a9e0d72a57d5bba4f112d256e39ea4033c76c65414c0693d8311faa14b090",
|
||||
"sha256:4a75bde5cda259bb31f2294960d75b9d5c148001b2b0bd20a91f9c2116675a6c",
|
||||
"sha256:52e5b3a2371d7231de17515c7c78d8d4a39d70c8c095e71d55b3b83434a193a8",
|
||||
"sha256:5314f6f08d2bcbc031778618ba97d9098d106119c2e616b3b081171fe42f5415",
|
||||
"sha256:68769f5e6722474bb1038e35560444659db8b951388bfe0c669bb52a640cd0eb",
|
||||
"sha256:aa922d1d73881d0820a341d2c406a571cc94630bdcdc275427c844a12e6e376e",
|
||||
"sha256:cccdad6cfe7a5db7d7eb8df2e5678f8375268739d5933214e180da300aa54e37",
|
||||
"sha256:d702cff041f30e7a53500b630e07b081e5328d4655023319253d73935e75ade2",
|
||||
"sha256:d84b06fb9002109bfc542e76860b81459a8585af0bbdabcfc5dcf272ef230de7",
|
||||
"sha256:fb6af82989dac7c58bd25ed9ba3323bc443f8c1f03804f69c9f5e363bf4a021c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version < '3.13' and python_version >= '3.8'",
|
||||
"version": "==6.0.0"
|
||||
},
|
||||
"pyinstaller-hooks-contrib": {
|
||||
"hashes": [
|
||||
"sha256:76084b5988e3957a9df169d2a935d65500136967e710ddebf57263f1a909cd80",
|
||||
"sha256:f34f4c6807210025c8073ebe665f422a3aa2ac5f4c7ebf4c2a26cc77bebf63b5"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2023.9"
|
||||
},
|
||||
"pytesseract": {
|
||||
"hashes": [
|
||||
"sha256:8f22cc98f765bf13517ead0c70effedb46c153540d25783e04014f28b55a5fc6",
|
||||
"sha256:f1c3a8b0f07fd01a1085d451f5b8315be6eec1d5577a6796d46dc7a62bd4120f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.3.10"
|
||||
},
|
||||
"pywin32": {
|
||||
"hashes": [
|
||||
"sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d",
|
||||
"sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65",
|
||||
"sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e",
|
||||
"sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b",
|
||||
"sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4",
|
||||
"sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040",
|
||||
"sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a",
|
||||
"sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36",
|
||||
"sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8",
|
||||
"sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e",
|
||||
"sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802",
|
||||
"sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a",
|
||||
"sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407",
|
||||
"sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"
|
||||
],
|
||||
"version": "==306"
|
||||
},
|
||||
"pywin32-ctypes": {
|
||||
"hashes": [
|
||||
"sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60",
|
||||
"sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"
|
||||
],
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==0.2.2"
|
||||
},
|
||||
"pywinauto": {
|
||||
"hashes": [
|
||||
"sha256:931ce622d7f402b1892ab472987a1332e4c0681bf87e106f798390d16ca95e58",
|
||||
"sha256:de23f1e977cc51e7eddd95c8f365710343136433968d1e2ad377962d6bd6540a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.6.8"
|
||||
},
|
||||
"rapidfuzz": {
|
||||
"hashes": [
|
||||
"sha256:01013ee67fb15608c8c5961af3bc2b1f242cff94c19f53237c9b3f0edb8e0a2d",
|
||||
"sha256:01d64710060bc3241c08ac1f1a9012c7184f3f4c3d6e2eebb16c6093a03f6a67",
|
||||
"sha256:02afbe7ed12e9191082ed7bda43398baced1d9d805302b7b010d397de3ae973f",
|
||||
"sha256:0b9197656a6d71483959bf7d216e7fb7a6b80ca507433bcb3015fb92abc266f8",
|
||||
"sha256:0d8c6cb80b5d2edf88bf6a88ac6827a353c974405c2d7e3025ed9527a5dbe1a6",
|
||||
"sha256:0df66e07e42e2831fae84dea481f7803bec7cfa53c31d770e86ac47bb18dcd57",
|
||||
"sha256:124578029d926b2be32d60b748be95ee0de6cb2753eb49d6d1d6146269b428b9",
|
||||
"sha256:1276c7f50cd90a48b00084feb25256135c9ace6c599295dd5932949ec30c0e70",
|
||||
"sha256:1438e68fe8869fe6819a313140e98641b34bfc89234b82486d8fd02044a067e8",
|
||||
"sha256:1a733c10b1fcc47f837c23ab4a255cc4021a88939ff81baa64d6738231cba33d",
|
||||
"sha256:1bafbd3e2e9e0b5f740f66155cc7e1e23eee1e1f2c44eff12daf14f90af0e8ab",
|
||||
"sha256:1ebee7313719dfe652debb74bdd4024e8cf381a59adc6d065520ff927f3445f4",
|
||||
"sha256:233bf022938c38060a93863ec548e624d69a56d7384634d8bea435b915b88e52",
|
||||
"sha256:23b07685c21c93cdf6d68b49eccacfe975651b8d99ea8a02687400c60315e5bc",
|
||||
"sha256:2543fd8d0fb3b1ac065bf94ee54c0ea33343c62481d8e54b6117a88c92c9b721",
|
||||
"sha256:273c7c7f5b405f2f54d41e805883572d57e1f0a56861f93ca5a6733672088acb",
|
||||
"sha256:28d03cd33817f6e0bea9b618b460f85ff9c9c3fedc6c19cfa0992f719a0d1801",
|
||||
"sha256:2e49151572b842d290dcee2cc6f9ce7a7b40b77cc20d0f6d6b54e7afb7bafa5c",
|
||||
"sha256:3456f4df5b8800315fd161045c996479016c112228e4da370d09ed80c24853e5",
|
||||
"sha256:37d5f0fbad6c092c89840eea2c4c845564d40849785de74c5e6ff48b47b0ecf6",
|
||||
"sha256:3af0384132e79fe6f6370d49347649382e04f689277525903bef84d30f3992fd",
|
||||
"sha256:3db79070888d0dcd4f6a20fd30b8184dd975d6b0f7818acff5d7e07eba19b71f",
|
||||
"sha256:437508ec1ea6e71a77126715ac6208cb9c3e74272536ebfa79be9dd008cfb85f",
|
||||
"sha256:46efc5e4675e2bd5118427513f86eaf3689e1482ebd309ad4532bcefae78179d",
|
||||
"sha256:4fd94acab871afbc845400814134a83512a711e824dc2c9a9776d6123464a221",
|
||||
"sha256:50ad7bac98a0f00492687eddda73d2c0bdf71c78b52fddaa5901634ae323d3ce",
|
||||
"sha256:51d47d52c890cbdb2d8b2085d747e557f15efd9c990cb6ae624c8f6948c4aa3a",
|
||||
"sha256:52c6b7a178f0e800488fa1aede17b00f6397cab0b79d48531504b0d89e45315f",
|
||||
"sha256:53bbef345644eac1c2d7cc21ade4fe9554fa289f60eb2c576f7fdc454dbc0641",
|
||||
"sha256:55efb3231bb954f3597313ebdf104289b8d139d5429ad517051855f84e12b94e",
|
||||
"sha256:59f851c7a54a9652b9598553547e0940244bfce7c9b672bac728efa0b9028d03",
|
||||
"sha256:5b9a7ab061c1b75b274fc2ebd1d29cfa2e510c36e2f4cd9518a6d56d589003c8",
|
||||
"sha256:5fe3ef7daecd79f852936528e37528fd88818bc000991e0fea23b9ac5b79e875",
|
||||
"sha256:61f16bb0f3026853500e7968261831a2e1a35d56947752bb6cf6953afd70b9de",
|
||||
"sha256:6286510910fcd649471a7f5b77fcc971e673729e7c84216dbf321bead580d5a1",
|
||||
"sha256:63933792146f3d333680d415cecc237e6275b42ad948d0a798f9a81325517666",
|
||||
"sha256:66ff93b81b382269dc7c2d46c839ce72e2d2331ad46a06321770bc94016fe236",
|
||||
"sha256:698488002eb7be2f737e48679ed0cd310b76291f26d8ec792db8345d13eb6573",
|
||||
"sha256:6b8258846e56b03230fa733d29bb4f9fb1f4790ac97d1ebe9faa3ff9d2850999",
|
||||
"sha256:6d38596c804a9f2bd49360c15e1f4afbf016f181fe37fc4f1a4ddd247d3e91e5",
|
||||
"sha256:6f5c8b901b6d3be63591c68e2612f76ad85af27193d0a88d4d87bb047aeafcb3",
|
||||
"sha256:712dd91d429afaddbf7e86662155f2ad9bc8135fca5803a01035a3c1d76c5977",
|
||||
"sha256:734046d557550589edb83d5ad1468a1341d1092f1c64f26fd0b1fc50f9efdce1",
|
||||
"sha256:74b9a1c1fc139d325fb0b89ccc85527d27096a76f6ed690ee3378143cc38e91d",
|
||||
"sha256:75d1365387ec8ef2128fd7e2f7436aa1a04a1953bc6d7068835bb769cd07c146",
|
||||
"sha256:76f4162ce5fe08609455d318936ed4aa709f40784be61fb4e200a378137b0230",
|
||||
"sha256:7f497f850d46c5e08f3340343842a28ede5d3997e5d1cadbd265793cf47417e5",
|
||||
"sha256:805dc2aa3ac295dcbf2df8c1e420e8a73b1f632d6820a5a1c8506d22c11e0f27",
|
||||
"sha256:83387fb81c4c0234b199110655779762dd5982cdf9de4f7c321110713193133e",
|
||||
"sha256:87409e12f9a82aa33a5b845c49dd8d5d4264f2f171f0a69ddc638e100fcc50de",
|
||||
"sha256:8756461e7ee79723b8f762fc6db226e65eb453bf9fa64b14fc0274d4aaaf9e21",
|
||||
"sha256:8b38d7677b2f20b137bb7aaf0dcd3d8ac2a2cde65f09f5621bf3f57d9a1e5d6e",
|
||||
"sha256:8eb33895353bfcc33ccf4b4bae837c0afb4eaf20a0361aa6f0800cef12505e91",
|
||||
"sha256:8f5d2adc48c181486125d42230e80479a1e0568942e883d1ebdeb76cd3f83470",
|
||||
"sha256:929e6b71e5b36caee2ee11c209e75a0fcbd716a1b76ae6162b89ee9b591b63b1",
|
||||
"sha256:93ceb62ade1a0e62696487274002157a58bb751fc82cd25016fc5523ba558ca5",
|
||||
"sha256:950d1dfd2927cd45c9bb2927933926718f0a17792841e651d42f4d1cb04a5c1d",
|
||||
"sha256:9814905414696080d8448d6e6df788a0148954ab34d7cd8d75bcb85ba30e0b25",
|
||||
"sha256:9e1142c8d35fa6f3af8150d02ff8edcbea3723c851d889e8b2172e0d1b99f3f7",
|
||||
"sha256:9f295842c282fe7fe93bfe7a20e78f33f43418f47fb601f2f0a05df8a8282b43",
|
||||
"sha256:a0750278693525b5ce58d3b313e432dfa5d90f00d06ae54fa8cde87f2a397eb0",
|
||||
"sha256:a716efcfc92659d8695291f07da4fa60f42a131dc4ceab583931452dd5662e92",
|
||||
"sha256:a7215f7c5de912b364d5cf7c4c66915ccf4acf71aafbb8da62ad346569196e15",
|
||||
"sha256:a74112e2126b428c77db5e96f7ce34e91e750552147305b2d361122cbede2955",
|
||||
"sha256:a7d6a9f04ea1277add8943d4e144e59215009f54f2668124ff26dee18a875343",
|
||||
"sha256:a80f9aa4245a49e0677896d1b51b2b3bc36472aff7cec31c4a96f789135f03fe",
|
||||
"sha256:ab981f9091ae8bd32bca9289fa1019b4ec656543489e7e13e64882d57d989282",
|
||||
"sha256:b05c7d4b4ddb617e977d648689013e50e5688140ee03538d3760a3a11d4fa8a2",
|
||||
"sha256:b38c7021f6114cfacba5717192fb3e1e50053261d49a774e645021a2f77e20a3",
|
||||
"sha256:b6fe2aff0d9b35191701714e05afe08f79eaea376a3a6ca802b72d9e5b48b545",
|
||||
"sha256:b81b8bc29114ca861fed23da548a837832b85495b0c1b2600e6060e3cf4d50aa",
|
||||
"sha256:bbb05b1203f683b341f44ebe8fe38afed6e56f606094f9840d6406e4a7bf0eab",
|
||||
"sha256:bd10d68baabb63a3bb36b683f98fc481fcc62230e493e4b31e316bd5b299ef68",
|
||||
"sha256:bd50bc90167601963e2a90b820fb862d239ecb096a991bf3ce33ffaa1d6eedee",
|
||||
"sha256:bf58ba21df06fc8aeef3056fd137eca0a593c2f5c82923a4524d251dc5f3df5d",
|
||||
"sha256:bfe14711b9a7b744e242a482c6cabb696517a1a9946fc1e88d353cd3eb384788",
|
||||
"sha256:c006aa481d1b91c2600920ce16e42d208a4b6f318d393aef4dd2172d568f2641",
|
||||
"sha256:c0150d521199277b5ad8bd3b060a5f3c1dbdf11df0533b4d79f458ef11d07e8c",
|
||||
"sha256:c2a564f748497b6a5e08a1dc0ac06655f65377cf072c4f0e2c73818acc655d36",
|
||||
"sha256:c56073ba1d1b25585359ad9769163cb2f3183e7a03c03b914a0667fcbd95dc5c",
|
||||
"sha256:c67f5ced39aff6277dd772b239ef8aa8fc810200a3b42f69ddbb085ea0e18232",
|
||||
"sha256:c7f4f6dac25c120de8845a65a97090658c8a976827ac22b6b86e2a16a60bb820",
|
||||
"sha256:c92d847c997c384670e3b4cf6727cb73a4d7a7ba6457310e2083cf06d56013c4",
|
||||
"sha256:cc3efc06db79e818f4a6783a4e001b3c8b2c61bd05c0d5c4d333adaf64ed1b34",
|
||||
"sha256:cfdc74afd93ac71270b5be5c25cb864b733b9ae32b07495705a6ac294ac4c390",
|
||||
"sha256:d0bda173b0ec1fa546f123088c0d42c9096304771b4c0555d4e08a66a246b3f6",
|
||||
"sha256:d15c364c5aa8f032dadf5b82fa02b7a4bd9688a961a27961cd5b985203f58037",
|
||||
"sha256:d188e8fb5a9709931c6a48cc62c4ac9b9d163969333711e426d9dbd134c1489b",
|
||||
"sha256:d1d81d380ceabc8297880525c9d8b9e93fead38d3d2254e558c36c18aaf2553f",
|
||||
"sha256:d3198f70b97127e52a4f96bb2f7de447f89baa338ff398eb126930c8e3137ad1",
|
||||
"sha256:d904ac97f2e370f91e8170802669c8ad68641bf84d742968416b53c5960410c6",
|
||||
"sha256:da2764604a31fd1e3f1cacf226b43a871cc9f28844a3196c2a6b1ba52ae12922",
|
||||
"sha256:dd54dd0355225dc3c1d55e233d510adcccee9bb25d656b4cf1136114b92e7bf3",
|
||||
"sha256:e14799297f194a4480f373e45142ef16d5dc68a42084c0e2018e0bdba56a8fef",
|
||||
"sha256:e182ea5c809e7ed36ebfbcef4bb1808e213d27b33c036007a33bcbb7ba498356",
|
||||
"sha256:e77873126eb07e7461f0b675263e6c5d42c8a952e88e4a44eeff96f237b2b024",
|
||||
"sha256:ed0d5761b44d9dd87278d5c32903bb55632346e4d84ea67ba2e4a84afc3b7d45",
|
||||
"sha256:ed3da08830c08c8bcd49414cc06b704a760d3067804775facc0df725b52085a4",
|
||||
"sha256:ef30b5f2720f0acbcfba0e0661a4cc118621c47cf69b5fe92531dfed1e369e1c",
|
||||
"sha256:f0075ff8990437923da42202b60cf04b5c122ee2856f0cf2344fb890cadecf57",
|
||||
"sha256:f1e91460baa42f5408f3c062913456a24b2fc1a181959b58a9c06b5eef700ca6",
|
||||
"sha256:f3effbe9c677658b3149da0d2778a740a6b7d8190c1407fd0c0770a4e223cfe0",
|
||||
"sha256:f5921780e7995e9ac3cea41fa57b623159d7295788618d3f2946d61328c25c25",
|
||||
"sha256:f71454249ddd29d8ba5415ed7307e7b7493fc7e9018f1ff496127b8b9a8df94b",
|
||||
"sha256:f723197f2dbce508a7030dcf6d3fc940117aa54fc876021bf6f6feeaf3825ba1",
|
||||
"sha256:f7f5ea97886d2ec7b2b9a8172812a76e1d243f2ce705c2f24baf46f9ef5d3951",
|
||||
"sha256:f813fb663d90038c1171d30ea1b6b275e09fced32f1d12b972c6045d9d4233f2",
|
||||
"sha256:fc4b1b69a64d337c40fa07a721dae1b1550d90f17973fb348055f6440d597e26"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.4.0"
|
||||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87",
|
||||
"sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==68.2.2"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
||||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.16.0"
|
||||
},
|
||||
"sniffio": {
|
||||
"hashes": [
|
||||
"sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101",
|
||||
"sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.3.0"
|
||||
},
|
||||
"tqdm": {
|
||||
"hashes": [
|
||||
"sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386",
|
||||
"sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.66.1"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
"0": "Wonders of the World",
|
||||
"1": "Mortal Travails: Series I",
|
||||
"2": "The Art of Adventure",
|
||||
"3": "The Hero's Journey",
|
||||
"4": "Mondstadt: The City of Wind and Song",
|
||||
"5": "Liyue: The Harbor of Stone and Contracts",
|
||||
"6": "Elemental Specialist: Series I",
|
||||
"7": "Marksmanship",
|
||||
"8": "Challenger: Series I",
|
||||
"9": "Domains and Spiral Abyss: Series I",
|
||||
"10": "Olah!: Series I",
|
||||
"11": "Snezhnaya Does Not Believe in Tears: Series I",
|
||||
"12": "Stone Harbor's Nostalgia: Series I",
|
||||
"13": "Meetings in Outrealm: Series I",
|
||||
"14": "Challenger: Series II",
|
||||
"15": "Challenger: Series III",
|
||||
"16": "Visitors on the Icy Mountain",
|
||||
"17": "Memories of the Heart",
|
||||
"18": "A Realm Beyond: Series I",
|
||||
"19": "A Realm Beyond: Series II",
|
||||
"20": "Challenger: Series IV",
|
||||
"21": "Meetings in Outrealm: Series II",
|
||||
"22": "Mortal Travails: Series II",
|
||||
"23": "A Realm Beyond: Series III",
|
||||
"24": "Inazuma: The Islands of Thunder and Eternity - Series I",
|
||||
"25": "Teyvat Fishing Guide: Series I",
|
||||
"26": "Inazuma: The Islands of Thunder and Eternity - Series II",
|
||||
"27": "The Chronicles of the Sea of Fog",
|
||||
"28": "The Light of Day",
|
||||
"29": "Challenger: Series V",
|
||||
"30": "Chasmlighter",
|
||||
"31": "Sumeru: The Rainforest of Lore",
|
||||
"32": "Mortal Travails: Series III",
|
||||
"33": "Meetings in Outrealm: Series III",
|
||||
"34": "Challenger: Series VI",
|
||||
"35": "Sumeru: The Gilded Desert - Series I",
|
||||
"36": "Elemental Specialist: Series II",
|
||||
"37": "Genius Invokation TCG",
|
||||
"38": "Sumeru: The Gilded Desert - Series II",
|
||||
"39": "Challenger: Series VII",
|
||||
"40": "Challenger: Series VIII",
|
||||
"41": "Blessed Hamada",
|
||||
"42": "Fontaine: Dance of the Dew-White Springs (I)",
|
||||
"43": "Mortal Travails: Series IV",
|
||||
"44": "Meetings in Outrealm: Series IV",
|
||||
"45": "Fontaine: Dance of the Dew-White Springs (II)"
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pyinstaller main.spec
|
||||
pyinstaller submit_to_gc.spec
|
|
@ -0,0 +1,380 @@
|
|||
import ctypes
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
from time import sleep
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
from PIL import ImageOps, Image
|
||||
from rapidfuzz import process, fuzz
|
||||
from rapidfuzz.utils import default_process
|
||||
from pywinauto import Application
|
||||
from pywinauto.controls.hwndwrapper import DialogWrapper
|
||||
from pywinauto.win32structures import RECT
|
||||
|
||||
from utils import find_process, scale_coords_to_resolution, scale_box_to_resolution, bold_color_mask, \
|
||||
generate_achievement_boxes, scan_image, get_asset_path
|
||||
|
||||
button_coords = {
|
||||
"main_achievement_button": (885, 542),
|
||||
"main_achievement_category": (249, 384),
|
||||
"achievement_category": (500, 290),
|
||||
"achievement_scroll": (969, 448),
|
||||
"category_scroll": (53, 448),
|
||||
}
|
||||
box_coords = {
|
||||
"achievement_category": RECT(152, 240, 658, 106),
|
||||
# "achievement": RECT(1167, 208, 878, 138),
|
||||
# "achievement_categories": RECT(1167, 393, 878, 138),
|
||||
# "achievement_status": RECT(2208, 195, 220, 161),
|
||||
}
|
||||
|
||||
|
||||
class AchievementScanner(object):
|
||||
debug_mode: bool = True
|
||||
debug_disable_postprocessing: bool = False
|
||||
window_rect: RECT = None
|
||||
|
||||
buttons: Dict[str, tuple] = {} # both are scaled for user's resolution
|
||||
boxes: Dict[str, RECT] = {}
|
||||
|
||||
achievements: Dict[str, bool] = {} # title - completed
|
||||
categories: List[str] = []
|
||||
database: List[str] = []
|
||||
|
||||
# loop
|
||||
achievement_id: int = 0
|
||||
category_id: int = 0
|
||||
|
||||
def scale_for_resolution(self):
|
||||
end_achievement = RECT(1167, 1148, 881, 140)
|
||||
end_achievement_status = RECT(2219, 1148, 220, 140)
|
||||
end_achievement_adjust = 167
|
||||
box_coords.update(generate_achievement_boxes(end_achievement, end_achievement_status, end_achievement_adjust,
|
||||
key="end_achievement", count=5))
|
||||
|
||||
end_category = RECT(173, 1213, 697, 109)
|
||||
end_category_adjust = 138
|
||||
box_coords.update(generate_achievement_boxes(end_category, None, end_category_adjust,
|
||||
key="end_category", count=7))
|
||||
|
||||
start_achievement_category = RECT(1167, 400, 900, 126)
|
||||
start_achievement_category_status = RECT(2224, 400, 192, 126)
|
||||
start_achievement_category_adjust = 167
|
||||
box_coords.update(
|
||||
generate_achievement_boxes(start_achievement_category, start_achievement_category_status,
|
||||
start_achievement_category_adjust,
|
||||
key="start_achievement_category", count=5, inversed=True))
|
||||
|
||||
start_achievement = RECT(1167, 176, 878, 138)
|
||||
start_achievement_status = RECT(2208, 176, 220, 138)
|
||||
start_achievement_adjust = 167
|
||||
box_coords.update(
|
||||
generate_achievement_boxes(start_achievement, start_achievement_status, start_achievement_adjust,
|
||||
key="start_achievement", count=5, inversed=True))
|
||||
|
||||
self.window_rect = self.window.element_info.rectangle
|
||||
resolution = (self.window_rect.width(), self.window_rect.height())
|
||||
self.buttons = {k: scale_coords_to_resolution(v, resolution) for k, v in button_coords.items()}
|
||||
self.boxes = {k: scale_box_to_resolution(v, self.window_rect) for k, v in box_coords.items()}
|
||||
self.logger.debug('ready')
|
||||
|
||||
def __init__(self, window: DialogWrapper):
|
||||
self.window = window
|
||||
self.logger = logging.getLogger("AchievementScanner")
|
||||
self.scale_for_resolution()
|
||||
|
||||
def scroll_mouse(self, steps: int, coords: tuple):
|
||||
self.logger.debug(f"Scrolling {steps} times at {coords}")
|
||||
max_scroll = steps
|
||||
scrolled = 0
|
||||
while scrolled < max_scroll:
|
||||
self.window.wheel_mouse_input(coords=coords, wheel_dist=-100)
|
||||
scrolled += 1
|
||||
sleep(0.02)
|
||||
self.logger.debug(f"{scrolled} / {max_scroll}")
|
||||
sleep(0.5)
|
||||
|
||||
def adjust_scroll_steps(self, category: bool = False):
|
||||
steps = 35
|
||||
if self.achievement_id % 15 == 0:
|
||||
steps -= 1
|
||||
"""
|
||||
if self.achievement_id % 14 == 0 or self.achievement_id % 41 == 0:
|
||||
steps -= 1
|
||||
if self.achievement_id % 42 == 0:
|
||||
steps += 1
|
||||
"""
|
||||
|
||||
if category:
|
||||
steps = 6
|
||||
if self.category_id % 4 == 0:
|
||||
steps -= 1
|
||||
if self.category_id % 33 == 0:
|
||||
steps -= 1
|
||||
|
||||
return steps
|
||||
|
||||
@staticmethod
|
||||
def improve_achievement_text(image: Image.Image) -> Image.Image:
|
||||
improved = ImageOps.expand(image, border=20, fill='#f0e9dc')
|
||||
improved = bold_color_mask(improved)
|
||||
improved = ImageOps.grayscale(improved)
|
||||
return improved
|
||||
|
||||
@staticmethod
|
||||
def improve_achievement_status(image: Image.Image) -> Image.Image:
|
||||
improved = bold_color_mask(image, target_color=(187, 167, 145), threshold=50)
|
||||
improved = ImageOps.grayscale(improved)
|
||||
return improved
|
||||
|
||||
@staticmethod
|
||||
def improve_achievement_category(image: Image.Image) -> Image.Image:
|
||||
improved = bold_color_mask(image, target_color=(73, 83, 102), threshold=100)
|
||||
improved = ImageOps.grayscale(improved)
|
||||
return improved
|
||||
|
||||
def left_click(self, coords: tuple):
|
||||
self.logger.debug(f"Clicking at {coords}")
|
||||
max_width, max_height = self.window_rect.width(), self.window_rect.height()
|
||||
if coords[0] > max_width or coords[1] > max_height:
|
||||
self.logger.warning(f"Coords {coords} are out of window bounds ({max_width}, {max_height})")
|
||||
|
||||
self.window.click_input(button='left', coords=coords)
|
||||
|
||||
def go_to_achievements(self):
|
||||
for _ in range(0, 4):
|
||||
self.window.type_keys('{ESC}')
|
||||
sleep(1)
|
||||
self.left_click(coords=self.buttons['main_achievement_button'])
|
||||
sleep(2)
|
||||
self.left_click(coords=self.buttons['main_achievement_category'])
|
||||
sleep(2)
|
||||
|
||||
def load_database(self):
|
||||
if len(self.database) == 0:
|
||||
assets = get_asset_path()
|
||||
|
||||
with open(assets['gc_achievements.json'], "r", encoding='utf-8') as file:
|
||||
gc_achievements = json.load(file)
|
||||
gc_achievements = [v['name'] for k, v in gc_achievements.items()]
|
||||
with open(assets['gc_categories.json'], "r", encoding='utf-8') as file:
|
||||
gc_categories = json.load(file)
|
||||
gc_categories = [v for k, v in gc_categories.items()]
|
||||
self.database = gc_achievements + gc_categories
|
||||
self.database.sort() # Leads to faster results down the line
|
||||
return
|
||||
|
||||
def fix_title_by_database(self, title: str):
|
||||
self.load_database()
|
||||
result, confidence, choices_type = process.extractOne(title, self.database, processor=default_process)
|
||||
self.logger.info(f"fix_title_by_database: {title} -> {result} ({confidence} / {choices_type})")
|
||||
if confidence >= 90.0:
|
||||
return result
|
||||
else:
|
||||
return title
|
||||
|
||||
def capture_image(self, box: RECT, improve_func: callable = None, debug_name: str = None):
|
||||
image = self.window.capture_as_image(rect=box)
|
||||
if improve_func and not self.debug_disable_postprocessing:
|
||||
image = improve_func(image)
|
||||
image_bytes = io.BytesIO()
|
||||
image.save(image_bytes, format='PNG')
|
||||
if self.debug_mode:
|
||||
image_path = f'results\\debug_images\\{debug_name}.png'
|
||||
image.save(image_path)
|
||||
|
||||
return image_bytes
|
||||
|
||||
def get_center_of_rect(self, box: RECT) -> Tuple[int, int]:
|
||||
x, y = int(box.left), int(box.top)
|
||||
x += int(box.width() / 2)
|
||||
y += int(box.height() / 2)
|
||||
# it needs to be within window coords for some reason, when capturing is not
|
||||
if self.window_rect.left != 0:
|
||||
x -= self.window_rect.left
|
||||
if self.window_rect.top != 0:
|
||||
y -= self.window_rect.top
|
||||
|
||||
return x, y
|
||||
|
||||
def scan_achievement(self, achievement_name_rect: RECT, status_rect: RECT):
|
||||
# Capture
|
||||
self.logger.info(f"Capturing achievement {self.achievement_id}")
|
||||
self.left_click(coords=self.get_center_of_rect(achievement_name_rect))
|
||||
title_image_bytes = self.capture_image(achievement_name_rect, improve_func=self.improve_achievement_text,
|
||||
debug_name=f"{self.achievement_id}")
|
||||
status_image_bytes = self.capture_image(status_rect, improve_func=self.improve_achievement_status,
|
||||
debug_name=f"{self.achievement_id}_status")
|
||||
|
||||
# Scan
|
||||
self.logger.info(f"Sending {self.achievement_id} over for scanning to OCR server")
|
||||
self.left_click(coords=self.get_center_of_rect(status_rect))
|
||||
scanned_title: str = scan_image(title_image_bytes.getvalue())
|
||||
scanned_status: str = scan_image(status_image_bytes.getvalue())
|
||||
|
||||
# Fix small fuckups
|
||||
scanned_title = scanned_title.strip()
|
||||
if scanned_title == '':
|
||||
return '', False
|
||||
if scanned_title == "":
|
||||
scanned_title = "\n" # so .splitlines doesn't crash the thing
|
||||
scanned_title = scanned_title.splitlines()[0].replace(
|
||||
"”", "\"").replace("“", "\"").replace('Deja', 'Déjà')
|
||||
scanned_title = self.fix_title_by_database(scanned_title)
|
||||
|
||||
# OCR Result
|
||||
self.logger.info(f"Found achievement {self.achievement_id}: {scanned_title}")
|
||||
self.logger.info(f"Status: {scanned_status}")
|
||||
return scanned_title, fuzz.partial_ratio("Completed", scanned_status, processor=default_process) >= 90.0
|
||||
|
||||
def scan_category(self, category_name_rect, skip: bool = False):
|
||||
end_of_list_mode = False # debug switch
|
||||
if end_of_list_mode:
|
||||
for _ in range(int(285 / 5)):
|
||||
self.scroll_mouse(35, self.buttons['achievement_scroll'])
|
||||
|
||||
category_image_bytes = self.capture_image(category_name_rect, improve_func=self.improve_achievement_category,
|
||||
debug_name=f"category_{self.category_id}")
|
||||
scanned_category: str = scan_image(category_image_bytes.getvalue()).strip().replace('and\nEternity',
|
||||
'and Eternity')
|
||||
scanned_category = self.fix_title_by_database(scanned_category)
|
||||
self.logger.info(f"Found category {self.category_id}: {scanned_category}")
|
||||
if scanned_category in self.categories or skip:
|
||||
return scanned_category
|
||||
self.categories.append(scanned_category)
|
||||
|
||||
last_achievement = None
|
||||
skip_scroll = True
|
||||
scanned = []
|
||||
while not end_of_list_mode:
|
||||
if not skip_scroll:
|
||||
self.logger.info(f"Scrolling...")
|
||||
self.scroll_mouse(self.adjust_scroll_steps(), self.buttons['achievement_scroll'])
|
||||
sleep(0.5)
|
||||
|
||||
for i in range(0, 5): # scan start-of-page items
|
||||
self.achievement_id += 1
|
||||
skip_scroll = False
|
||||
|
||||
if self.category_id <= 2:
|
||||
self.logger.info('Selected normal achievement boxes')
|
||||
achievement_name_rect = self.boxes[f"start_achievement_{i}"]
|
||||
status_rect = self.boxes[f"start_achievement_{i}_status"]
|
||||
else:
|
||||
self.logger.info('Selected namecard achievement boxes')
|
||||
achievement_name_rect = self.boxes[f"start_achievement_category_{i}"]
|
||||
status_rect = self.boxes[f"start_achievement_category_{i}_status"]
|
||||
|
||||
title, completed = self.scan_achievement(achievement_name_rect, status_rect)
|
||||
|
||||
# In-case we are stuck (end-of-page)
|
||||
if last_achievement == title or title in scanned:
|
||||
end_of_list_mode = True
|
||||
break
|
||||
else:
|
||||
last_achievement = title
|
||||
scanned.append(title)
|
||||
|
||||
if completed:
|
||||
self.achievements[title] = completed
|
||||
|
||||
for i in range(0, 5): # scan end-of-page items
|
||||
self.achievement_id += 1
|
||||
achievement_name_rect = self.boxes[f"end_achievement_{i}"]
|
||||
status_rect = self.boxes[f"end_achievement_{i}_status"]
|
||||
|
||||
title, completed = self.scan_achievement(achievement_name_rect, status_rect)
|
||||
if completed:
|
||||
self.achievements[title] = completed
|
||||
|
||||
if title in scanned: # leave faster whenever possible (caught on Challenger IV)
|
||||
break
|
||||
|
||||
return scanned_category
|
||||
|
||||
def scan_categories(self):
|
||||
skip_data = False # debug switch
|
||||
|
||||
last_category = None
|
||||
while True:
|
||||
self.category_id += 1
|
||||
if self.category_id != 1:
|
||||
self.logger.info(f"Scrolling to category {self.category_id}")
|
||||
self.left_click(coords=self.buttons['category_scroll'])
|
||||
sleep(0.5)
|
||||
self.scroll_mouse(self.adjust_scroll_steps(category=True), self.buttons['category_scroll'])
|
||||
sleep(0.5)
|
||||
self.logger.info(f"Clicking on category {self.category_id}")
|
||||
self.left_click(coords=self.buttons['achievement_category'])
|
||||
sleep(0.5)
|
||||
|
||||
self.logger.info(f"Scanning category {self.category_id}")
|
||||
category_name = self.scan_category(self.boxes['achievement_category'], skip=skip_data)
|
||||
if category_name == last_category:
|
||||
break
|
||||
last_category = category_name
|
||||
sleep(1)
|
||||
|
||||
for i in range(0, 7):
|
||||
self.category_id += 1
|
||||
self.logger.info(f"Scanning category (end-of-page) {self.category_id}")
|
||||
category_box: RECT = self.boxes[f"end_category_{i}"]
|
||||
self.left_click(coords=self.get_center_of_rect(category_box))
|
||||
sleep(0.5)
|
||||
category_name = self.scan_category(category_box, skip=skip_data)
|
||||
if category_name is None:
|
||||
break
|
||||
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def run(cls):
|
||||
app = Application().connect(process=find_process("GenshinImpact.exe").pid)
|
||||
main_window: DialogWrapper = app.windows()[0]
|
||||
main_window.set_focus()
|
||||
|
||||
inst = cls(main_window)
|
||||
inst.go_to_achievements()
|
||||
inst.scan_categories()
|
||||
with open('results\\achievements.json', 'w') as file:
|
||||
json.dump(inst.achievements, file, indent=4)
|
||||
return inst
|
||||
|
||||
|
||||
def is_admin():
|
||||
try:
|
||||
return ctypes.windll.shell32.IsUserAnAdmin()
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def check_if_tesseract_is_available():
|
||||
default_tesseract_path = "C:\\Program Files\\Tesseract-OCR\\tesseract.exe"
|
||||
import os
|
||||
if not os.path.exists(default_tesseract_path):
|
||||
print("Tesseract не установлен. Пожалуйста, установите его из интернета.")
|
||||
print("Tesseract is not installed. Please, install it from the web.")
|
||||
print("https://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-w64-setup-5.3.3.20231005.exe")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if is_admin():
|
||||
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
logging.getLogger('PIL').setLevel(logging.WARNING)
|
||||
# logging.getLogger('PIL.PngImagePlugin').setLevel(logging.WARNING)
|
||||
if not check_if_tesseract_is_available():
|
||||
input("Press \"Enter\" to exit ")
|
||||
sys.exit(1)
|
||||
# input("Press \"Enter\" to start ")
|
||||
try:
|
||||
AchievementScanner.run()
|
||||
except Exception as exc:
|
||||
logging.exception(exc)
|
||||
input("Press \"Enter\" to exit ")
|
||||
else:
|
||||
# Re-run the program with admin rights
|
||||
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
|
|
@ -0,0 +1,37 @@
|
|||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['main.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[('C:\\Users\\Levent\\Stuff\\Projects\\GI_AchievementParser\\client\\assets\\', './assets/')],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='GI_AchievementParser',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
|
@ -0,0 +1,56 @@
|
|||
import json
|
||||
import logging
|
||||
from time import sleep
|
||||
|
||||
import httpx
|
||||
from tqdm import tqdm
|
||||
|
||||
from utils import get_asset_path
|
||||
|
||||
|
||||
def submit_ids(ids_to_submit: list[int], cookies: str):
|
||||
cookies_as_dict = {cookie.split('=', 1)[0]: cookie.split('=', 1)[1] for cookie in cookies.split(';')}
|
||||
|
||||
with httpx.Client(http2=True, cookies=cookies_as_dict) as client:
|
||||
for id_to_submit in tqdm(ids_to_submit):
|
||||
# print(f'Загружаем achievementId {id_to_submit}')
|
||||
result = client.post('https://genshin-center.com/api/achievements/update',
|
||||
json={'achievementId': id_to_submit, 'done': True})
|
||||
result.raise_for_status()
|
||||
sleep(0.1)
|
||||
|
||||
|
||||
def main():
|
||||
cookies = input('Введите свои куки из genshin-center.com и нажмите "Enter": ')
|
||||
assets = get_asset_path()
|
||||
with open("results\\achievements.json", "r", encoding='utf-8') as file:
|
||||
completed_achievements = json.load(file)
|
||||
with open(assets['gc_achievements.json'], "r", encoding='utf-8') as file:
|
||||
gc_achievements = json.load(file)
|
||||
# gc_map = {v['name']: k for k, v in gc_achievements.items()}
|
||||
gc_map = {}
|
||||
for k, v in gc_achievements.items():
|
||||
ach_name = v['name']
|
||||
if gc_map.get(ach_name):
|
||||
gc_map[ach_name].append(int(k))
|
||||
else:
|
||||
gc_map[ach_name] = [int(k)]
|
||||
|
||||
ids_to_submit = []
|
||||
for k in completed_achievements.keys():
|
||||
gc_ids = gc_map.get(k)
|
||||
if not gc_ids:
|
||||
print(f'Пропускаем {k} (нет в базе)')
|
||||
continue
|
||||
if gc_achievements.get(str(gc_ids[0]), {'category_id': 123})['category_id'] == 0:
|
||||
ids_to_submit += gc_ids
|
||||
submit_ids(ids_to_submit, cookies)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.WARN, format='%(asctime)s %(levelname)s %(message)s')
|
||||
try:
|
||||
main()
|
||||
except Exception as exc:
|
||||
logging.exception(exc)
|
||||
input('Нажмите "Enter" для выхода.')
|
|
@ -0,0 +1,37 @@
|
|||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['submit_to_gc.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[('C:\\Users\\Levent\\Stuff\\Projects\\GI_AchievementParser\\client\\assets\\', './assets/')],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='Загрузчик в Genshin Center',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
|
@ -0,0 +1,104 @@
|
|||
import io
|
||||
import os.path
|
||||
import sys
|
||||
import threading
|
||||
import timeit
|
||||
|
||||
import psutil
|
||||
import pytesseract
|
||||
from PIL import Image, ImageChops
|
||||
from pywinauto.win32structures import RECT
|
||||
|
||||
|
||||
def find_process(name: str):
|
||||
matching = [x for x in psutil.process_iter() if x.name() == name]
|
||||
if len(matching) == 0:
|
||||
return None
|
||||
return matching[0]
|
||||
|
||||
|
||||
def scale_coords_to_resolution(coords: tuple, resolution: tuple):
|
||||
x, y = coords
|
||||
base_x, base_y = x / 2560, y / 1440
|
||||
return int(base_x * resolution[0]), int(base_y * resolution[1])
|
||||
|
||||
|
||||
def scale_box_to_resolution(box: RECT, window_rect: RECT):
|
||||
left, top, right, bottom = int(box.left), int(box.top), int(box.right), int(box.bottom)
|
||||
base_left, base_top, base_right, base_bottom = left / 2560, top / 1440, right / 2560, bottom / 1440
|
||||
low_res_left = int(base_left * window_rect.width()) + int(window_rect.left)
|
||||
low_res_top = int(base_top * window_rect.height()) + int(window_rect.top)
|
||||
low_res_right = int(base_right * window_rect.width()) + low_res_left
|
||||
low_res_bottom = int(base_bottom * window_rect.height()) + low_res_top
|
||||
return RECT(low_res_left, low_res_top, low_res_right, low_res_bottom)
|
||||
|
||||
|
||||
def bold_color_mask(image: Image.Image, target_color=(85, 85, 85), threshold=50):
|
||||
# Create a mask for the gradient effect
|
||||
start_mask = timeit.default_timer()
|
||||
|
||||
mask = Image.new("L", image.size)
|
||||
for x in range(image.width):
|
||||
for y in range(image.height):
|
||||
pixel = image.getpixel((x, y))
|
||||
color_difference = sum((a - b) ** 2 for a, b in zip(pixel, target_color))
|
||||
if color_difference <= threshold ** 2:
|
||||
mask.putpixel((x, y), 0)
|
||||
else:
|
||||
mask.putpixel((x, y), 255)
|
||||
|
||||
end_mask = timeit.default_timer()
|
||||
|
||||
# Apply the mask to the original image
|
||||
composited = ImageChops.composite(Image.new("RGB", image.size, (255, 255, 255)), image, mask)
|
||||
end_composite = timeit.default_timer()
|
||||
# print(f"Mask: {end_mask - start_mask}, Composite: {end_composite - end_mask}")
|
||||
return composited
|
||||
|
||||
|
||||
def generate_achievement_boxes(achievement: RECT, status: RECT | None, height_adjust: int,
|
||||
key: str = "end_achievement", count: int = 6, inversed: bool = False) -> dict:
|
||||
box_coords = {}
|
||||
|
||||
for adjust_count in range(0, count):
|
||||
generated_achievement_y = int(achievement.top) - (adjust_count * height_adjust)
|
||||
if inversed:
|
||||
generated_achievement_y = int(achievement.top) + (adjust_count * height_adjust)
|
||||
|
||||
box_coords[f"{key}_{adjust_count}"] = RECT(achievement.left, generated_achievement_y,
|
||||
achievement.right,
|
||||
achievement.bottom) # it's actually width and height
|
||||
if status is not None:
|
||||
generated_status_y = int(status.top) - (adjust_count * height_adjust)
|
||||
if inversed:
|
||||
generated_status_y = int(status.top) + (adjust_count * height_adjust)
|
||||
|
||||
box_coords[f"{key}_{adjust_count}_status"] = RECT(status.left, generated_status_y,
|
||||
status.right, status.bottom)
|
||||
|
||||
return box_coords
|
||||
|
||||
|
||||
def scan_image(image: str | bytes) -> str:
|
||||
data = image
|
||||
if isinstance(image, str):
|
||||
with open(image, 'rb') as file:
|
||||
data = file.read()
|
||||
|
||||
default_tesseract_path = "C:\\Program Files\\Tesseract-OCR\\tesseract.exe"
|
||||
if not os.path.exists(default_tesseract_path):
|
||||
raise Exception(f"Can't find tesseract at {default_tesseract_path}")
|
||||
else:
|
||||
pytesseract.pytesseract.tesseract_cmd = default_tesseract_path
|
||||
fake_file = io.BytesIO(data)
|
||||
return pytesseract.image_to_string(Image.open(fake_file), lang='eng')
|
||||
|
||||
|
||||
def get_asset_path():
|
||||
assets = {
|
||||
'gc_achievements.json': 'assets\\gc_achievements.json',
|
||||
'gc_categories.json': 'assets\\gc_categories.json',
|
||||
}
|
||||
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
|
||||
return {k: os.path.join(sys._MEIPASS, v) for k, v in assets.items()}
|
||||
return assets
|
Loading…
Reference in New Issue