py2ls 0.2.4.34__tar.gz → 0.2.4.35__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/PKG-INFO +6 -2
  2. py2ls-0.2.4.35/py2ls/data/RealESRGAN_x4plus.pth +0 -0
  3. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/ips.py +350 -33
  4. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/netfinder.py +30 -40
  5. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/ocr.py +2 -2
  6. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/pyproject.toml +6 -2
  7. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/README.md +0 -0
  8. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.DS_Store +0 -0
  9. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/.DS_Store +0 -0
  10. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/COMMIT_EDITMSG +0 -0
  11. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/FETCH_HEAD +0 -0
  12. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/HEAD +0 -0
  13. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/config +0 -0
  14. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/description +0 -0
  15. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/applypatch-msg.sample +0 -0
  16. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/commit-msg.sample +0 -0
  17. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/fsmonitor-watchman.sample +0 -0
  18. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/post-update.sample +0 -0
  19. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/pre-applypatch.sample +0 -0
  20. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/pre-commit.sample +0 -0
  21. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/pre-merge-commit.sample +0 -0
  22. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/pre-push.sample +0 -0
  23. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/pre-rebase.sample +0 -0
  24. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/pre-receive.sample +0 -0
  25. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/prepare-commit-msg.sample +0 -0
  26. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/push-to-checkout.sample +0 -0
  27. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/hooks/update.sample +0 -0
  28. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/index +0 -0
  29. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/info/exclude +0 -0
  30. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/logs/HEAD +0 -0
  31. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/logs/refs/heads/main +0 -0
  32. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/logs/refs/remotes/origin/HEAD +0 -0
  33. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/logs/refs/remotes/origin/main +0 -0
  34. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/.DS_Store +0 -0
  35. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/01/d5bd8065e6860c0bd23ff9fa57161806a099e1 +0 -0
  36. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/09/08da26de58c114225ad81f484b80bf5d351b34 +0 -0
  37. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/0b/409e1bc918277010f5679b402d1d1dda53e15c +0 -0
  38. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/12/c2808a1b3a4d0892a4154dfba1e2ae3770fa73 +0 -0
  39. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/14/449a0e6ba4ea2f1a73acf63ef91c9c6193f9ed +0 -0
  40. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/15/a8e468aacfcb440e090020f36d0b985d45da23 +0 -0
  41. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/1a/b4585881a6a42889f01aa0cfe25fd5acfaf46f +0 -0
  42. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/1c/3f92adda34344bcbbbf9d409c79855ae2aaea8 +0 -0
  43. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/1c/9314c5f69b9390068a2a8616875d974849d71f +0 -0
  44. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/1d/fe9d9633b24ea560354f4f93d39c6e5f163ea0 +0 -0
  45. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/20/72c28e83f4347959d29f7b3a6c1fc3e4ee6b59 +0 -0
  46. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/24/6b368b986f758630c46dc02b7fa512b53422f7 +0 -0
  47. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/25/b796accd261b9135fd32a2c00785f68edf6c46 +0 -0
  48. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/27/aa6074f652bc6f7078f8647489d9ee8e24f0e2 +0 -0
  49. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/28/c2969d785c1b892c2a96b3f00eba63a59811b3 +0 -0
  50. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/2a/ae95d517d213b660bf4f65a4e0cfae7bb893eb +0 -0
  51. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/2a/fdf45791a26d42ccead35ace76a8f0b2a56561 +0 -0
  52. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/30/a2f8da47ee947811dc8d993f5a06a45de374f4 +0 -0
  53. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/32/fd627b62fad7cf3b2f9e34ab9777126a0987ad +0 -0
  54. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/34/9e31b6a3634cea102ce5588b98c11cc1738605 +0 -0
  55. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/34/b6f3a2ee84f39bed4eee57f2c0e0afb994feb1 +0 -0
  56. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/35/1a5f491ab97eee9d1ee699478d75a8bb5d3dc2 +0 -0
  57. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/36/b4a1b7403abc6c360f8fe2cb656ab945254971 +0 -0
  58. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/36/e56a361f526eafa59c5235a5c990bf288b5f9c +0 -0
  59. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/36/ef43e50009e59db11812c258846d9e38718173 +0 -0
  60. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/39/7ead045fbbcfb17c62019eb18fe21ed05dbee5 +0 -0
  61. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/39/b13be65125556784e44c7a1d9821703c7ab67e +0 -0
  62. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/3b/507acc7f23391644cc0b824b1e79fd2677a362 +0 -0
  63. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/3b/bd972aa7ad680858f8dfbd0f7fcd97756f0d6f +0 -0
  64. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/3c/bbe5f4173d165127b9ad96119f1ec24c306ffc +0 -0
  65. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/3d/9d10d27724657a436c65a6254bfd213d4b3562 +0 -0
  66. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/3f/d6561300938afbb3d11976cf9c8f29549280d9 +0 -0
  67. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/41/dcf4b3bf0460946b2da93776cf9e836d62178f +0 -0
  68. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/43/dbd49b2ee367c5434dd545e3b5795434f2ef0b +0 -0
  69. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/45/b1b6178bacbfc997811a998b5cc60c1ea7fac8 +0 -0
  70. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/47/6cbd5a7c5e35cddef2f8a38bdc4896d403b095 +0 -0
  71. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/48/a88fc5806305d0bb0755ee6801161b79696972 +0 -0
  72. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/4f/7afb40dff2153d857fc85748c2eecb85125042 +0 -0
  73. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/50/08ddfcf53c02e82d7eee2e57c38e5672ef89f6 +0 -0
  74. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/53/e0deb1cb4c2c606bced6e7f9a66b0fda60980d +0 -0
  75. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/56/e4e8b2d5545e0256090f45aa8fc42c5fe067d0 +0 -0
  76. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/57/63d0c52f5c9c69e89d514a1f96034947abe21a +0 -0
  77. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/57/bd1c0199483ab316235b094543b85edec6c35e +0 -0
  78. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/58/20a729045d4dc7e37ccaf8aa8eec126850afe2 +0 -0
  79. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/59/380c4c26bdcd4d9b71ae3e2e35f05b3f26c5ab +0 -0
  80. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/5a/192565abf89c9d765af846ce6d53a92b1ce7ad +0 -0
  81. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/60/f273eb1c412d916fa3f11318a7da7a9911b52a +0 -0
  82. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/61/570cec8c061abe74121f27f5face6c69b98f99 +0 -0
  83. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/62/4488173ed2c8936fa5cea3cf5dd3f26a30b86e +0 -0
  84. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/62/7c81b23b4e56e87b042b650b0103653cc9e34a +0 -0
  85. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/62/d90ccf8cbefdc2e4fd475e7c6f4f76e9fdf801 +0 -0
  86. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/63/100154b27846e8010e55b6bf4b3d7762c14c5f +0 -0
  87. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/64/27a4edff08f93d98f511418423f09f2ab90bcd +0 -0
  88. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/66/6227eeeba24073e63811e89f1449f3d958f183 +0 -0
  89. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/66/c998778721d424bd0aae80602dabbffa93af2e +0 -0
  90. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/68/6df3072c8b025fb18106ed2df505994ad062a9 +0 -0
  91. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/69/13c452ca319f7cbf6a0836dc10a5bb033c84e4 +0 -0
  92. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/6a/52e747a2b349b128d1490d9e896d2323818eb7 +0 -0
  93. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/6b/7fde264d93a7a0986d394c46c7650d0ce2ab92 +0 -0
  94. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/6c/cebb29b7f3f5b0c889f6dadbf9ff066554587d +0 -0
  95. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/6d/c2cdf4a84e538e5d4777486aeff87e42f41799 +0 -0
  96. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/6d/ee29dbdcc84edeeacede105110446f3ccac963 +0 -0
  97. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/71/36b2074a2754be8b58127d82250e5b37e3c373 +0 -0
  98. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/72/245a05b0966011cb381e6b32b0465000e969ab +0 -0
  99. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/72/e4179337639859678ddaecf38b16f33aaec8e1 +0 -0
  100. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/78/063f4c863fc371ec0313303c0a81283b35d9b6 +0 -0
  101. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/78/3d4167bc95c9d2175e0df03ef1c1c880ba75ab +0 -0
  102. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/79/7ae089b2212a937840e215276005ce76881307 +0 -0
  103. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/7e/5956c806b5edc344d46dab599dec337891ba1f +0 -0
  104. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/81/8f26b7bf042269729020cf944fc362d66ba27e +0 -0
  105. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/82/70b319ce4046854fbe7dc41054b6c2d112dab2 +0 -0
  106. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/84/59071b722a255b774a80b27746033f8141ab39 +0 -0
  107. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/85/aee46f478e9afdb84d50a05242c53b04ed2e21 +0 -0
  108. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/86/e288b46f8fe179907e4413f665aeb5053fddb1 +0 -0
  109. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/87/ef1fc3f7f1ddc4d0ab9b3e65381ce9f3388621 +0 -0
  110. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/8b/84f56978e1de8f2ae82abce5f8b3e182d365cd +0 -0
  111. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/8e/55a7d2b96184030211f20c9b9af201eefcac82 +0 -0
  112. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/91/c69ad88fe0ba94aa7859fb5f7edac5e6f1a3f7 +0 -0
  113. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/94/74152b4b463d70ae5ad07f0c658be3e296026b +0 -0
  114. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/94/f7dbe88e80c4205a901b71eb8f181974376bba +0 -0
  115. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/97/1aef09ea939f46b60b9646f8d524c78a9220f4 +0 -0
  116. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/9b/ec5ee2236ee2d5532c36bfd132e23c58fdb69c +0 -0
  117. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/9d/0df52899fe95279059286d9c0ec42287edc168 +0 -0
  118. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/a1/5389729850729fc7bd78a54f26fce77f30be12 +0 -0
  119. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/a1/906da89d1174f74867800c74c43af36253bd5e +0 -0
  120. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/a4/63fdd23e5efd713db8a71f316f3a1c7bd60916 +0 -0
  121. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/a5/ec8f74642fbba27f7ea78c53b372ae0c7dedce +0 -0
  122. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/a7/3e13eafee65c5b8d73ad2d3ea46d0eee82f0d3 +0 -0
  123. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/b0/56be4be89ba6b76949dd641df45bb7036050c8 +0 -0
  124. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/b0/9cd7856d58590578ee1a4f3ad45d1310a97f87 +0 -0
  125. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/b2/18e6a0f0f1c4df8cdefa9852058348abc713b7 +0 -0
  126. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/b3/4f7f271c6d6105e35a6556ffda71d03afe8c96 +0 -0
  127. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/b3/69579064bde9de9a19d114fc33e4e48cc8c0e4 +0 -0
  128. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/b5/61831c7dce8ea51e7ee6b6fa35745f14d8242d +0 -0
  129. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/b7/2c9e75ab7d0afe594664650aa8f6c772f5ac64 +0 -0
  130. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/bb/81ccc0513f18fc160b54a82861e9a80d23f4f6 +0 -0
  131. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/bb/934eb33bc1a8b85630bf680caffd99560c1b8f +0 -0
  132. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/bf/67907e337021ebff434e02b19b30a741c144af +0 -0
  133. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/bf/b54d65922ce1dfda1aaa014913a54e7172d0bc +0 -0
  134. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/c1/20fc812b9ad311c34a3608512d6a9d976bb48e +0 -0
  135. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/c1/397c6ed72c4e20ef6b9ab83163e9a6baba5b45 +0 -0
  136. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/c4/cba65f1163661999ee4b8ed23342b63bc1300c +0 -0
  137. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/c6/7f17e5707313600efcb85e9a3fedea35dba591 +0 -0
  138. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/c6/f32aced880bd165a251cb52b26b0c1107e2141 +0 -0
  139. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/cc/45df1d317a2eb63ff1ff3a5f3b4a9f98fd92b5 +0 -0
  140. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/cd/822b3574a88ebdd1ed82fd6983f37e626d52b4 +0 -0
  141. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/cf/0c0d9c6fb09473aaeb7f7e2edbd770c3f2ef3d +0 -0
  142. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/d2/992df305f4b56a466a2f221aeb182ddd20f418 +0 -0
  143. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/d6/39e8af592cd75a318d8affddd1bcc70c2095f2 +0 -0
  144. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/d6/9ab1c4aadf279936dd778e8346ba60f74705b6 +0 -0
  145. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/d8/4688b54c0040a30976b3a6540bc47adf7ce680 +0 -0
  146. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/d9/005f2cc7fc4e65f14ed5518276007c08cf2fd0 +0 -0
  147. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/d9/c2403fd166ce791b4e9d0c6792ed8342c71fcd +0 -0
  148. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/d9/dfa5aee51e92a541b707e8e7baea6f06deff98 +0 -0
  149. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/db/141dbaa93594df2a8156182f361ee4db829359 +0 -0
  150. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/db/3f2cd643292057936230b95cf7ec3046affe11 +0 -0
  151. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/db/ffa8ea7bda721d0cee7b9e4ce5b2ef927733ff +0 -0
  152. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/dc/c2bdbafb3296e09d9ee4955cfa55d275825f94 +0 -0
  153. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/dc/cdbd4266765d840be2ae35ab1752a0fa312c16 +0 -0
  154. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/dd/87fb5f606fe380d81e6fe3a2c98f9f99e3e09b +0 -0
  155. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/de/214c626ac2dd2685bfaa0bc0fc20f528d014d7 +0 -0
  156. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/df/e0770424b2a19faf507a501ebfc23be8f54e7b +0 -0
  157. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/e2/f2f8f4c25e62a297fc55f36acc6b01cfbab76f +0 -0
  158. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/e3/1356f90ea6dd0577b5e0b40b206319adcbf085 +0 -0
  159. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/e3/5a4dafc50850cacac7bf76c56db2715cbda2c4 +0 -0
  160. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/e4/6c715352db9fe3c887a635f1916df4ca1f4ff9 +0 -0
  161. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/e5/0580a0bd1e1b3d29f834382b80fceb61d5cf0c +0 -0
  162. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/e9/391ffe371f1cc43b42ef09b705d9c767c2e14f +0 -0
  163. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/ea/3a18cc75e53792744ef754e05d3f4481768c13 +0 -0
  164. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/ec/40fd8bf8e4c342534a9fc020289e402ba6bc9d +0 -0
  165. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/ec/d980279432b13f0374b90ca439a6329cdece0f +0 -0
  166. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/ee/cee64eacaff022dcdc509c0c2b1da492f21060 +0 -0
  167. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/f1/e50757fddc28b445545dc7e2759b54cdd0f42e +0 -0
  168. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/f4/b64d3107b39e3ad6f540c6607004ea34e6c024 +0 -0
  169. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/f4/ba7f815b886797b73fede071d86e0c134d2bc7 +0 -0
  170. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/f5/61c3c1bf1c9ea9c9d1f556a7be2869f71f3bdf +0 -0
  171. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/f6/44a8ff56fa035105fc517cbb1ac46c3d8e349a +0 -0
  172. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/f7/c98ba5c2f903e603b1f5e63d49fbc8a43815cc +0 -0
  173. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/f9/045a08e96eb76848fc4d68e3e3e687cca39a2d +0 -0
  174. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/fa/147e6bb78a2e8db241d231295fd7f1ed061af8 +0 -0
  175. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/objects/fc/292e793ecfd42240ac43be407023bd731fa9e7 +0 -0
  176. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/refs/.DS_Store +0 -0
  177. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/refs/heads/main +0 -0
  178. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/refs/remotes/origin/HEAD +0 -0
  179. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.git/refs/remotes/origin/main +0 -0
  180. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.gitattributes +0 -0
  181. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/.gitignore +0 -0
  182. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/LICENSE +0 -0
  183. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/README.md +0 -0
  184. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/__init__.py +0 -0
  185. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/batman.py +0 -0
  186. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/bio.py +0 -0
  187. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/brain_atlas.py +0 -0
  188. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/chat.py +0 -0
  189. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/corr.py +0 -0
  190. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/correlators.py +0 -0
  191. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/.DS_Store +0 -0
  192. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/db2ls_sql_chtsht.json +0 -0
  193. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/docs_links.json +0 -0
  194. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/email/email_html_template.html +0 -0
  195. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/hyper_param_autogluon_zeroshot2024.json +0 -0
  196. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/hyper_param_tabrepo_2024.py +0 -0
  197. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/lang_code_iso639.json +0 -0
  198. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/mygenes_fields_241022.txt +0 -0
  199. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/sns_info.json +0 -0
  200. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/.DS_Store +0 -0
  201. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/example/.DS_Store +0 -0
  202. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/example/style1.pdf +0 -0
  203. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/example/style2.pdf +0 -0
  204. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/example/style3.pdf +0 -0
  205. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/example/style4.pdf +0 -0
  206. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/example/style5.pdf +0 -0
  207. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/example/style6.pdf +0 -0
  208. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/example/style7.pdf +0 -0
  209. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/example/style8.pdf +0 -0
  210. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/example/style9.pdf +0 -0
  211. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style1.json +0 -0
  212. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style10.json +0 -0
  213. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style11.json +0 -0
  214. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style12.json +0 -0
  215. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style2.json +0 -0
  216. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style3.json +0 -0
  217. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style4.json +0 -0
  218. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style5.json +0 -0
  219. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style6.json +0 -0
  220. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style7.json +0 -0
  221. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style8.json +0 -0
  222. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/style9.json +0 -0
  223. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/.DS_Store +0 -0
  224. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/grid.mplstyle +0 -0
  225. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/high-contrast.mplstyle +0 -0
  226. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/high-vis.mplstyle +0 -0
  227. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/ieee.mplstyle +0 -0
  228. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/light.mplstyl +0 -0
  229. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/muted.mplstyle +0 -0
  230. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/nature-reviews-latex.mplstyle +0 -0
  231. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/nature-reviews.mplstyle +0 -0
  232. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/nature.mplstyle +0 -0
  233. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/no-latex.mplstyle +0 -0
  234. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/notebook.mplstyle +0 -0
  235. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/paper.mplstyle +0 -0
  236. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/retro.mplstyle +0 -0
  237. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/sans.mplstyle +0 -0
  238. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/scatter.mplstyle +0 -0
  239. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/science.mplstyle +0 -0
  240. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/std-colors.mplstyle +0 -0
  241. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/styles/stylelib/vibrant.mplstyle +0 -0
  242. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/tiles.csv +0 -0
  243. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/usages_pd.json +0 -0
  244. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/data/usages_sns.json +0 -0
  245. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/db2ls.py +0 -0
  246. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/doc.py +0 -0
  247. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/ec2ls.py +0 -0
  248. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/export_requirements.py +0 -0
  249. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/fetch_update.py +0 -0
  250. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/freqanalysis.py +0 -0
  251. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/ich2ls.py +0 -0
  252. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/ml2ls.py +0 -0
  253. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/mol.py +0 -0
  254. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/nl2ls.py +0 -0
  255. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/plot.py +0 -0
  256. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/setuptools-70.1.0-py3-none-any.whl +0 -0
  257. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/sleep_events_detectors.py +0 -0
  258. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/stats.py +0 -0
  259. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/translator.py +0 -0
  260. {py2ls-0.2.4.34 → py2ls-0.2.4.35}/py2ls/wb_detector.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: py2ls
3
- Version: 0.2.4.34
3
+ Version: 0.2.4.35
4
4
  Summary: py(thon)2(too)ls
5
5
  Author: Jianfeng
6
6
  Author-email: Jianfeng.Liu0413@gmail.com
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.9
14
14
  Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: Programming Language :: Python :: 3.11
16
16
  Classifier: Programming Language :: Python :: 3.12
17
- Provides-Extra: extr
17
+ Provides-Extra: full
18
18
  Requires-Dist: CacheControl (>=0.13.1)
19
19
  Requires-Dist: Cython (>=3.0.10)
20
20
  Requires-Dist: Deprecated (>=1.2.14)
@@ -123,6 +123,7 @@ Requires-Dist: mne (>=1.7.1)
123
123
  Requires-Dist: more-itertools (>=10.3.0)
124
124
  Requires-Dist: mpmath (>=1.3.0)
125
125
  Requires-Dist: msgpack (>=1.0.8)
126
+ Requires-Dist: msoffcrypto-tool (>=5.4.2)
126
127
  Requires-Dist: mtscomp (>=1.0.2)
127
128
  Requires-Dist: nbclient (>=0.10.0)
128
129
  Requires-Dist: nbconvert (>=7.16.4)
@@ -131,6 +132,7 @@ Requires-Dist: neo (>=0.13.1)
131
132
  Requires-Dist: nest-asyncio (>=1.6.0)
132
133
  Requires-Dist: networkx (>=3.3)
133
134
  Requires-Dist: nltk (>=3.8.1)
135
+ Requires-Dist: nuitka (>=2.5.9)
134
136
  Requires-Dist: numba (>=0.59.1)
135
137
  Requires-Dist: numcodecs (>=0.13.0)
136
138
  Requires-Dist: numerizer (>=0.2.3)
@@ -139,6 +141,7 @@ Requires-Dist: onnxruntime (>=1.18.1)
139
141
  Requires-Dist: opencv-contrib-python (>=4.10.0.84)
140
142
  Requires-Dist: opencv-python (>=4.10.0.84)
141
143
  Requires-Dist: opencv-python-headless (>=4.10.0.84)
144
+ Requires-Dist: openpyxl (>=3.1.5)
142
145
  Requires-Dist: outcome (>=1.3.0.post0)
143
146
  Requires-Dist: packaging (>=24.1)
144
147
  Requires-Dist: pandas (>=2.2.2)
@@ -199,6 +202,7 @@ Requires-Dist: rpds-py (>=0.18.1)
199
202
  Requires-Dist: scikit-image (>=0.23.2)
200
203
  Requires-Dist: scikit-learn (>=1.5.1)
201
204
  Requires-Dist: scipy (>=1.14.0)
205
+ Requires-Dist: scrapy (>=2.12.0)
202
206
  Requires-Dist: seaborn (>=0.13.2)
203
207
  Requires-Dist: selenium (>=4.23.1)
204
208
  Requires-Dist: setuptools (>=70.3.0)
@@ -32,10 +32,16 @@ def backup(
32
32
  tar="/Users/macjianfeng/Dropbox/github/python/py2ls/py2ls/",
33
33
  kind="py",
34
34
  overwrite=True,
35
- ):
36
- f = listdir(src, kind)
37
- [copy(i, tar, overwrite=overwrite) for i in f.path]
38
- print(f"all files are copied from {os.path.basename(src)} to {tar}")
35
+ reverse=False,
36
+ verbose=False
37
+ ):
38
+ if reverse:
39
+ src, tar = tar,src
40
+ print(f"reversed")
41
+ f = listdir(src, kind, verbose=verbose)
42
+ [copy(i, tar, overwrite=overwrite, verbose=verbose) for i in f.path]
43
+ print(f"all files are copied from {os.path.basename(src)} to {tar}") if verbose else None
44
+
39
45
  def run_once_within(duration=60, reverse=False): # default 60s
40
46
  import time
41
47
 
@@ -2693,13 +2699,41 @@ def fload(fpath, kind=None, **kwargs):
2693
2699
  def load_excel(fpath, **kwargs):
2694
2700
  engine = kwargs.get("engine", "openpyxl")
2695
2701
  verbose = kwargs.pop("verbose", False)
2696
- if run_once_within(reverse=True):
2697
- use_pd("read_excel", verbose=verbose)
2698
- df = pd.read_excel(fpath, engine=engine, **kwargs)
2702
+ password=kwargs.pop("password",None)
2703
+
2704
+ if not password:
2705
+ if run_once_within(reverse=True):
2706
+ use_pd("read_excel", verbose=verbose)
2707
+ df = pd.read_excel(fpath, engine=engine, **kwargs)
2708
+ try:
2709
+ meta = pd.ExcelFile(fpath)
2710
+ print(f"n_sheet={len(meta.sheet_names)},\t'sheetname = 0 (default)':")
2711
+ [print(f"{i}:\t{i_}") for i, i_ in enumerate(meta.sheet_names)]
2712
+ except:
2713
+ pass
2714
+ return df
2715
+ #* needs a password?
2716
+ import msoffcrypto # pip install msoffcrypto-tool
2717
+ from io import BytesIO
2718
+
2719
+ # Open the encrypted Excel file
2720
+ with open(fpath, 'rb') as f:
2721
+ try:
2722
+ office_file = msoffcrypto.OfficeFile(f)
2723
+ office_file.load_key(password=password) # Provide the password
2724
+ decrypted = BytesIO()
2725
+ office_file.decrypt(decrypted)
2726
+ except:
2727
+ office_file = msoffcrypto.OfficeFile(f)
2728
+ office_file.load_key(password=depass(password)) # Provide the password
2729
+ decrypted = BytesIO()
2730
+ office_file.decrypt(decrypted)
2731
+ decrypted.seek(0)
2732
+ df = pd.read_excel(decrypted, engine=engine, **kwargs)
2699
2733
  try:
2700
- meata = pd.ExcelFile(fpath)
2701
- print(f"n_sheet={len(meata.sheet_names)},\t'sheetname = 0 (default)':")
2702
- [print(f"{i}:\t{i_}") for i, i_ in enumerate(meata.sheet_names)]
2734
+ meta = pd.ExcelFile(fpath)
2735
+ print(f"n_sheet={len(meta.sheet_names)},\t'sheetname = 0 (default)':")
2736
+ [print(f"{i}:\t{i_}") for i, i_ in enumerate(meta.sheet_names)]
2703
2737
  except:
2704
2738
  pass
2705
2739
  return df
@@ -3283,11 +3317,16 @@ def fsave(
3283
3317
  df = pd.DataFrame(data)
3284
3318
  df.to_csv(fpath, **kwargs_valid)
3285
3319
 
3286
- def save_xlsx(fpath, data, **kwargs):
3320
+
3321
+ def save_xlsx(fpath, data, password=None, **kwargs):
3322
+ import msoffcrypto
3323
+ from io import BytesIO
3287
3324
  verbose = kwargs.pop("verbose", False)
3288
3325
  sheet_name = kwargs.pop("sheet_name", "Sheet1")
3326
+
3289
3327
  if run_once_within(reverse=True):
3290
3328
  use_pd("to_excel", verbose=verbose)
3329
+
3291
3330
  if any(kwargs):
3292
3331
  format_excel(df=data, filename=fpath, **kwargs)
3293
3332
  else:
@@ -3312,16 +3351,30 @@ def fsave(
3312
3351
  kwargs.pop(key, None)
3313
3352
 
3314
3353
  df = pd.DataFrame(data)
3315
- # Check if the file exists, then append the sheet, otherwise create a new file
3316
- try:
3317
- # Use ExcelWriter with append mode if the file exists
3318
- with pd.ExcelWriter(
3319
- fpath, engine="openpyxl", mode="a", if_sheet_exists="new"
3320
- ) as writer:
3321
- df.to_excel(writer, sheet_name=sheet_name, index=False, **kwargs)
3322
- except FileNotFoundError:
3323
- # If file doesn't exist, create a new one
3324
- df.to_excel(fpath, sheet_name=sheet_name, index=False, **kwargs)
3354
+
3355
+ # Write to Excel without password first
3356
+ temp_file = BytesIO()
3357
+ df.to_excel(temp_file, sheet_name=sheet_name, index=False, engine="xlsxwriter", **kwargs)
3358
+
3359
+ # If a password is provided, encrypt the file
3360
+ if password:
3361
+ temp_file.seek(0)
3362
+ office_file = msoffcrypto.OfficeFile(temp_file)
3363
+ office_file.load_key(password=password) # Provide the password
3364
+
3365
+ # Encrypt and save the file
3366
+ with open(fpath, 'wb') as encrypted_file:
3367
+ office_file.encrypt(encrypted_file)
3368
+ else:
3369
+ # Save the file without encryption if no password is provided
3370
+ try:
3371
+ # Use ExcelWriter with append mode if the file exists
3372
+ with pd.ExcelWriter(fpath, engine="openpyxl", mode="a", if_sheet_exists="new") as writer:
3373
+ df.to_excel(writer, sheet_name=sheet_name, index=False, **kwargs)
3374
+ except FileNotFoundError:
3375
+ # If file doesn't exist, create a new one
3376
+ df.to_excel(fpath, sheet_name=sheet_name, index=False, **kwargs)
3377
+
3325
3378
 
3326
3379
  def save_ipynb(fpath, data, **kwargs):
3327
3380
  # Split the content by code fences to distinguish between code and markdown
@@ -4410,13 +4463,13 @@ def func_list(lib_name, opt="call"):
4410
4463
  return list_func(lib_name, opt=opt)
4411
4464
 
4412
4465
 
4413
- def copy(src, dst, overwrite=False):
4466
+ def copy(src, dst, overwrite=False, verbose=True):
4414
4467
  """Copy a file from src to dst."""
4415
4468
  try:
4416
4469
  dir_par_dst = os.path.dirname(dst)
4417
4470
  if not os.path.isdir(dir_par_dst):
4418
4471
  mkdir(dir_par_dst)
4419
- print(dir_par_dst)
4472
+ print(dir_par_dst) if verbose else None
4420
4473
  src = Path(src)
4421
4474
  dst = Path(dst)
4422
4475
  if not src.is_dir():
@@ -4431,7 +4484,7 @@ def copy(src, dst, overwrite=False):
4431
4484
  f"{dst.stem}_{datetime.now().strftime('_%H%M%S')}{dst.suffix}"
4432
4485
  )
4433
4486
  shutil.copy(src, dst)
4434
- print(f"\n Done! copy to {dst}\n")
4487
+ print(f"\n Done! copy to {dst}\n") if verbose else None
4435
4488
  else:
4436
4489
  dst = dst / src.name
4437
4490
  if dst.exists():
@@ -4442,7 +4495,7 @@ def copy(src, dst, overwrite=False):
4442
4495
  f"{dst.stem}_{datetime.now().strftime('%H%M%S')}"
4443
4496
  )
4444
4497
  shutil.copytree(src, dst)
4445
- print(f"\n Done! copy to {dst}\n")
4498
+ print(f"\n Done! copy to {dst}\n") if verbose else None
4446
4499
 
4447
4500
  except Exception as e:
4448
4501
  logging.error(f"Failed {e}")
@@ -4452,7 +4505,7 @@ def cut(src, dst, overwrite=False):
4452
4505
  return move(src=src, dst=dst, overwrite=overwrite)
4453
4506
 
4454
4507
 
4455
- def move(src, dst, overwrite=False):
4508
+ def move(src, dst, overwrite=False, verbose=True):
4456
4509
  try:
4457
4510
  dir_par_dst = os.path.dirname(dst)
4458
4511
  if not os.path.isdir(dir_par_dst):
@@ -4470,7 +4523,7 @@ def move(src, dst, overwrite=False):
4470
4523
  f"{dst.stem}_{datetime.now().strftime('_%H%M%S')}{dst.suffix}"
4471
4524
  )
4472
4525
  shutil.move(src, dst)
4473
- print(f"\n Done! moved to {dst}\n")
4526
+ print(f"\n Done! moved to {dst}\n") if verbose else None
4474
4527
  except Exception as e:
4475
4528
  logging.error(f"Failed to move file from {src} to {dst}: {e}")
4476
4529
 
@@ -4729,6 +4782,19 @@ def figsave(*args, dpi=300):
4729
4782
  plt.savefig(fname, format="emf", dpi=dpi, bbox_inches="tight", pad_inches=0)
4730
4783
  elif ftype.lower() == "fig":
4731
4784
  plt.savefig(fname, format="pdf", bbox_inches="tight", dpi=dpi, pad_inches=0)
4785
+
4786
+ elif ftype.lower() == "ico":
4787
+ # Ensure the image is in a format that can be saved as an icon (e.g., 32x32, 64x64, etc.)
4788
+ if img is None: # If no image is provided, use the matplotlib figure
4789
+ img = plt.figure()
4790
+ img.savefig(fname, dpi=dpi, format="png", bbox_inches="tight")
4791
+ img = Image.open(fname) # Load the saved figure image
4792
+
4793
+ # Resize the image to typical icon sizes and save it as .ico
4794
+ icon_sizes = [(32, 32), (64, 64), (128, 128), (256, 256)]
4795
+ img = img.convert("RGBA") # Ensure it has an alpha channel for transparency
4796
+ img.save(fname, format="ICO", sizes=icon_sizes)
4797
+ print(f"Icon saved @: {fname} with sizes: {icon_sizes}")
4732
4798
  print(f"\nSaved @: dpi={dpi}\n{fname}")
4733
4799
 
4734
4800
 
@@ -5507,7 +5573,6 @@ def detect_angle(image, by="median", template=None):
5507
5573
  print(f"Unknown method {by}: supported methods: {methods}")
5508
5574
  return 0
5509
5575
 
5510
-
5511
5576
  def imgsets(img,
5512
5577
  auto:bool=True,
5513
5578
  size=None,
@@ -5594,7 +5659,6 @@ def imgsets(img,
5594
5659
  "birefnet-massive": "A pre-trained model with massive dataset.",
5595
5660
  }
5596
5661
  models_support_rem=list(rem_models.keys())
5597
-
5598
5662
  str_usage="""
5599
5663
  imgsets(dir_img, auto=1, color=1.5, plot_=0)
5600
5664
  imgsets(dir_img, color=2)
@@ -5714,7 +5778,7 @@ def imgsets(img,
5714
5778
  kwargs = {**auto_enhance(img_update), **kwargs}
5715
5779
  params=["sharp","color","contrast","bright","crop","rotate",'size',"resize",
5716
5780
  "thumbnail","cover","contain","filter","fit","pad",
5717
- "rem","rm","back","bg_color","cut",'gamma','flip']
5781
+ "rem","rm","back","bg_color","cut","gamma","flip","booster"]
5718
5782
  for k, value in kwargs.items():
5719
5783
  k = strcmp(k, params)[0] # correct the param name
5720
5784
  if "shar" in k.lower():
@@ -5735,7 +5799,7 @@ def imgsets(img,
5735
5799
  img_update = ImageOps.autocontrast(img_update)
5736
5800
  print("autocontrasted")
5737
5801
  except Exception as e:
5738
- print(f"Failed 'autocontrasted':{e}")
5802
+ print(f"Failed 'auto-contrasted':{e}")
5739
5803
  elif "bri" in k.lower():
5740
5804
  enhancer = ImageEnhance.Brightness(img_update)
5741
5805
  img_update = enhancer.enhance(value)
@@ -5780,9 +5844,12 @@ def imgsets(img,
5780
5844
  from rembg import remove, new_session
5781
5845
  if verbose:
5782
5846
  preview(rem_models)
5847
+
5848
+ print(f"supported modles: {models_support_rem}")
5783
5849
  model=strcmp(model, models_support_rem)[0]
5784
5850
  session = new_session(model)
5785
5851
  if isinstance(value, bool):
5852
+ print(f"using model:{model}")
5786
5853
  img_update = remove(img_update, session=session)
5787
5854
  elif value and isinstance(value, (int, float, list)):
5788
5855
  if verbose:
@@ -5817,6 +5884,7 @@ def imgsets(img,
5817
5884
  img_update = remove(img_update, bgcolor=value, session=session)
5818
5885
  elif isinstance(value, str):
5819
5886
  # use custom model
5887
+ print(f"using model:{strcmp(value, models_support_rem)[0]}")
5820
5888
  img_update = remove(img_update, session=new_session(strcmp(value, models_support_rem)[0]))
5821
5889
  elif "bg" in k.lower() and "color" in k.lower():
5822
5890
  from rembg import remove
@@ -5827,7 +5895,33 @@ def imgsets(img,
5827
5895
  if len(value) == 3:
5828
5896
  value += (255,)
5829
5897
  img_update = remove(img_update, bgcolor=value)
5830
-
5898
+ elif 'boost' in k.lower():
5899
+ import torch
5900
+ from realesrgan import RealESRGANer
5901
+ if verbose:
5902
+ print("Applying Real-ESRGAN for image reconstruction...")
5903
+ if isinstance(value, bool):
5904
+ scale=4
5905
+ elif isinstance(value, (float, int)):
5906
+ scale=value
5907
+ else:
5908
+ scale=4
5909
+
5910
+ # try:
5911
+ device = "cuda" if torch.cuda.is_available() else "cpu"
5912
+ dir_curr_script = os.path.dirname(os.path.abspath(__file__))
5913
+ model_path = dir_curr_script + "/data/RealESRGAN_x4plus.pth"
5914
+ model_RealESRGAN = RealESRGANer(device=device,
5915
+ scale=scale,
5916
+ model_path=model_path,
5917
+ model="RealESRGAN_x4plus"
5918
+ )
5919
+ # https://github.com/xinntao/Real-ESRGAN?tab=readme-ov-file#python-script
5920
+
5921
+ img_update = model_RealESRGAN.enhance(np.array(img_update))[0]
5922
+ # except Exception as e:
5923
+ # print(f"Failed to apply Real-ESRGAN: {e}")
5924
+
5831
5925
  # elif "ga" in k.lower() and "m" in k.lower():
5832
5926
  # img_update = gamma_correction(img_update, gamma=value)
5833
5927
  # Display the image if requested
@@ -10728,4 +10822,227 @@ def mouse(
10728
10822
  # "Image not found. Ensure the image is visible and parameters are correct."
10729
10823
  # )
10730
10824
  # except Exception as e:
10731
- # print(f"An error occurred: {e}")
10825
+ # print(f"An error occurred: {e}")
10826
+
10827
+
10828
+
10829
+ def py2installer(
10830
+ script_path: str=None,
10831
+ flatform:str="mingw64",
10832
+ output_dir: str = "dist",
10833
+ icon_path: str = None,
10834
+ extra_data: list = None,
10835
+ hidden_imports: list = None,
10836
+ plugins:list=None,
10837
+ use_nuitka: bool = True,
10838
+ onefile: bool = True,
10839
+ console: bool = True,
10840
+ clean_build: bool = False,
10841
+ additional_args: list = None,
10842
+ verbose: bool = True,
10843
+ use_docker: bool = False,
10844
+ docker_image: str = "python:3.12-slim",
10845
+ ):
10846
+ """
10847
+ to package Python scripts into standalone application.
10848
+
10849
+ script_path (str): Path to the Python script to package.
10850
+ output_dir (str): Directory where the executable will be stored.
10851
+ icon_path (str): Path to the .ico file for the executable icon.
10852
+ extra_data (list): List of additional data files or directories in "source:dest" format.
10853
+ hidden_imports (list): List of hidden imports to include.
10854
+ plugins (list): List of plugins imports to include.e.g., 'tk-inter'
10855
+ use_nuitka (bool): Whether to use Nuitka instead of PyInstaller.
10856
+ onefile (bool): If True, produces a single executable file.
10857
+ console (bool): If False, hides the console window (GUI mode).
10858
+ clean_build (bool): If True, cleans previous build and dist directories.
10859
+ additional_args (list): Additional arguments for PyInstaller/Nuitka.
10860
+ verbose (bool): If True, provides detailed logs.
10861
+ use_docker (bool): If True, uses Docker to package the script.
10862
+ docker_image (str): Docker image to use for packaging.
10863
+
10864
+ """
10865
+
10866
+ import os
10867
+ import sys
10868
+ import shutil
10869
+ import subprocess
10870
+ import sys
10871
+ import glob
10872
+ from pathlib import Path
10873
+ if run_once_within():
10874
+ usage_str="""
10875
+ # build locally
10876
+ py2installer(
10877
+ script_path="update_tab.py",
10878
+ output_dir="dist",
10879
+ icon_path="icon4app.ico",
10880
+ extra_data=["dat/*.xlsx:dat"],
10881
+ hidden_imports=["msoffcrypto", "tkinter", "pandas", "numpy"],
10882
+ onefile=True,
10883
+ console=False,
10884
+ clean_build=True,
10885
+ verbose=True,
10886
+ )
10887
+ # build via docker
10888
+ py2installer(
10889
+ "my_script.py",
10890
+ output_dir="dist",
10891
+ onefile=True,
10892
+ clean_build=True,
10893
+ use_docker=True,
10894
+ docker_image="python:3.12-slim"
10895
+ )
10896
+ """
10897
+ print(usage_str)
10898
+ if verbose:
10899
+ return
10900
+ else:
10901
+ pass
10902
+ # Check if the script path exists
10903
+ script_path = Path(script_path)
10904
+ if not script_path.exists():
10905
+ raise FileNotFoundError(f"Script '{script_path}' not found.")
10906
+
10907
+ # Clean build and dist directories if requested
10908
+ if clean_build:
10909
+ for folder in ["build", "dist"]:
10910
+ folder_path = Path(folder)
10911
+ if folder_path.exists():
10912
+ shutil.rmtree(folder_path, ignore_errors=True)
10913
+ # Recreate the folders
10914
+ for folder in ["build", "dist"]:
10915
+ folder_path = Path(folder)
10916
+ folder_path.mkdir(parents=True, exist_ok=True)
10917
+
10918
+
10919
+ if use_docker:
10920
+ # Ensure Docker is installed
10921
+ try:
10922
+ subprocess.run(["docker", "--version"], check=True, capture_output=True, text=True)
10923
+ except FileNotFoundError:
10924
+ raise EnvironmentError("Docker is not installed or not in the PATH.")
10925
+
10926
+ # Prepare Docker volume mappings
10927
+ script_dir = script_path.parent.resolve()
10928
+ dist_path = Path(output_dir).resolve()
10929
+ volumes = [
10930
+ f"{script_dir}:/app:rw",
10931
+ f"{dist_path}:/output:rw",
10932
+ ]
10933
+ docker_cmd = [
10934
+ "docker", "run", "--rm",
10935
+ "-v", volumes[0],
10936
+ "-v", volumes[1],
10937
+ docker_image,
10938
+ "bash", "-c",
10939
+ ]
10940
+
10941
+ # Build the packaging command inside the container
10942
+ cmd = ["nuitka"] if use_nuitka else ["pyinstaller"]
10943
+ if onefile:
10944
+ cmd.append("--onefile")
10945
+ if not console:
10946
+ cmd.append("--windowed")
10947
+ cmd.extend(["--distpath", "/output"])
10948
+ if icon_path:
10949
+ cmd.extend(["--icon", f"/app/{Path(icon_path).name}"])
10950
+ if extra_data:
10951
+ for data in extra_data:
10952
+ cmd.extend(["--add-data", f"/app/{data}"])
10953
+ if hidden_imports:
10954
+ for hidden in hidden_imports:
10955
+ cmd.extend(["--hidden-import", hidden])
10956
+ if additional_args:
10957
+ cmd.extend(additional_args)
10958
+ cmd.append(f"/app/{script_path.name}")
10959
+
10960
+ # Full command to execute inside the container
10961
+ docker_cmd.append(" ".join(cmd))
10962
+
10963
+ if verbose:
10964
+ print(f"Running Docker command: {' '.join(docker_cmd)}")
10965
+
10966
+ # Run Docker command
10967
+ try:
10968
+ subprocess.run(
10969
+ docker_cmd,
10970
+ capture_output=not verbose,
10971
+ text=True,
10972
+ check=True,
10973
+ )
10974
+ except subprocess.CalledProcessError as e:
10975
+ print(f"Error during Docker packaging:\n{e.stderr}", file=sys.stderr)
10976
+ raise
10977
+ else:
10978
+ # Handle local packaging (native build)
10979
+ cmd = ["nuitka"]
10980
+ cmd.append("--standalone") # Make sure to use --standalone for independent environments
10981
+ if 'min' in flatform.lower():
10982
+ cmd.append("--mingw64")
10983
+ if onefile:
10984
+ cmd.append("--onefile")
10985
+ if not console:
10986
+ # cmd.append("--windows-disable-console") # Disabled based on your request
10987
+ pass
10988
+
10989
+ cmd.extend([f"--output-dir={output_dir}"]) # Correct the space issue here
10990
+ if icon_path:
10991
+ icon_path = Path(icon_path)
10992
+ if not icon_path.exists():
10993
+ raise FileNotFoundError(f"Icon file '{icon_path}' not found.")
10994
+ cmd.extend([f"--windows-icon-from-ico={icon_path}"])
10995
+
10996
+ if extra_data:
10997
+ for data in extra_data:
10998
+ if "*" in data:
10999
+ matches = glob.glob(data.split(":")[0])
11000
+ for match in matches:
11001
+ dest = data.split(":")[1]
11002
+ cmd.extend(
11003
+ [
11004
+ "--include-data-file=" if use_nuitka else "--add-data",
11005
+ f"{match}:{dest}",
11006
+ ]
11007
+ )
11008
+ else:
11009
+ cmd.extend(
11010
+ ["--include-data-file=" if use_nuitka else "--add-data", data]
11011
+ )
11012
+
11013
+ if hidden_imports:
11014
+ cmd.extend([f"--nofollow-import-to={','.join(hidden_imports)}"])
11015
+
11016
+ if plugins:
11017
+ for plugin in plugins:
11018
+ cmd.extend([f"--plugin-enable={plugin}"])
11019
+
11020
+ if additional_args:
11021
+ cmd.extend(additional_args)
11022
+
11023
+ # Add the script path (final positional argument)
11024
+ cmd.append(str(script_path))
11025
+
11026
+ # Ensure Windows shell compatibility
11027
+ shell_flag = sys.platform.startswith("win")
11028
+
11029
+ # Run the command
11030
+ if verbose:
11031
+ print(f"Running command: {' '.join(cmd)}")
11032
+ try:
11033
+ result = subprocess.run(
11034
+ cmd,
11035
+ capture_output=not verbose,
11036
+ text=True,
11037
+ shell=shell_flag,
11038
+ check=True,
11039
+ )
11040
+ if verbose:
11041
+ print(result.stdout)
11042
+ except subprocess.CalledProcessError as e:
11043
+ print(f"Error during packaging:\n{e.stderr}", file=sys.stderr)
11044
+ print(" ".join(cmd))
11045
+ raise
11046
+
11047
+ print("\nPackaging complete. Check the output directory for the executable.")
11048
+
@@ -333,32 +333,6 @@ def parse_cookies(cookies_str):
333
333
 
334
334
  return cookies_dict
335
335
 
336
- class FetchSpider(scrapy.Spider):
337
- name = "fetch_spider"
338
-
339
- def __init__(self, url, parser="html.parser", cookies=None, headers=None, *args, **kwargs):
340
- super(FetchSpider, self).__init__(*args, **kwargs)
341
- self.start_urls = [url]
342
- self.cookies = cookies
343
- self.headers = headers
344
- self.parser = parser
345
-
346
- def start_requests(self):
347
- for url in self.start_urls:
348
- yield scrapy.Request(
349
- url,
350
- cookies=self.cookies,
351
- headers=self.headers,
352
- callback=self.parse
353
- )
354
-
355
- def parse(self, response):
356
- # Use the desired parser (default: html.parser)
357
- from bs4 import BeautifulSoup
358
- soup = BeautifulSoup(response.text, self.parser)
359
- yield {"content": soup}
360
-
361
-
362
336
  def fetch_scrapy(
363
337
  url,
364
338
  parser="html.parser",
@@ -367,7 +341,7 @@ def fetch_scrapy(
367
341
  settings=None,
368
342
  ):
369
343
  """
370
- Fetches content using Scrapy.
344
+ Fetches content using Scrapy with proper reactor handling.
371
345
 
372
346
  Args:
373
347
  url (str): The URL to scrape.
@@ -380,9 +354,10 @@ def fetch_scrapy(
380
354
  dict: Parsed content as a dictionary.
381
355
  """
382
356
  from scrapy.utils.project import get_project_settings
383
- from scrapy.crawler import CrawlerProcess
357
+ from scrapy.crawler import CrawlerRunner
384
358
  from scrapy.signalmanager import dispatcher
385
359
  from scrapy import signals
360
+ from twisted.internet import reactor, defer
386
361
  import scrapy
387
362
 
388
363
  # Container for scraped content
@@ -403,19 +378,30 @@ def fetch_scrapy(
403
378
  }
404
379
  )
405
380
 
406
- # Initialize and configure Scrapy process
407
- process = CrawlerProcess(settings=process_settings)
381
+ # Connect item scraped signal
408
382
  dispatcher.connect(handle_item, signal=signals.item_scraped)
409
383
 
410
- # Start the Scrapy crawl
411
- process.crawl(
412
- FetchSpider,
413
- url=url,
414
- parser=parser,
415
- cookies=cookies,
416
- headers=headers,
417
- )
418
- process.start() # Blocks until all crawls are finished
384
+ # Asynchronous Twisted function
385
+ @defer.inlineCallbacks
386
+ def crawl():
387
+ runner = CrawlerRunner(settings=process_settings)
388
+ yield runner.crawl(
389
+ FetchSpider,
390
+ url=url,
391
+ parser=parser,
392
+ cookies=cookies,
393
+ headers=headers,
394
+ )
395
+ reactor.stop()
396
+
397
+ # Start the reactor if not already running
398
+ if not reactor.running:
399
+ crawl()
400
+ reactor.run() # Blocks until the crawl finishes
401
+ else:
402
+ # Run the crawl if the reactor is already running
403
+ d = crawl()
404
+ d.addBoth(lambda _: reactor.stop())
419
405
 
420
406
  # Return the first scraped content or None if empty
421
407
  return content[0] if content else None
@@ -654,7 +640,11 @@ def fetch_all(
654
640
  "COOKIES_ENABLED": True if cookies else False,
655
641
  "LOG_LEVEL": "WARNING", # Reduce log verbosity
656
642
  }
657
- content=fetch_scrapy(url, parser=parser, cookies=cookies, headers=headers, settings=settings)
643
+ content=fetch_scrapy(url,
644
+ parser=parser,
645
+ cookies=cookies,
646
+ headers=headers,
647
+ settings=settings)
658
648
  return parser, content
659
649
 
660
650
  except requests.RequestException as e:
@@ -561,8 +561,8 @@ def get_text(
561
561
  font=cv2.FONT_HERSHEY_SIMPLEX,# draw_box
562
562
  fontsize=8,# draw_box
563
563
  figsize=[10,10],
564
- box_color = (0, 255, 0), # draw_box
565
- fontcolor = (0, 0, 0),# draw_box
564
+ box_color = (0, 255, 0), # draw_box
565
+ fontcolor = (116,173,233), # draw_box
566
566
  bg_color=(133, 203, 245, 100),# draw_box
567
567
  usage=False,
568
568
  **kwargs,