android-notify 1.59.3__py3-none-any.whl → 1.60.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of android-notify might be problematic. Click here for more details.

Files changed (1351) hide show
  1. android_notify/__init__.py +4 -4
  2. android_notify/__main__.py +24 -0
  3. android_notify/an_types.py +226 -91
  4. android_notify/an_utils.py +129 -18
  5. android_notify/base.py +97 -90
  6. android_notify/config.py +145 -0
  7. android_notify/core.py +227 -139
  8. android_notify/styles.py +25 -22
  9. android_notify/sword.py +1043 -961
  10. {android_notify-1.59.3.dist-info → android_notify-1.60.0.dist-info}/METADATA +164 -119
  11. android_notify-1.60.0.dist-info/RECORD +1350 -0
  12. android_notify-1.60.0.dist-info/entry_points.txt +2 -0
  13. {android_notify-1.59.3.dist-info → android_notify-1.60.0.dist-info}/top_level.txt +2 -0
  14. docs/examples/flet-working/src/core.py +221 -0
  15. docs/examples/flet-working/src/main.py +68 -0
  16. docs/tests/flet/adv/main.py +97 -0
  17. docs/tests/flet/adv/tests/__init__.py +0 -0
  18. docs/tests/flet/adv/tests/test_android_notify_full.py +199 -0
  19. docs/tests/flet/basic/src/core.py +221 -0
  20. docs/tests/flet/basic/src/main.py +112 -0
  21. docs/website/src/pages/data/laner_Sent.py +24 -0
  22. venv/Lib/site-packages/__editable___android_notify_1_60_0_finder.py +85 -0
  23. venv/Lib/site-packages/build/__init__.py +39 -0
  24. venv/Lib/site-packages/build/__main__.py +486 -0
  25. venv/Lib/site-packages/build/_builder.py +355 -0
  26. venv/Lib/site-packages/build/_compat/__init__.py +0 -0
  27. venv/Lib/site-packages/build/_compat/importlib.py +22 -0
  28. venv/Lib/site-packages/build/_compat/tarfile.py +31 -0
  29. venv/Lib/site-packages/build/_compat/tomllib.py +16 -0
  30. venv/Lib/site-packages/build/_ctx.py +99 -0
  31. venv/Lib/site-packages/build/_exceptions.py +65 -0
  32. venv/Lib/site-packages/build/_types.py +19 -0
  33. venv/Lib/site-packages/build/_util.py +63 -0
  34. venv/Lib/site-packages/build/env.py +393 -0
  35. venv/Lib/site-packages/build/py.typed +0 -0
  36. venv/Lib/site-packages/build/util.py +63 -0
  37. venv/Lib/site-packages/certifi/__init__.py +4 -0
  38. venv/Lib/site-packages/certifi/__main__.py +12 -0
  39. venv/Lib/site-packages/certifi/core.py +83 -0
  40. venv/Lib/site-packages/certifi/py.typed +0 -0
  41. venv/Lib/site-packages/charset_normalizer/__init__.py +48 -0
  42. venv/Lib/site-packages/charset_normalizer/__main__.py +6 -0
  43. venv/Lib/site-packages/charset_normalizer/api.py +669 -0
  44. venv/Lib/site-packages/charset_normalizer/cd.py +395 -0
  45. venv/Lib/site-packages/charset_normalizer/cli/__init__.py +8 -0
  46. venv/Lib/site-packages/charset_normalizer/cli/__main__.py +381 -0
  47. venv/Lib/site-packages/charset_normalizer/constant.py +2015 -0
  48. venv/Lib/site-packages/charset_normalizer/legacy.py +80 -0
  49. venv/Lib/site-packages/charset_normalizer/md.py +635 -0
  50. venv/Lib/site-packages/charset_normalizer/models.py +360 -0
  51. venv/Lib/site-packages/charset_normalizer/py.typed +0 -0
  52. venv/Lib/site-packages/charset_normalizer/utils.py +414 -0
  53. venv/Lib/site-packages/charset_normalizer/version.py +8 -0
  54. venv/Lib/site-packages/colorama/__init__.py +7 -0
  55. venv/Lib/site-packages/colorama/ansi.py +102 -0
  56. venv/Lib/site-packages/colorama/ansitowin32.py +277 -0
  57. venv/Lib/site-packages/colorama/initialise.py +121 -0
  58. venv/Lib/site-packages/colorama/tests/__init__.py +1 -0
  59. venv/Lib/site-packages/colorama/tests/ansi_test.py +76 -0
  60. venv/Lib/site-packages/colorama/tests/ansitowin32_test.py +294 -0
  61. venv/Lib/site-packages/colorama/tests/initialise_test.py +189 -0
  62. venv/Lib/site-packages/colorama/tests/isatty_test.py +57 -0
  63. venv/Lib/site-packages/colorama/tests/utils.py +49 -0
  64. venv/Lib/site-packages/colorama/tests/winterm_test.py +131 -0
  65. venv/Lib/site-packages/colorama/win32.py +180 -0
  66. venv/Lib/site-packages/colorama/winterm.py +195 -0
  67. venv/Lib/site-packages/docutils/__init__.py +341 -0
  68. venv/Lib/site-packages/docutils/__main__.py +103 -0
  69. venv/Lib/site-packages/docutils/core.py +855 -0
  70. venv/Lib/site-packages/docutils/examples.py +123 -0
  71. venv/Lib/site-packages/docutils/frontend.py +1178 -0
  72. venv/Lib/site-packages/docutils/io.py +718 -0
  73. venv/Lib/site-packages/docutils/languages/__init__.py +117 -0
  74. venv/Lib/site-packages/docutils/languages/af.py +58 -0
  75. venv/Lib/site-packages/docutils/languages/ar.py +60 -0
  76. venv/Lib/site-packages/docutils/languages/ca.py +65 -0
  77. venv/Lib/site-packages/docutils/languages/cs.py +60 -0
  78. venv/Lib/site-packages/docutils/languages/da.py +61 -0
  79. venv/Lib/site-packages/docutils/languages/de.py +58 -0
  80. venv/Lib/site-packages/docutils/languages/en.py +60 -0
  81. venv/Lib/site-packages/docutils/languages/eo.py +61 -0
  82. venv/Lib/site-packages/docutils/languages/es.py +58 -0
  83. venv/Lib/site-packages/docutils/languages/fa.py +60 -0
  84. venv/Lib/site-packages/docutils/languages/fi.py +60 -0
  85. venv/Lib/site-packages/docutils/languages/fr.py +58 -0
  86. venv/Lib/site-packages/docutils/languages/gl.py +62 -0
  87. venv/Lib/site-packages/docutils/languages/he.py +62 -0
  88. venv/Lib/site-packages/docutils/languages/it.py +58 -0
  89. venv/Lib/site-packages/docutils/languages/ja.py +60 -0
  90. venv/Lib/site-packages/docutils/languages/ka.py +58 -0
  91. venv/Lib/site-packages/docutils/languages/ko.py +60 -0
  92. venv/Lib/site-packages/docutils/languages/lt.py +60 -0
  93. venv/Lib/site-packages/docutils/languages/lv.py +59 -0
  94. venv/Lib/site-packages/docutils/languages/nl.py +60 -0
  95. venv/Lib/site-packages/docutils/languages/pl.py +60 -0
  96. venv/Lib/site-packages/docutils/languages/pt_br.py +60 -0
  97. venv/Lib/site-packages/docutils/languages/ru.py +58 -0
  98. venv/Lib/site-packages/docutils/languages/sk.py +58 -0
  99. venv/Lib/site-packages/docutils/languages/sv.py +59 -0
  100. venv/Lib/site-packages/docutils/languages/uk.py +58 -0
  101. venv/Lib/site-packages/docutils/languages/zh_cn.py +62 -0
  102. venv/Lib/site-packages/docutils/languages/zh_tw.py +61 -0
  103. venv/Lib/site-packages/docutils/nodes.py +3341 -0
  104. venv/Lib/site-packages/docutils/parsers/__init__.py +115 -0
  105. venv/Lib/site-packages/docutils/parsers/commonmark_wrapper.py +56 -0
  106. venv/Lib/site-packages/docutils/parsers/docutils_xml.py +194 -0
  107. venv/Lib/site-packages/docutils/parsers/null.py +24 -0
  108. venv/Lib/site-packages/docutils/parsers/recommonmark_wrapper.py +174 -0
  109. venv/Lib/site-packages/docutils/parsers/rst/__init__.py +414 -0
  110. venv/Lib/site-packages/docutils/parsers/rst/directives/__init__.py +480 -0
  111. venv/Lib/site-packages/docutils/parsers/rst/directives/admonitions.py +101 -0
  112. venv/Lib/site-packages/docutils/parsers/rst/directives/body.py +318 -0
  113. venv/Lib/site-packages/docutils/parsers/rst/directives/html.py +21 -0
  114. venv/Lib/site-packages/docutils/parsers/rst/directives/images.py +186 -0
  115. venv/Lib/site-packages/docutils/parsers/rst/directives/misc.py +690 -0
  116. venv/Lib/site-packages/docutils/parsers/rst/directives/parts.py +126 -0
  117. venv/Lib/site-packages/docutils/parsers/rst/directives/references.py +28 -0
  118. venv/Lib/site-packages/docutils/parsers/rst/directives/tables.py +523 -0
  119. venv/Lib/site-packages/docutils/parsers/rst/languages/__init__.py +63 -0
  120. venv/Lib/site-packages/docutils/parsers/rst/languages/af.py +107 -0
  121. venv/Lib/site-packages/docutils/parsers/rst/languages/ar.py +99 -0
  122. venv/Lib/site-packages/docutils/parsers/rst/languages/ca.py +130 -0
  123. venv/Lib/site-packages/docutils/parsers/rst/languages/cs.py +110 -0
  124. venv/Lib/site-packages/docutils/parsers/rst/languages/da.py +113 -0
  125. venv/Lib/site-packages/docutils/parsers/rst/languages/de.py +106 -0
  126. venv/Lib/site-packages/docutils/parsers/rst/languages/en.py +115 -0
  127. venv/Lib/site-packages/docutils/parsers/rst/languages/eo.py +118 -0
  128. venv/Lib/site-packages/docutils/parsers/rst/languages/es.py +121 -0
  129. venv/Lib/site-packages/docutils/parsers/rst/languages/fa.py +102 -0
  130. venv/Lib/site-packages/docutils/parsers/rst/languages/fi.py +98 -0
  131. venv/Lib/site-packages/docutils/parsers/rst/languages/fr.py +107 -0
  132. venv/Lib/site-packages/docutils/parsers/rst/languages/gl.py +106 -0
  133. venv/Lib/site-packages/docutils/parsers/rst/languages/he.py +110 -0
  134. venv/Lib/site-packages/docutils/parsers/rst/languages/it.py +98 -0
  135. venv/Lib/site-packages/docutils/parsers/rst/languages/ja.py +119 -0
  136. venv/Lib/site-packages/docutils/parsers/rst/languages/ka.py +89 -0
  137. venv/Lib/site-packages/docutils/parsers/rst/languages/ko.py +111 -0
  138. venv/Lib/site-packages/docutils/parsers/rst/languages/lt.py +109 -0
  139. venv/Lib/site-packages/docutils/parsers/rst/languages/lv.py +108 -0
  140. venv/Lib/site-packages/docutils/parsers/rst/languages/nl.py +113 -0
  141. venv/Lib/site-packages/docutils/parsers/rst/languages/pl.py +100 -0
  142. venv/Lib/site-packages/docutils/parsers/rst/languages/pt_br.py +109 -0
  143. venv/Lib/site-packages/docutils/parsers/rst/languages/ru.py +90 -0
  144. venv/Lib/site-packages/docutils/parsers/rst/languages/sk.py +96 -0
  145. venv/Lib/site-packages/docutils/parsers/rst/languages/sv.py +96 -0
  146. venv/Lib/site-packages/docutils/parsers/rst/languages/uk.py +91 -0
  147. venv/Lib/site-packages/docutils/parsers/rst/languages/zh_cn.py +104 -0
  148. venv/Lib/site-packages/docutils/parsers/rst/languages/zh_tw.py +109 -0
  149. venv/Lib/site-packages/docutils/parsers/rst/roles.py +450 -0
  150. venv/Lib/site-packages/docutils/parsers/rst/states.py +3255 -0
  151. venv/Lib/site-packages/docutils/parsers/rst/tableparser.py +540 -0
  152. venv/Lib/site-packages/docutils/readers/__init__.py +135 -0
  153. venv/Lib/site-packages/docutils/readers/doctree.py +50 -0
  154. venv/Lib/site-packages/docutils/readers/pep.py +55 -0
  155. venv/Lib/site-packages/docutils/readers/standalone.py +65 -0
  156. venv/Lib/site-packages/docutils/statemachine.py +1534 -0
  157. venv/Lib/site-packages/docutils/transforms/__init__.py +196 -0
  158. venv/Lib/site-packages/docutils/transforms/components.py +56 -0
  159. venv/Lib/site-packages/docutils/transforms/frontmatter.py +548 -0
  160. venv/Lib/site-packages/docutils/transforms/misc.py +151 -0
  161. venv/Lib/site-packages/docutils/transforms/parts.py +175 -0
  162. venv/Lib/site-packages/docutils/transforms/peps.py +315 -0
  163. venv/Lib/site-packages/docutils/transforms/references.py +990 -0
  164. venv/Lib/site-packages/docutils/transforms/universal.py +364 -0
  165. venv/Lib/site-packages/docutils/transforms/writer_aux.py +57 -0
  166. venv/Lib/site-packages/docutils/utils/__init__.py +853 -0
  167. venv/Lib/site-packages/docutils/utils/_roman_numerals.py +264 -0
  168. venv/Lib/site-packages/docutils/utils/_typing.py +39 -0
  169. venv/Lib/site-packages/docutils/utils/code_analyzer.py +140 -0
  170. venv/Lib/site-packages/docutils/utils/math/__init__.py +77 -0
  171. venv/Lib/site-packages/docutils/utils/math/latex2mathml.py +1252 -0
  172. venv/Lib/site-packages/docutils/utils/math/math2html.py +3166 -0
  173. venv/Lib/site-packages/docutils/utils/math/mathalphabet2unichar.py +892 -0
  174. venv/Lib/site-packages/docutils/utils/math/mathml_elements.py +482 -0
  175. venv/Lib/site-packages/docutils/utils/math/tex2mathml_extern.py +263 -0
  176. venv/Lib/site-packages/docutils/utils/math/tex2unichar.py +730 -0
  177. venv/Lib/site-packages/docutils/utils/math/unichar2tex.py +808 -0
  178. venv/Lib/site-packages/docutils/utils/punctuation_chars.py +123 -0
  179. venv/Lib/site-packages/docutils/utils/smartquotes.py +1006 -0
  180. venv/Lib/site-packages/docutils/utils/urischemes.py +138 -0
  181. venv/Lib/site-packages/docutils/writers/__init__.py +277 -0
  182. venv/Lib/site-packages/docutils/writers/_html_base.py +1885 -0
  183. venv/Lib/site-packages/docutils/writers/docutils_xml.py +191 -0
  184. venv/Lib/site-packages/docutils/writers/html4css1/__init__.py +964 -0
  185. venv/Lib/site-packages/docutils/writers/html5_polyglot/__init__.py +396 -0
  186. venv/Lib/site-packages/docutils/writers/latex2e/__init__.py +3419 -0
  187. venv/Lib/site-packages/docutils/writers/manpage.py +1353 -0
  188. venv/Lib/site-packages/docutils/writers/null.py +28 -0
  189. venv/Lib/site-packages/docutils/writers/odf_odt/__init__.py +3461 -0
  190. venv/Lib/site-packages/docutils/writers/odf_odt/prepstyles.py +80 -0
  191. venv/Lib/site-packages/docutils/writers/odf_odt/pygmentsformatter.py +106 -0
  192. venv/Lib/site-packages/docutils/writers/pep_html/__init__.py +102 -0
  193. venv/Lib/site-packages/docutils/writers/pseudoxml.py +41 -0
  194. venv/Lib/site-packages/docutils/writers/s5_html/__init__.py +354 -0
  195. venv/Lib/site-packages/docutils/writers/xetex/__init__.py +168 -0
  196. venv/Lib/site-packages/id/__init__.py +91 -0
  197. venv/Lib/site-packages/id/__main__.py +88 -0
  198. venv/Lib/site-packages/id/_internal/oidc/__init__.py +13 -0
  199. venv/Lib/site-packages/id/_internal/oidc/ambient.py +328 -0
  200. venv/Lib/site-packages/idna/__init__.py +45 -0
  201. venv/Lib/site-packages/idna/codec.py +122 -0
  202. venv/Lib/site-packages/idna/compat.py +15 -0
  203. venv/Lib/site-packages/idna/core.py +437 -0
  204. venv/Lib/site-packages/idna/idnadata.py +4309 -0
  205. venv/Lib/site-packages/idna/intranges.py +57 -0
  206. venv/Lib/site-packages/idna/package_data.py +1 -0
  207. venv/Lib/site-packages/idna/py.typed +0 -0
  208. venv/Lib/site-packages/idna/uts46data.py +8841 -0
  209. venv/Lib/site-packages/jaraco/classes/__init__.py +0 -0
  210. venv/Lib/site-packages/jaraco/classes/ancestry.py +76 -0
  211. venv/Lib/site-packages/jaraco/classes/meta.py +85 -0
  212. venv/Lib/site-packages/jaraco/classes/properties.py +241 -0
  213. venv/Lib/site-packages/jaraco/classes/py.typed +0 -0
  214. venv/Lib/site-packages/jaraco/context/__init__.py +356 -0
  215. venv/Lib/site-packages/jaraco/context/py.typed +0 -0
  216. venv/Lib/site-packages/jaraco/functools/__init__.py +714 -0
  217. venv/Lib/site-packages/jaraco/functools/__init__.pyi +123 -0
  218. venv/Lib/site-packages/jaraco/functools/py.typed +0 -0
  219. venv/Lib/site-packages/jnius/__init__.py +89 -0
  220. venv/Lib/site-packages/jnius/env.py +378 -0
  221. venv/Lib/site-packages/jnius/reflect.py +440 -0
  222. venv/Lib/site-packages/jnius/signatures.py +105 -0
  223. venv/Lib/site-packages/jnius_config.py +112 -0
  224. venv/Lib/site-packages/keyring/__init__.py +17 -0
  225. venv/Lib/site-packages/keyring/__main__.py +4 -0
  226. venv/Lib/site-packages/keyring/backend.py +300 -0
  227. venv/Lib/site-packages/keyring/backends/SecretService.py +120 -0
  228. venv/Lib/site-packages/keyring/backends/Windows.py +168 -0
  229. venv/Lib/site-packages/keyring/backends/__init__.py +0 -0
  230. venv/Lib/site-packages/keyring/backends/chainer.py +71 -0
  231. venv/Lib/site-packages/keyring/backends/fail.py +30 -0
  232. venv/Lib/site-packages/keyring/backends/kwallet.py +164 -0
  233. venv/Lib/site-packages/keyring/backends/libsecret.py +155 -0
  234. venv/Lib/site-packages/keyring/backends/macOS/__init__.py +85 -0
  235. venv/Lib/site-packages/keyring/backends/macOS/api.py +184 -0
  236. venv/Lib/site-packages/keyring/backends/null.py +20 -0
  237. venv/Lib/site-packages/keyring/cli.py +220 -0
  238. venv/Lib/site-packages/keyring/compat/__init__.py +7 -0
  239. venv/Lib/site-packages/keyring/compat/properties.py +169 -0
  240. venv/Lib/site-packages/keyring/compat/py312.py +9 -0
  241. venv/Lib/site-packages/keyring/compat/py38.py +9 -0
  242. venv/Lib/site-packages/keyring/completion.py +56 -0
  243. venv/Lib/site-packages/keyring/core.py +200 -0
  244. venv/Lib/site-packages/keyring/credentials.py +85 -0
  245. venv/Lib/site-packages/keyring/devpi_client.py +29 -0
  246. venv/Lib/site-packages/keyring/errors.py +67 -0
  247. venv/Lib/site-packages/keyring/http.py +39 -0
  248. venv/Lib/site-packages/keyring/py.typed +0 -0
  249. venv/Lib/site-packages/keyring/testing/__init__.py +0 -0
  250. venv/Lib/site-packages/keyring/testing/backend.py +200 -0
  251. venv/Lib/site-packages/keyring/testing/util.py +68 -0
  252. venv/Lib/site-packages/keyring/util/__init__.py +11 -0
  253. venv/Lib/site-packages/keyring/util/platform_.py +40 -0
  254. venv/Lib/site-packages/markdown_it/__init__.py +6 -0
  255. venv/Lib/site-packages/markdown_it/_compat.py +1 -0
  256. venv/Lib/site-packages/markdown_it/_punycode.py +67 -0
  257. venv/Lib/site-packages/markdown_it/cli/__init__.py +0 -0
  258. venv/Lib/site-packages/markdown_it/cli/parse.py +110 -0
  259. venv/Lib/site-packages/markdown_it/common/__init__.py +0 -0
  260. venv/Lib/site-packages/markdown_it/common/entities.py +5 -0
  261. venv/Lib/site-packages/markdown_it/common/html_blocks.py +69 -0
  262. venv/Lib/site-packages/markdown_it/common/html_re.py +39 -0
  263. venv/Lib/site-packages/markdown_it/common/normalize_url.py +81 -0
  264. venv/Lib/site-packages/markdown_it/common/utils.py +313 -0
  265. venv/Lib/site-packages/markdown_it/helpers/__init__.py +6 -0
  266. venv/Lib/site-packages/markdown_it/helpers/parse_link_destination.py +83 -0
  267. venv/Lib/site-packages/markdown_it/helpers/parse_link_label.py +44 -0
  268. venv/Lib/site-packages/markdown_it/helpers/parse_link_title.py +75 -0
  269. venv/Lib/site-packages/markdown_it/main.py +350 -0
  270. venv/Lib/site-packages/markdown_it/parser_block.py +113 -0
  271. venv/Lib/site-packages/markdown_it/parser_core.py +46 -0
  272. venv/Lib/site-packages/markdown_it/parser_inline.py +148 -0
  273. venv/Lib/site-packages/markdown_it/presets/__init__.py +28 -0
  274. venv/Lib/site-packages/markdown_it/presets/commonmark.py +75 -0
  275. venv/Lib/site-packages/markdown_it/presets/default.py +36 -0
  276. venv/Lib/site-packages/markdown_it/presets/zero.py +44 -0
  277. venv/Lib/site-packages/markdown_it/py.typed +1 -0
  278. venv/Lib/site-packages/markdown_it/renderer.py +336 -0
  279. venv/Lib/site-packages/markdown_it/ruler.py +275 -0
  280. venv/Lib/site-packages/markdown_it/rules_block/__init__.py +27 -0
  281. venv/Lib/site-packages/markdown_it/rules_block/blockquote.py +299 -0
  282. venv/Lib/site-packages/markdown_it/rules_block/code.py +36 -0
  283. venv/Lib/site-packages/markdown_it/rules_block/fence.py +101 -0
  284. venv/Lib/site-packages/markdown_it/rules_block/heading.py +69 -0
  285. venv/Lib/site-packages/markdown_it/rules_block/hr.py +56 -0
  286. venv/Lib/site-packages/markdown_it/rules_block/html_block.py +90 -0
  287. venv/Lib/site-packages/markdown_it/rules_block/lheading.py +86 -0
  288. venv/Lib/site-packages/markdown_it/rules_block/list.py +345 -0
  289. venv/Lib/site-packages/markdown_it/rules_block/paragraph.py +66 -0
  290. venv/Lib/site-packages/markdown_it/rules_block/reference.py +235 -0
  291. venv/Lib/site-packages/markdown_it/rules_block/state_block.py +261 -0
  292. venv/Lib/site-packages/markdown_it/rules_block/table.py +250 -0
  293. venv/Lib/site-packages/markdown_it/rules_core/__init__.py +19 -0
  294. venv/Lib/site-packages/markdown_it/rules_core/block.py +13 -0
  295. venv/Lib/site-packages/markdown_it/rules_core/inline.py +10 -0
  296. venv/Lib/site-packages/markdown_it/rules_core/linkify.py +149 -0
  297. venv/Lib/site-packages/markdown_it/rules_core/normalize.py +19 -0
  298. venv/Lib/site-packages/markdown_it/rules_core/replacements.py +127 -0
  299. venv/Lib/site-packages/markdown_it/rules_core/smartquotes.py +202 -0
  300. venv/Lib/site-packages/markdown_it/rules_core/state_core.py +25 -0
  301. venv/Lib/site-packages/markdown_it/rules_core/text_join.py +35 -0
  302. venv/Lib/site-packages/markdown_it/rules_inline/__init__.py +31 -0
  303. venv/Lib/site-packages/markdown_it/rules_inline/autolink.py +77 -0
  304. venv/Lib/site-packages/markdown_it/rules_inline/backticks.py +72 -0
  305. venv/Lib/site-packages/markdown_it/rules_inline/balance_pairs.py +138 -0
  306. venv/Lib/site-packages/markdown_it/rules_inline/emphasis.py +102 -0
  307. venv/Lib/site-packages/markdown_it/rules_inline/entity.py +53 -0
  308. venv/Lib/site-packages/markdown_it/rules_inline/escape.py +93 -0
  309. venv/Lib/site-packages/markdown_it/rules_inline/fragments_join.py +43 -0
  310. venv/Lib/site-packages/markdown_it/rules_inline/html_inline.py +43 -0
  311. venv/Lib/site-packages/markdown_it/rules_inline/image.py +148 -0
  312. venv/Lib/site-packages/markdown_it/rules_inline/link.py +149 -0
  313. venv/Lib/site-packages/markdown_it/rules_inline/linkify.py +62 -0
  314. venv/Lib/site-packages/markdown_it/rules_inline/newline.py +44 -0
  315. venv/Lib/site-packages/markdown_it/rules_inline/state_inline.py +165 -0
  316. venv/Lib/site-packages/markdown_it/rules_inline/strikethrough.py +127 -0
  317. venv/Lib/site-packages/markdown_it/rules_inline/text.py +62 -0
  318. venv/Lib/site-packages/markdown_it/token.py +178 -0
  319. venv/Lib/site-packages/markdown_it/tree.py +333 -0
  320. venv/Lib/site-packages/markdown_it/utils.py +186 -0
  321. venv/Lib/site-packages/mdurl/__init__.py +18 -0
  322. venv/Lib/site-packages/mdurl/_decode.py +104 -0
  323. venv/Lib/site-packages/mdurl/_encode.py +85 -0
  324. venv/Lib/site-packages/mdurl/_format.py +27 -0
  325. venv/Lib/site-packages/mdurl/_parse.py +304 -0
  326. venv/Lib/site-packages/mdurl/_url.py +14 -0
  327. venv/Lib/site-packages/mdurl/py.typed +1 -0
  328. venv/Lib/site-packages/more_itertools/__init__.py +6 -0
  329. venv/Lib/site-packages/more_itertools/__init__.pyi +2 -0
  330. venv/Lib/site-packages/more_itertools/more.py +5303 -0
  331. venv/Lib/site-packages/more_itertools/more.pyi +949 -0
  332. venv/Lib/site-packages/more_itertools/py.typed +0 -0
  333. venv/Lib/site-packages/more_itertools/recipes.py +1471 -0
  334. venv/Lib/site-packages/more_itertools/recipes.pyi +205 -0
  335. venv/Lib/site-packages/nh3/__init__.py +5 -0
  336. venv/Lib/site-packages/nh3/__init__.pyi +41 -0
  337. venv/Lib/site-packages/nh3/py.typed +0 -0
  338. venv/Lib/site-packages/packaging/__init__.py +15 -0
  339. venv/Lib/site-packages/packaging/_elffile.py +109 -0
  340. venv/Lib/site-packages/packaging/_manylinux.py +262 -0
  341. venv/Lib/site-packages/packaging/_musllinux.py +85 -0
  342. venv/Lib/site-packages/packaging/_parser.py +353 -0
  343. venv/Lib/site-packages/packaging/_structures.py +61 -0
  344. venv/Lib/site-packages/packaging/_tokenizer.py +195 -0
  345. venv/Lib/site-packages/packaging/licenses/__init__.py +145 -0
  346. venv/Lib/site-packages/packaging/licenses/_spdx.py +759 -0
  347. venv/Lib/site-packages/packaging/markers.py +362 -0
  348. venv/Lib/site-packages/packaging/metadata.py +862 -0
  349. venv/Lib/site-packages/packaging/py.typed +0 -0
  350. venv/Lib/site-packages/packaging/requirements.py +91 -0
  351. venv/Lib/site-packages/packaging/specifiers.py +1019 -0
  352. venv/Lib/site-packages/packaging/tags.py +656 -0
  353. venv/Lib/site-packages/packaging/utils.py +163 -0
  354. venv/Lib/site-packages/packaging/version.py +582 -0
  355. venv/Lib/site-packages/pip/__init__.py +13 -0
  356. venv/Lib/site-packages/pip/__main__.py +24 -0
  357. venv/Lib/site-packages/pip/__pip-runner__.py +50 -0
  358. venv/Lib/site-packages/pip/_internal/__init__.py +18 -0
  359. venv/Lib/site-packages/pip/_internal/build_env.py +417 -0
  360. venv/Lib/site-packages/pip/_internal/cache.py +291 -0
  361. venv/Lib/site-packages/pip/_internal/cli/__init__.py +3 -0
  362. venv/Lib/site-packages/pip/_internal/cli/autocompletion.py +184 -0
  363. venv/Lib/site-packages/pip/_internal/cli/base_command.py +244 -0
  364. venv/Lib/site-packages/pip/_internal/cli/cmdoptions.py +1110 -0
  365. venv/Lib/site-packages/pip/_internal/cli/command_context.py +28 -0
  366. venv/Lib/site-packages/pip/_internal/cli/index_command.py +175 -0
  367. venv/Lib/site-packages/pip/_internal/cli/main.py +80 -0
  368. venv/Lib/site-packages/pip/_internal/cli/main_parser.py +134 -0
  369. venv/Lib/site-packages/pip/_internal/cli/parser.py +298 -0
  370. venv/Lib/site-packages/pip/_internal/cli/progress_bars.py +151 -0
  371. venv/Lib/site-packages/pip/_internal/cli/req_command.py +371 -0
  372. venv/Lib/site-packages/pip/_internal/cli/spinners.py +235 -0
  373. venv/Lib/site-packages/pip/_internal/cli/status_codes.py +6 -0
  374. venv/Lib/site-packages/pip/_internal/commands/__init__.py +139 -0
  375. venv/Lib/site-packages/pip/_internal/commands/cache.py +231 -0
  376. venv/Lib/site-packages/pip/_internal/commands/check.py +66 -0
  377. venv/Lib/site-packages/pip/_internal/commands/completion.py +135 -0
  378. venv/Lib/site-packages/pip/_internal/commands/configuration.py +288 -0
  379. venv/Lib/site-packages/pip/_internal/commands/debug.py +203 -0
  380. venv/Lib/site-packages/pip/_internal/commands/download.py +142 -0
  381. venv/Lib/site-packages/pip/_internal/commands/freeze.py +107 -0
  382. venv/Lib/site-packages/pip/_internal/commands/hash.py +58 -0
  383. venv/Lib/site-packages/pip/_internal/commands/help.py +40 -0
  384. venv/Lib/site-packages/pip/_internal/commands/index.py +159 -0
  385. venv/Lib/site-packages/pip/_internal/commands/inspect.py +92 -0
  386. venv/Lib/site-packages/pip/_internal/commands/install.py +803 -0
  387. venv/Lib/site-packages/pip/_internal/commands/list.py +400 -0
  388. venv/Lib/site-packages/pip/_internal/commands/lock.py +167 -0
  389. venv/Lib/site-packages/pip/_internal/commands/search.py +178 -0
  390. venv/Lib/site-packages/pip/_internal/commands/show.py +231 -0
  391. venv/Lib/site-packages/pip/_internal/commands/uninstall.py +113 -0
  392. venv/Lib/site-packages/pip/_internal/commands/wheel.py +176 -0
  393. venv/Lib/site-packages/pip/_internal/configuration.py +396 -0
  394. venv/Lib/site-packages/pip/_internal/distributions/__init__.py +21 -0
  395. venv/Lib/site-packages/pip/_internal/distributions/base.py +55 -0
  396. venv/Lib/site-packages/pip/_internal/distributions/installed.py +33 -0
  397. venv/Lib/site-packages/pip/_internal/distributions/sdist.py +164 -0
  398. venv/Lib/site-packages/pip/_internal/distributions/wheel.py +44 -0
  399. venv/Lib/site-packages/pip/_internal/exceptions.py +898 -0
  400. venv/Lib/site-packages/pip/_internal/index/__init__.py +1 -0
  401. venv/Lib/site-packages/pip/_internal/index/collector.py +489 -0
  402. venv/Lib/site-packages/pip/_internal/index/package_finder.py +1059 -0
  403. venv/Lib/site-packages/pip/_internal/index/sources.py +287 -0
  404. venv/Lib/site-packages/pip/_internal/locations/__init__.py +441 -0
  405. venv/Lib/site-packages/pip/_internal/locations/_distutils.py +173 -0
  406. venv/Lib/site-packages/pip/_internal/locations/_sysconfig.py +215 -0
  407. venv/Lib/site-packages/pip/_internal/locations/base.py +82 -0
  408. venv/Lib/site-packages/pip/_internal/main.py +12 -0
  409. venv/Lib/site-packages/pip/_internal/metadata/__init__.py +169 -0
  410. venv/Lib/site-packages/pip/_internal/metadata/_json.py +87 -0
  411. venv/Lib/site-packages/pip/_internal/metadata/base.py +685 -0
  412. venv/Lib/site-packages/pip/_internal/metadata/importlib/__init__.py +6 -0
  413. venv/Lib/site-packages/pip/_internal/metadata/importlib/_compat.py +87 -0
  414. venv/Lib/site-packages/pip/_internal/metadata/importlib/_dists.py +229 -0
  415. venv/Lib/site-packages/pip/_internal/metadata/importlib/_envs.py +143 -0
  416. venv/Lib/site-packages/pip/_internal/metadata/pkg_resources.py +298 -0
  417. venv/Lib/site-packages/pip/_internal/models/__init__.py +1 -0
  418. venv/Lib/site-packages/pip/_internal/models/candidate.py +25 -0
  419. venv/Lib/site-packages/pip/_internal/models/direct_url.py +227 -0
  420. venv/Lib/site-packages/pip/_internal/models/format_control.py +78 -0
  421. venv/Lib/site-packages/pip/_internal/models/index.py +28 -0
  422. venv/Lib/site-packages/pip/_internal/models/installation_report.py +57 -0
  423. venv/Lib/site-packages/pip/_internal/models/link.py +613 -0
  424. venv/Lib/site-packages/pip/_internal/models/pylock.py +188 -0
  425. venv/Lib/site-packages/pip/_internal/models/scheme.py +25 -0
  426. venv/Lib/site-packages/pip/_internal/models/search_scope.py +126 -0
  427. venv/Lib/site-packages/pip/_internal/models/selection_prefs.py +53 -0
  428. venv/Lib/site-packages/pip/_internal/models/target_python.py +122 -0
  429. venv/Lib/site-packages/pip/_internal/models/wheel.py +80 -0
  430. venv/Lib/site-packages/pip/_internal/network/__init__.py +1 -0
  431. venv/Lib/site-packages/pip/_internal/network/auth.py +564 -0
  432. venv/Lib/site-packages/pip/_internal/network/cache.py +128 -0
  433. venv/Lib/site-packages/pip/_internal/network/download.py +342 -0
  434. venv/Lib/site-packages/pip/_internal/network/lazy_wheel.py +215 -0
  435. venv/Lib/site-packages/pip/_internal/network/session.py +528 -0
  436. venv/Lib/site-packages/pip/_internal/network/utils.py +98 -0
  437. venv/Lib/site-packages/pip/_internal/network/xmlrpc.py +61 -0
  438. venv/Lib/site-packages/pip/_internal/operations/__init__.py +0 -0
  439. venv/Lib/site-packages/pip/_internal/operations/build/__init__.py +0 -0
  440. venv/Lib/site-packages/pip/_internal/operations/build/build_tracker.py +140 -0
  441. venv/Lib/site-packages/pip/_internal/operations/build/metadata.py +38 -0
  442. venv/Lib/site-packages/pip/_internal/operations/build/metadata_editable.py +41 -0
  443. venv/Lib/site-packages/pip/_internal/operations/build/wheel.py +38 -0
  444. venv/Lib/site-packages/pip/_internal/operations/build/wheel_editable.py +47 -0
  445. venv/Lib/site-packages/pip/_internal/operations/check.py +175 -0
  446. venv/Lib/site-packages/pip/_internal/operations/freeze.py +259 -0
  447. venv/Lib/site-packages/pip/_internal/operations/install/__init__.py +1 -0
  448. venv/Lib/site-packages/pip/_internal/operations/install/wheel.py +746 -0
  449. venv/Lib/site-packages/pip/_internal/operations/prepare.py +748 -0
  450. venv/Lib/site-packages/pip/_internal/pyproject.py +123 -0
  451. venv/Lib/site-packages/pip/_internal/req/__init__.py +103 -0
  452. venv/Lib/site-packages/pip/_internal/req/constructors.py +566 -0
  453. venv/Lib/site-packages/pip/_internal/req/req_dependency_group.py +75 -0
  454. venv/Lib/site-packages/pip/_internal/req/req_file.py +619 -0
  455. venv/Lib/site-packages/pip/_internal/req/req_install.py +828 -0
  456. venv/Lib/site-packages/pip/_internal/req/req_set.py +81 -0
  457. venv/Lib/site-packages/pip/_internal/req/req_uninstall.py +639 -0
  458. venv/Lib/site-packages/pip/_internal/resolution/__init__.py +0 -0
  459. venv/Lib/site-packages/pip/_internal/resolution/base.py +20 -0
  460. venv/Lib/site-packages/pip/_internal/resolution/legacy/__init__.py +0 -0
  461. venv/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py +598 -0
  462. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__init__.py +0 -0
  463. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py +142 -0
  464. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py +591 -0
  465. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py +845 -0
  466. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py +166 -0
  467. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py +285 -0
  468. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/reporter.py +98 -0
  469. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/requirements.py +247 -0
  470. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py +332 -0
  471. venv/Lib/site-packages/pip/_internal/self_outdated_check.py +262 -0
  472. venv/Lib/site-packages/pip/_internal/utils/__init__.py +0 -0
  473. venv/Lib/site-packages/pip/_internal/utils/_jaraco_text.py +109 -0
  474. venv/Lib/site-packages/pip/_internal/utils/_log.py +38 -0
  475. venv/Lib/site-packages/pip/_internal/utils/appdirs.py +52 -0
  476. venv/Lib/site-packages/pip/_internal/utils/compat.py +85 -0
  477. venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py +201 -0
  478. venv/Lib/site-packages/pip/_internal/utils/datetime.py +10 -0
  479. venv/Lib/site-packages/pip/_internal/utils/deprecation.py +126 -0
  480. venv/Lib/site-packages/pip/_internal/utils/direct_url_helpers.py +87 -0
  481. venv/Lib/site-packages/pip/_internal/utils/egg_link.py +81 -0
  482. venv/Lib/site-packages/pip/_internal/utils/entrypoints.py +88 -0
  483. venv/Lib/site-packages/pip/_internal/utils/filesystem.py +164 -0
  484. venv/Lib/site-packages/pip/_internal/utils/filetypes.py +24 -0
  485. venv/Lib/site-packages/pip/_internal/utils/glibc.py +102 -0
  486. venv/Lib/site-packages/pip/_internal/utils/hashes.py +150 -0
  487. venv/Lib/site-packages/pip/_internal/utils/logging.py +364 -0
  488. venv/Lib/site-packages/pip/_internal/utils/misc.py +765 -0
  489. venv/Lib/site-packages/pip/_internal/utils/packaging.py +44 -0
  490. venv/Lib/site-packages/pip/_internal/utils/retry.py +45 -0
  491. venv/Lib/site-packages/pip/_internal/utils/subprocess.py +248 -0
  492. venv/Lib/site-packages/pip/_internal/utils/temp_dir.py +294 -0
  493. venv/Lib/site-packages/pip/_internal/utils/unpacking.py +362 -0
  494. venv/Lib/site-packages/pip/_internal/utils/urls.py +55 -0
  495. venv/Lib/site-packages/pip/_internal/utils/virtualenv.py +105 -0
  496. venv/Lib/site-packages/pip/_internal/utils/wheel.py +132 -0
  497. venv/Lib/site-packages/pip/_internal/vcs/__init__.py +15 -0
  498. venv/Lib/site-packages/pip/_internal/vcs/bazaar.py +130 -0
  499. venv/Lib/site-packages/pip/_internal/vcs/git.py +571 -0
  500. venv/Lib/site-packages/pip/_internal/vcs/mercurial.py +186 -0
  501. venv/Lib/site-packages/pip/_internal/vcs/subversion.py +335 -0
  502. venv/Lib/site-packages/pip/_internal/vcs/versioncontrol.py +693 -0
  503. venv/Lib/site-packages/pip/_internal/wheel_builder.py +261 -0
  504. venv/Lib/site-packages/pip/_vendor/__init__.py +117 -0
  505. venv/Lib/site-packages/pip/_vendor/cachecontrol/__init__.py +29 -0
  506. venv/Lib/site-packages/pip/_vendor/cachecontrol/_cmd.py +70 -0
  507. venv/Lib/site-packages/pip/_vendor/cachecontrol/adapter.py +168 -0
  508. venv/Lib/site-packages/pip/_vendor/cachecontrol/cache.py +75 -0
  509. venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__init__.py +8 -0
  510. venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py +145 -0
  511. venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py +48 -0
  512. venv/Lib/site-packages/pip/_vendor/cachecontrol/controller.py +511 -0
  513. venv/Lib/site-packages/pip/_vendor/cachecontrol/filewrapper.py +119 -0
  514. venv/Lib/site-packages/pip/_vendor/cachecontrol/heuristics.py +157 -0
  515. venv/Lib/site-packages/pip/_vendor/cachecontrol/py.typed +0 -0
  516. venv/Lib/site-packages/pip/_vendor/cachecontrol/serialize.py +146 -0
  517. venv/Lib/site-packages/pip/_vendor/cachecontrol/wrapper.py +43 -0
  518. venv/Lib/site-packages/pip/_vendor/certifi/__init__.py +4 -0
  519. venv/Lib/site-packages/pip/_vendor/certifi/__main__.py +12 -0
  520. venv/Lib/site-packages/pip/_vendor/certifi/core.py +83 -0
  521. venv/Lib/site-packages/pip/_vendor/certifi/py.typed +0 -0
  522. venv/Lib/site-packages/pip/_vendor/dependency_groups/__init__.py +13 -0
  523. venv/Lib/site-packages/pip/_vendor/dependency_groups/__main__.py +65 -0
  524. venv/Lib/site-packages/pip/_vendor/dependency_groups/_implementation.py +209 -0
  525. venv/Lib/site-packages/pip/_vendor/dependency_groups/_lint_dependency_groups.py +59 -0
  526. venv/Lib/site-packages/pip/_vendor/dependency_groups/_pip_wrapper.py +62 -0
  527. venv/Lib/site-packages/pip/_vendor/dependency_groups/_toml_compat.py +9 -0
  528. venv/Lib/site-packages/pip/_vendor/dependency_groups/py.typed +0 -0
  529. venv/Lib/site-packages/pip/_vendor/distlib/__init__.py +33 -0
  530. venv/Lib/site-packages/pip/_vendor/distlib/compat.py +1137 -0
  531. venv/Lib/site-packages/pip/_vendor/distlib/resources.py +358 -0
  532. venv/Lib/site-packages/pip/_vendor/distlib/scripts.py +447 -0
  533. venv/Lib/site-packages/pip/_vendor/distlib/util.py +1984 -0
  534. venv/Lib/site-packages/pip/_vendor/distro/__init__.py +54 -0
  535. venv/Lib/site-packages/pip/_vendor/distro/__main__.py +4 -0
  536. venv/Lib/site-packages/pip/_vendor/distro/distro.py +1403 -0
  537. venv/Lib/site-packages/pip/_vendor/distro/py.typed +0 -0
  538. venv/Lib/site-packages/pip/_vendor/idna/__init__.py +45 -0
  539. venv/Lib/site-packages/pip/_vendor/idna/codec.py +122 -0
  540. venv/Lib/site-packages/pip/_vendor/idna/compat.py +15 -0
  541. venv/Lib/site-packages/pip/_vendor/idna/core.py +437 -0
  542. venv/Lib/site-packages/pip/_vendor/idna/idnadata.py +4243 -0
  543. venv/Lib/site-packages/pip/_vendor/idna/intranges.py +57 -0
  544. venv/Lib/site-packages/pip/_vendor/idna/package_data.py +1 -0
  545. venv/Lib/site-packages/pip/_vendor/idna/py.typed +0 -0
  546. venv/Lib/site-packages/pip/_vendor/idna/uts46data.py +8681 -0
  547. venv/Lib/site-packages/pip/_vendor/msgpack/__init__.py +55 -0
  548. venv/Lib/site-packages/pip/_vendor/msgpack/exceptions.py +48 -0
  549. venv/Lib/site-packages/pip/_vendor/msgpack/ext.py +170 -0
  550. venv/Lib/site-packages/pip/_vendor/msgpack/fallback.py +929 -0
  551. venv/Lib/site-packages/pip/_vendor/packaging/__init__.py +15 -0
  552. venv/Lib/site-packages/pip/_vendor/packaging/_elffile.py +109 -0
  553. venv/Lib/site-packages/pip/_vendor/packaging/_manylinux.py +262 -0
  554. venv/Lib/site-packages/pip/_vendor/packaging/_musllinux.py +85 -0
  555. venv/Lib/site-packages/pip/_vendor/packaging/_parser.py +353 -0
  556. venv/Lib/site-packages/pip/_vendor/packaging/_structures.py +61 -0
  557. venv/Lib/site-packages/pip/_vendor/packaging/_tokenizer.py +195 -0
  558. venv/Lib/site-packages/pip/_vendor/packaging/licenses/__init__.py +145 -0
  559. venv/Lib/site-packages/pip/_vendor/packaging/licenses/_spdx.py +759 -0
  560. venv/Lib/site-packages/pip/_vendor/packaging/markers.py +362 -0
  561. venv/Lib/site-packages/pip/_vendor/packaging/metadata.py +862 -0
  562. venv/Lib/site-packages/pip/_vendor/packaging/py.typed +0 -0
  563. venv/Lib/site-packages/pip/_vendor/packaging/requirements.py +91 -0
  564. venv/Lib/site-packages/pip/_vendor/packaging/specifiers.py +1019 -0
  565. venv/Lib/site-packages/pip/_vendor/packaging/tags.py +656 -0
  566. venv/Lib/site-packages/pip/_vendor/packaging/utils.py +163 -0
  567. venv/Lib/site-packages/pip/_vendor/packaging/version.py +582 -0
  568. venv/Lib/site-packages/pip/_vendor/pkg_resources/__init__.py +3676 -0
  569. venv/Lib/site-packages/pip/_vendor/platformdirs/__init__.py +631 -0
  570. venv/Lib/site-packages/pip/_vendor/platformdirs/__main__.py +55 -0
  571. venv/Lib/site-packages/pip/_vendor/platformdirs/android.py +249 -0
  572. venv/Lib/site-packages/pip/_vendor/platformdirs/api.py +299 -0
  573. venv/Lib/site-packages/pip/_vendor/platformdirs/macos.py +146 -0
  574. venv/Lib/site-packages/pip/_vendor/platformdirs/py.typed +0 -0
  575. venv/Lib/site-packages/pip/_vendor/platformdirs/unix.py +272 -0
  576. venv/Lib/site-packages/pip/_vendor/platformdirs/version.py +34 -0
  577. venv/Lib/site-packages/pip/_vendor/platformdirs/windows.py +272 -0
  578. venv/Lib/site-packages/pip/_vendor/pygments/__init__.py +82 -0
  579. venv/Lib/site-packages/pip/_vendor/pygments/__main__.py +17 -0
  580. venv/Lib/site-packages/pip/_vendor/pygments/console.py +70 -0
  581. venv/Lib/site-packages/pip/_vendor/pygments/filter.py +70 -0
  582. venv/Lib/site-packages/pip/_vendor/pygments/filters/__init__.py +940 -0
  583. venv/Lib/site-packages/pip/_vendor/pygments/formatter.py +129 -0
  584. venv/Lib/site-packages/pip/_vendor/pygments/formatters/__init__.py +157 -0
  585. venv/Lib/site-packages/pip/_vendor/pygments/formatters/_mapping.py +23 -0
  586. venv/Lib/site-packages/pip/_vendor/pygments/lexer.py +963 -0
  587. venv/Lib/site-packages/pip/_vendor/pygments/lexers/__init__.py +362 -0
  588. venv/Lib/site-packages/pip/_vendor/pygments/lexers/_mapping.py +602 -0
  589. venv/Lib/site-packages/pip/_vendor/pygments/lexers/python.py +1201 -0
  590. venv/Lib/site-packages/pip/_vendor/pygments/modeline.py +43 -0
  591. venv/Lib/site-packages/pip/_vendor/pygments/plugin.py +72 -0
  592. venv/Lib/site-packages/pip/_vendor/pygments/regexopt.py +91 -0
  593. venv/Lib/site-packages/pip/_vendor/pygments/scanner.py +104 -0
  594. venv/Lib/site-packages/pip/_vendor/pygments/sphinxext.py +247 -0
  595. venv/Lib/site-packages/pip/_vendor/pygments/style.py +203 -0
  596. venv/Lib/site-packages/pip/_vendor/pygments/styles/__init__.py +61 -0
  597. venv/Lib/site-packages/pip/_vendor/pygments/styles/_mapping.py +54 -0
  598. venv/Lib/site-packages/pip/_vendor/pygments/token.py +214 -0
  599. venv/Lib/site-packages/pip/_vendor/pygments/unistring.py +153 -0
  600. venv/Lib/site-packages/pip/_vendor/pygments/util.py +324 -0
  601. venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__init__.py +31 -0
  602. venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_impl.py +410 -0
  603. venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py +21 -0
  604. venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py +389 -0
  605. venv/Lib/site-packages/pip/_vendor/pyproject_hooks/py.typed +0 -0
  606. venv/Lib/site-packages/pip/_vendor/requests/__init__.py +179 -0
  607. venv/Lib/site-packages/pip/_vendor/requests/__version__.py +14 -0
  608. venv/Lib/site-packages/pip/_vendor/requests/_internal_utils.py +50 -0
  609. venv/Lib/site-packages/pip/_vendor/requests/adapters.py +696 -0
  610. venv/Lib/site-packages/pip/_vendor/requests/api.py +157 -0
  611. venv/Lib/site-packages/pip/_vendor/requests/auth.py +314 -0
  612. venv/Lib/site-packages/pip/_vendor/requests/certs.py +17 -0
  613. venv/Lib/site-packages/pip/_vendor/requests/compat.py +90 -0
  614. venv/Lib/site-packages/pip/_vendor/requests/cookies.py +561 -0
  615. venv/Lib/site-packages/pip/_vendor/requests/exceptions.py +151 -0
  616. venv/Lib/site-packages/pip/_vendor/requests/help.py +127 -0
  617. venv/Lib/site-packages/pip/_vendor/requests/hooks.py +33 -0
  618. venv/Lib/site-packages/pip/_vendor/requests/models.py +1039 -0
  619. venv/Lib/site-packages/pip/_vendor/requests/packages.py +25 -0
  620. venv/Lib/site-packages/pip/_vendor/requests/sessions.py +831 -0
  621. venv/Lib/site-packages/pip/_vendor/requests/status_codes.py +128 -0
  622. venv/Lib/site-packages/pip/_vendor/requests/structures.py +99 -0
  623. venv/Lib/site-packages/pip/_vendor/requests/utils.py +1086 -0
  624. venv/Lib/site-packages/pip/_vendor/resolvelib/__init__.py +27 -0
  625. venv/Lib/site-packages/pip/_vendor/resolvelib/providers.py +196 -0
  626. venv/Lib/site-packages/pip/_vendor/resolvelib/py.typed +0 -0
  627. venv/Lib/site-packages/pip/_vendor/resolvelib/reporters.py +55 -0
  628. venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/__init__.py +27 -0
  629. venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/abstract.py +47 -0
  630. venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/criterion.py +48 -0
  631. venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/exceptions.py +57 -0
  632. venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/resolution.py +627 -0
  633. venv/Lib/site-packages/pip/_vendor/resolvelib/structs.py +209 -0
  634. venv/Lib/site-packages/pip/_vendor/rich/__init__.py +177 -0
  635. venv/Lib/site-packages/pip/_vendor/rich/__main__.py +245 -0
  636. venv/Lib/site-packages/pip/_vendor/rich/_cell_widths.py +454 -0
  637. venv/Lib/site-packages/pip/_vendor/rich/_emoji_codes.py +3610 -0
  638. venv/Lib/site-packages/pip/_vendor/rich/_emoji_replace.py +32 -0
  639. venv/Lib/site-packages/pip/_vendor/rich/_export_format.py +76 -0
  640. venv/Lib/site-packages/pip/_vendor/rich/_extension.py +10 -0
  641. venv/Lib/site-packages/pip/_vendor/rich/_fileno.py +24 -0
  642. venv/Lib/site-packages/pip/_vendor/rich/_inspect.py +268 -0
  643. venv/Lib/site-packages/pip/_vendor/rich/_log_render.py +94 -0
  644. venv/Lib/site-packages/pip/_vendor/rich/_loop.py +43 -0
  645. venv/Lib/site-packages/pip/_vendor/rich/_null_file.py +69 -0
  646. venv/Lib/site-packages/pip/_vendor/rich/_palettes.py +309 -0
  647. venv/Lib/site-packages/pip/_vendor/rich/_pick.py +17 -0
  648. venv/Lib/site-packages/pip/_vendor/rich/_ratio.py +153 -0
  649. venv/Lib/site-packages/pip/_vendor/rich/_spinners.py +482 -0
  650. venv/Lib/site-packages/pip/_vendor/rich/_stack.py +16 -0
  651. venv/Lib/site-packages/pip/_vendor/rich/_timer.py +19 -0
  652. venv/Lib/site-packages/pip/_vendor/rich/_win32_console.py +661 -0
  653. venv/Lib/site-packages/pip/_vendor/rich/_windows.py +71 -0
  654. venv/Lib/site-packages/pip/_vendor/rich/_windows_renderer.py +56 -0
  655. venv/Lib/site-packages/pip/_vendor/rich/_wrap.py +93 -0
  656. venv/Lib/site-packages/pip/_vendor/rich/abc.py +33 -0
  657. venv/Lib/site-packages/pip/_vendor/rich/align.py +306 -0
  658. venv/Lib/site-packages/pip/_vendor/rich/ansi.py +241 -0
  659. venv/Lib/site-packages/pip/_vendor/rich/bar.py +93 -0
  660. venv/Lib/site-packages/pip/_vendor/rich/box.py +474 -0
  661. venv/Lib/site-packages/pip/_vendor/rich/cells.py +174 -0
  662. venv/Lib/site-packages/pip/_vendor/rich/color.py +621 -0
  663. venv/Lib/site-packages/pip/_vendor/rich/color_triplet.py +38 -0
  664. venv/Lib/site-packages/pip/_vendor/rich/columns.py +187 -0
  665. venv/Lib/site-packages/pip/_vendor/rich/console.py +2680 -0
  666. venv/Lib/site-packages/pip/_vendor/rich/constrain.py +37 -0
  667. venv/Lib/site-packages/pip/_vendor/rich/containers.py +167 -0
  668. venv/Lib/site-packages/pip/_vendor/rich/control.py +219 -0
  669. venv/Lib/site-packages/pip/_vendor/rich/default_styles.py +193 -0
  670. venv/Lib/site-packages/pip/_vendor/rich/diagnose.py +39 -0
  671. venv/Lib/site-packages/pip/_vendor/rich/emoji.py +91 -0
  672. venv/Lib/site-packages/pip/_vendor/rich/errors.py +34 -0
  673. venv/Lib/site-packages/pip/_vendor/rich/file_proxy.py +57 -0
  674. venv/Lib/site-packages/pip/_vendor/rich/filesize.py +88 -0
  675. venv/Lib/site-packages/pip/_vendor/rich/highlighter.py +232 -0
  676. venv/Lib/site-packages/pip/_vendor/rich/json.py +139 -0
  677. venv/Lib/site-packages/pip/_vendor/rich/jupyter.py +101 -0
  678. venv/Lib/site-packages/pip/_vendor/rich/layout.py +442 -0
  679. venv/Lib/site-packages/pip/_vendor/rich/live.py +400 -0
  680. venv/Lib/site-packages/pip/_vendor/rich/live_render.py +106 -0
  681. venv/Lib/site-packages/pip/_vendor/rich/logging.py +297 -0
  682. venv/Lib/site-packages/pip/_vendor/rich/markup.py +251 -0
  683. venv/Lib/site-packages/pip/_vendor/rich/measure.py +151 -0
  684. venv/Lib/site-packages/pip/_vendor/rich/padding.py +141 -0
  685. venv/Lib/site-packages/pip/_vendor/rich/pager.py +34 -0
  686. venv/Lib/site-packages/pip/_vendor/rich/palette.py +100 -0
  687. venv/Lib/site-packages/pip/_vendor/rich/panel.py +317 -0
  688. venv/Lib/site-packages/pip/_vendor/rich/pretty.py +1016 -0
  689. venv/Lib/site-packages/pip/_vendor/rich/progress.py +1715 -0
  690. venv/Lib/site-packages/pip/_vendor/rich/progress_bar.py +223 -0
  691. venv/Lib/site-packages/pip/_vendor/rich/prompt.py +400 -0
  692. venv/Lib/site-packages/pip/_vendor/rich/protocol.py +42 -0
  693. venv/Lib/site-packages/pip/_vendor/rich/py.typed +0 -0
  694. venv/Lib/site-packages/pip/_vendor/rich/region.py +10 -0
  695. venv/Lib/site-packages/pip/_vendor/rich/repr.py +149 -0
  696. venv/Lib/site-packages/pip/_vendor/rich/rule.py +130 -0
  697. venv/Lib/site-packages/pip/_vendor/rich/scope.py +86 -0
  698. venv/Lib/site-packages/pip/_vendor/rich/screen.py +54 -0
  699. venv/Lib/site-packages/pip/_vendor/rich/segment.py +752 -0
  700. venv/Lib/site-packages/pip/_vendor/rich/spinner.py +132 -0
  701. venv/Lib/site-packages/pip/_vendor/rich/status.py +131 -0
  702. venv/Lib/site-packages/pip/_vendor/rich/style.py +792 -0
  703. venv/Lib/site-packages/pip/_vendor/rich/styled.py +42 -0
  704. venv/Lib/site-packages/pip/_vendor/rich/syntax.py +985 -0
  705. venv/Lib/site-packages/pip/_vendor/rich/table.py +1006 -0
  706. venv/Lib/site-packages/pip/_vendor/rich/terminal_theme.py +153 -0
  707. venv/Lib/site-packages/pip/_vendor/rich/text.py +1361 -0
  708. venv/Lib/site-packages/pip/_vendor/rich/theme.py +115 -0
  709. venv/Lib/site-packages/pip/_vendor/rich/themes.py +5 -0
  710. venv/Lib/site-packages/pip/_vendor/rich/traceback.py +899 -0
  711. venv/Lib/site-packages/pip/_vendor/rich/tree.py +257 -0
  712. venv/Lib/site-packages/pip/_vendor/tomli/__init__.py +8 -0
  713. venv/Lib/site-packages/pip/_vendor/tomli/_parser.py +777 -0
  714. venv/Lib/site-packages/pip/_vendor/tomli/_re.py +115 -0
  715. venv/Lib/site-packages/pip/_vendor/tomli/_types.py +10 -0
  716. venv/Lib/site-packages/pip/_vendor/tomli/py.typed +1 -0
  717. venv/Lib/site-packages/pip/_vendor/tomli_w/__init__.py +4 -0
  718. venv/Lib/site-packages/pip/_vendor/tomli_w/_writer.py +229 -0
  719. venv/Lib/site-packages/pip/_vendor/tomli_w/py.typed +1 -0
  720. venv/Lib/site-packages/pip/_vendor/truststore/__init__.py +36 -0
  721. venv/Lib/site-packages/pip/_vendor/truststore/_api.py +341 -0
  722. venv/Lib/site-packages/pip/_vendor/truststore/_macos.py +571 -0
  723. venv/Lib/site-packages/pip/_vendor/truststore/_openssl.py +68 -0
  724. venv/Lib/site-packages/pip/_vendor/truststore/_ssl_constants.py +31 -0
  725. venv/Lib/site-packages/pip/_vendor/truststore/_windows.py +567 -0
  726. venv/Lib/site-packages/pip/_vendor/truststore/py.typed +0 -0
  727. venv/Lib/site-packages/pip/_vendor/urllib3/__init__.py +102 -0
  728. venv/Lib/site-packages/pip/_vendor/urllib3/_collections.py +355 -0
  729. venv/Lib/site-packages/pip/_vendor/urllib3/_version.py +2 -0
  730. venv/Lib/site-packages/pip/_vendor/urllib3/connection.py +572 -0
  731. venv/Lib/site-packages/pip/_vendor/urllib3/connectionpool.py +1140 -0
  732. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__init__.py +0 -0
  733. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py +36 -0
  734. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py +0 -0
  735. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +519 -0
  736. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +397 -0
  737. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/appengine.py +314 -0
  738. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py +130 -0
  739. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py +518 -0
  740. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/securetransport.py +920 -0
  741. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/socks.py +216 -0
  742. venv/Lib/site-packages/pip/_vendor/urllib3/exceptions.py +323 -0
  743. venv/Lib/site-packages/pip/_vendor/urllib3/fields.py +274 -0
  744. venv/Lib/site-packages/pip/_vendor/urllib3/filepost.py +98 -0
  745. venv/Lib/site-packages/pip/_vendor/urllib3/packages/__init__.py +0 -0
  746. venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py +0 -0
  747. venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py +51 -0
  748. venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py +155 -0
  749. venv/Lib/site-packages/pip/_vendor/urllib3/packages/six.py +1076 -0
  750. venv/Lib/site-packages/pip/_vendor/urllib3/poolmanager.py +540 -0
  751. venv/Lib/site-packages/pip/_vendor/urllib3/request.py +191 -0
  752. venv/Lib/site-packages/pip/_vendor/urllib3/response.py +879 -0
  753. venv/Lib/site-packages/pip/_vendor/urllib3/util/__init__.py +49 -0
  754. venv/Lib/site-packages/pip/_vendor/urllib3/util/connection.py +149 -0
  755. venv/Lib/site-packages/pip/_vendor/urllib3/util/proxy.py +57 -0
  756. venv/Lib/site-packages/pip/_vendor/urllib3/util/queue.py +22 -0
  757. venv/Lib/site-packages/pip/_vendor/urllib3/util/request.py +137 -0
  758. venv/Lib/site-packages/pip/_vendor/urllib3/util/response.py +107 -0
  759. venv/Lib/site-packages/pip/_vendor/urllib3/util/retry.py +622 -0
  760. venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_.py +504 -0
  761. venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py +159 -0
  762. venv/Lib/site-packages/pip/_vendor/urllib3/util/ssltransport.py +221 -0
  763. venv/Lib/site-packages/pip/_vendor/urllib3/util/timeout.py +271 -0
  764. venv/Lib/site-packages/pip/_vendor/urllib3/util/url.py +435 -0
  765. venv/Lib/site-packages/pip/_vendor/urllib3/util/wait.py +152 -0
  766. venv/Lib/site-packages/pip/py.typed +4 -0
  767. venv/Lib/site-packages/pygments/__init__.py +82 -0
  768. venv/Lib/site-packages/pygments/__main__.py +17 -0
  769. venv/Lib/site-packages/pygments/cmdline.py +668 -0
  770. venv/Lib/site-packages/pygments/console.py +70 -0
  771. venv/Lib/site-packages/pygments/filter.py +70 -0
  772. venv/Lib/site-packages/pygments/filters/__init__.py +940 -0
  773. venv/Lib/site-packages/pygments/formatter.py +129 -0
  774. venv/Lib/site-packages/pygments/formatters/__init__.py +157 -0
  775. venv/Lib/site-packages/pygments/formatters/_mapping.py +23 -0
  776. venv/Lib/site-packages/pygments/formatters/bbcode.py +108 -0
  777. venv/Lib/site-packages/pygments/formatters/groff.py +170 -0
  778. venv/Lib/site-packages/pygments/formatters/html.py +995 -0
  779. venv/Lib/site-packages/pygments/formatters/img.py +686 -0
  780. venv/Lib/site-packages/pygments/formatters/irc.py +154 -0
  781. venv/Lib/site-packages/pygments/formatters/latex.py +518 -0
  782. venv/Lib/site-packages/pygments/formatters/other.py +160 -0
  783. venv/Lib/site-packages/pygments/formatters/pangomarkup.py +83 -0
  784. venv/Lib/site-packages/pygments/formatters/rtf.py +349 -0
  785. venv/Lib/site-packages/pygments/formatters/svg.py +185 -0
  786. venv/Lib/site-packages/pygments/formatters/terminal.py +127 -0
  787. venv/Lib/site-packages/pygments/formatters/terminal256.py +338 -0
  788. venv/Lib/site-packages/pygments/lexer.py +961 -0
  789. venv/Lib/site-packages/pygments/lexers/__init__.py +362 -0
  790. venv/Lib/site-packages/pygments/lexers/_ada_builtins.py +103 -0
  791. venv/Lib/site-packages/pygments/lexers/_asy_builtins.py +1644 -0
  792. venv/Lib/site-packages/pygments/lexers/_cl_builtins.py +231 -0
  793. venv/Lib/site-packages/pygments/lexers/_cocoa_builtins.py +75 -0
  794. venv/Lib/site-packages/pygments/lexers/_csound_builtins.py +1780 -0
  795. venv/Lib/site-packages/pygments/lexers/_css_builtins.py +558 -0
  796. venv/Lib/site-packages/pygments/lexers/_googlesql_builtins.py +918 -0
  797. venv/Lib/site-packages/pygments/lexers/_julia_builtins.py +411 -0
  798. venv/Lib/site-packages/pygments/lexers/_lasso_builtins.py +5326 -0
  799. venv/Lib/site-packages/pygments/lexers/_lilypond_builtins.py +4932 -0
  800. venv/Lib/site-packages/pygments/lexers/_lua_builtins.py +285 -0
  801. venv/Lib/site-packages/pygments/lexers/_luau_builtins.py +62 -0
  802. venv/Lib/site-packages/pygments/lexers/_mapping.py +602 -0
  803. venv/Lib/site-packages/pygments/lexers/_mql_builtins.py +1171 -0
  804. venv/Lib/site-packages/pygments/lexers/_mysql_builtins.py +1335 -0
  805. venv/Lib/site-packages/pygments/lexers/_openedge_builtins.py +2600 -0
  806. venv/Lib/site-packages/pygments/lexers/_php_builtins.py +3325 -0
  807. venv/Lib/site-packages/pygments/lexers/_postgres_builtins.py +739 -0
  808. venv/Lib/site-packages/pygments/lexers/_qlik_builtins.py +666 -0
  809. venv/Lib/site-packages/pygments/lexers/_scheme_builtins.py +1609 -0
  810. venv/Lib/site-packages/pygments/lexers/_scilab_builtins.py +3093 -0
  811. venv/Lib/site-packages/pygments/lexers/_sourcemod_builtins.py +1151 -0
  812. venv/Lib/site-packages/pygments/lexers/_sql_builtins.py +106 -0
  813. venv/Lib/site-packages/pygments/lexers/_stan_builtins.py +648 -0
  814. venv/Lib/site-packages/pygments/lexers/_stata_builtins.py +457 -0
  815. venv/Lib/site-packages/pygments/lexers/_tsql_builtins.py +1003 -0
  816. venv/Lib/site-packages/pygments/lexers/_usd_builtins.py +112 -0
  817. venv/Lib/site-packages/pygments/lexers/_vbscript_builtins.py +279 -0
  818. venv/Lib/site-packages/pygments/lexers/_vim_builtins.py +1938 -0
  819. venv/Lib/site-packages/pygments/lexers/actionscript.py +243 -0
  820. venv/Lib/site-packages/pygments/lexers/ada.py +144 -0
  821. venv/Lib/site-packages/pygments/lexers/agile.py +25 -0
  822. venv/Lib/site-packages/pygments/lexers/algebra.py +299 -0
  823. venv/Lib/site-packages/pygments/lexers/ambient.py +75 -0
  824. venv/Lib/site-packages/pygments/lexers/amdgpu.py +54 -0
  825. venv/Lib/site-packages/pygments/lexers/ampl.py +87 -0
  826. venv/Lib/site-packages/pygments/lexers/apdlexer.py +593 -0
  827. venv/Lib/site-packages/pygments/lexers/apl.py +103 -0
  828. venv/Lib/site-packages/pygments/lexers/archetype.py +315 -0
  829. venv/Lib/site-packages/pygments/lexers/arrow.py +116 -0
  830. venv/Lib/site-packages/pygments/lexers/arturo.py +249 -0
  831. venv/Lib/site-packages/pygments/lexers/asc.py +55 -0
  832. venv/Lib/site-packages/pygments/lexers/asm.py +1051 -0
  833. venv/Lib/site-packages/pygments/lexers/asn1.py +178 -0
  834. venv/Lib/site-packages/pygments/lexers/automation.py +379 -0
  835. venv/Lib/site-packages/pygments/lexers/bare.py +101 -0
  836. venv/Lib/site-packages/pygments/lexers/basic.py +656 -0
  837. venv/Lib/site-packages/pygments/lexers/bdd.py +57 -0
  838. venv/Lib/site-packages/pygments/lexers/berry.py +99 -0
  839. venv/Lib/site-packages/pygments/lexers/bibtex.py +159 -0
  840. venv/Lib/site-packages/pygments/lexers/blueprint.py +173 -0
  841. venv/Lib/site-packages/pygments/lexers/boa.py +97 -0
  842. venv/Lib/site-packages/pygments/lexers/bqn.py +112 -0
  843. venv/Lib/site-packages/pygments/lexers/business.py +625 -0
  844. venv/Lib/site-packages/pygments/lexers/c_cpp.py +414 -0
  845. venv/Lib/site-packages/pygments/lexers/c_like.py +738 -0
  846. venv/Lib/site-packages/pygments/lexers/capnproto.py +74 -0
  847. venv/Lib/site-packages/pygments/lexers/carbon.py +95 -0
  848. venv/Lib/site-packages/pygments/lexers/cddl.py +172 -0
  849. venv/Lib/site-packages/pygments/lexers/chapel.py +139 -0
  850. venv/Lib/site-packages/pygments/lexers/clean.py +180 -0
  851. venv/Lib/site-packages/pygments/lexers/codeql.py +80 -0
  852. venv/Lib/site-packages/pygments/lexers/comal.py +81 -0
  853. venv/Lib/site-packages/pygments/lexers/compiled.py +35 -0
  854. venv/Lib/site-packages/pygments/lexers/configs.py +1433 -0
  855. venv/Lib/site-packages/pygments/lexers/console.py +114 -0
  856. venv/Lib/site-packages/pygments/lexers/cplint.py +43 -0
  857. venv/Lib/site-packages/pygments/lexers/crystal.py +364 -0
  858. venv/Lib/site-packages/pygments/lexers/csound.py +466 -0
  859. venv/Lib/site-packages/pygments/lexers/css.py +602 -0
  860. venv/Lib/site-packages/pygments/lexers/d.py +259 -0
  861. venv/Lib/site-packages/pygments/lexers/dalvik.py +126 -0
  862. venv/Lib/site-packages/pygments/lexers/data.py +763 -0
  863. venv/Lib/site-packages/pygments/lexers/dax.py +135 -0
  864. venv/Lib/site-packages/pygments/lexers/devicetree.py +108 -0
  865. venv/Lib/site-packages/pygments/lexers/diff.py +169 -0
  866. venv/Lib/site-packages/pygments/lexers/dns.py +109 -0
  867. venv/Lib/site-packages/pygments/lexers/dotnet.py +873 -0
  868. venv/Lib/site-packages/pygments/lexers/dsls.py +970 -0
  869. venv/Lib/site-packages/pygments/lexers/dylan.py +279 -0
  870. venv/Lib/site-packages/pygments/lexers/ecl.py +144 -0
  871. venv/Lib/site-packages/pygments/lexers/eiffel.py +68 -0
  872. venv/Lib/site-packages/pygments/lexers/elm.py +123 -0
  873. venv/Lib/site-packages/pygments/lexers/elpi.py +175 -0
  874. venv/Lib/site-packages/pygments/lexers/email.py +132 -0
  875. venv/Lib/site-packages/pygments/lexers/erlang.py +526 -0
  876. venv/Lib/site-packages/pygments/lexers/esoteric.py +300 -0
  877. venv/Lib/site-packages/pygments/lexers/ezhil.py +76 -0
  878. venv/Lib/site-packages/pygments/lexers/factor.py +363 -0
  879. venv/Lib/site-packages/pygments/lexers/fantom.py +251 -0
  880. venv/Lib/site-packages/pygments/lexers/felix.py +275 -0
  881. venv/Lib/site-packages/pygments/lexers/fift.py +68 -0
  882. venv/Lib/site-packages/pygments/lexers/floscript.py +81 -0
  883. venv/Lib/site-packages/pygments/lexers/forth.py +178 -0
  884. venv/Lib/site-packages/pygments/lexers/fortran.py +212 -0
  885. venv/Lib/site-packages/pygments/lexers/foxpro.py +427 -0
  886. venv/Lib/site-packages/pygments/lexers/freefem.py +893 -0
  887. venv/Lib/site-packages/pygments/lexers/func.py +110 -0
  888. venv/Lib/site-packages/pygments/lexers/functional.py +21 -0
  889. venv/Lib/site-packages/pygments/lexers/futhark.py +105 -0
  890. venv/Lib/site-packages/pygments/lexers/gcodelexer.py +35 -0
  891. venv/Lib/site-packages/pygments/lexers/gdscript.py +189 -0
  892. venv/Lib/site-packages/pygments/lexers/gleam.py +74 -0
  893. venv/Lib/site-packages/pygments/lexers/go.py +97 -0
  894. venv/Lib/site-packages/pygments/lexers/grammar_notation.py +262 -0
  895. venv/Lib/site-packages/pygments/lexers/graph.py +108 -0
  896. venv/Lib/site-packages/pygments/lexers/graphics.py +794 -0
  897. venv/Lib/site-packages/pygments/lexers/graphql.py +176 -0
  898. venv/Lib/site-packages/pygments/lexers/graphviz.py +58 -0
  899. venv/Lib/site-packages/pygments/lexers/gsql.py +103 -0
  900. venv/Lib/site-packages/pygments/lexers/hare.py +73 -0
  901. venv/Lib/site-packages/pygments/lexers/haskell.py +866 -0
  902. venv/Lib/site-packages/pygments/lexers/haxe.py +935 -0
  903. venv/Lib/site-packages/pygments/lexers/hdl.py +466 -0
  904. venv/Lib/site-packages/pygments/lexers/hexdump.py +102 -0
  905. venv/Lib/site-packages/pygments/lexers/html.py +670 -0
  906. venv/Lib/site-packages/pygments/lexers/idl.py +284 -0
  907. venv/Lib/site-packages/pygments/lexers/igor.py +435 -0
  908. venv/Lib/site-packages/pygments/lexers/inferno.py +95 -0
  909. venv/Lib/site-packages/pygments/lexers/installers.py +352 -0
  910. venv/Lib/site-packages/pygments/lexers/int_fiction.py +1370 -0
  911. venv/Lib/site-packages/pygments/lexers/iolang.py +61 -0
  912. venv/Lib/site-packages/pygments/lexers/j.py +151 -0
  913. venv/Lib/site-packages/pygments/lexers/javascript.py +1591 -0
  914. venv/Lib/site-packages/pygments/lexers/jmespath.py +69 -0
  915. venv/Lib/site-packages/pygments/lexers/jslt.py +94 -0
  916. venv/Lib/site-packages/pygments/lexers/json5.py +83 -0
  917. venv/Lib/site-packages/pygments/lexers/jsonnet.py +169 -0
  918. venv/Lib/site-packages/pygments/lexers/jsx.py +100 -0
  919. venv/Lib/site-packages/pygments/lexers/julia.py +294 -0
  920. venv/Lib/site-packages/pygments/lexers/jvm.py +1802 -0
  921. venv/Lib/site-packages/pygments/lexers/kuin.py +332 -0
  922. venv/Lib/site-packages/pygments/lexers/kusto.py +93 -0
  923. venv/Lib/site-packages/pygments/lexers/ldap.py +155 -0
  924. venv/Lib/site-packages/pygments/lexers/lean.py +241 -0
  925. venv/Lib/site-packages/pygments/lexers/lilypond.py +225 -0
  926. venv/Lib/site-packages/pygments/lexers/lisp.py +3146 -0
  927. venv/Lib/site-packages/pygments/lexers/macaulay2.py +1814 -0
  928. venv/Lib/site-packages/pygments/lexers/make.py +212 -0
  929. venv/Lib/site-packages/pygments/lexers/maple.py +291 -0
  930. venv/Lib/site-packages/pygments/lexers/markup.py +1654 -0
  931. venv/Lib/site-packages/pygments/lexers/math.py +21 -0
  932. venv/Lib/site-packages/pygments/lexers/matlab.py +3307 -0
  933. venv/Lib/site-packages/pygments/lexers/maxima.py +84 -0
  934. venv/Lib/site-packages/pygments/lexers/meson.py +139 -0
  935. venv/Lib/site-packages/pygments/lexers/mime.py +210 -0
  936. venv/Lib/site-packages/pygments/lexers/minecraft.py +391 -0
  937. venv/Lib/site-packages/pygments/lexers/mips.py +130 -0
  938. venv/Lib/site-packages/pygments/lexers/ml.py +958 -0
  939. venv/Lib/site-packages/pygments/lexers/modeling.py +366 -0
  940. venv/Lib/site-packages/pygments/lexers/modula2.py +1579 -0
  941. venv/Lib/site-packages/pygments/lexers/mojo.py +707 -0
  942. venv/Lib/site-packages/pygments/lexers/monte.py +203 -0
  943. venv/Lib/site-packages/pygments/lexers/mosel.py +447 -0
  944. venv/Lib/site-packages/pygments/lexers/ncl.py +894 -0
  945. venv/Lib/site-packages/pygments/lexers/nimrod.py +199 -0
  946. venv/Lib/site-packages/pygments/lexers/nit.py +63 -0
  947. venv/Lib/site-packages/pygments/lexers/nix.py +144 -0
  948. venv/Lib/site-packages/pygments/lexers/numbair.py +63 -0
  949. venv/Lib/site-packages/pygments/lexers/oberon.py +120 -0
  950. venv/Lib/site-packages/pygments/lexers/objective.py +513 -0
  951. venv/Lib/site-packages/pygments/lexers/ooc.py +84 -0
  952. venv/Lib/site-packages/pygments/lexers/openscad.py +96 -0
  953. venv/Lib/site-packages/pygments/lexers/other.py +41 -0
  954. venv/Lib/site-packages/pygments/lexers/parasail.py +78 -0
  955. venv/Lib/site-packages/pygments/lexers/parsers.py +798 -0
  956. venv/Lib/site-packages/pygments/lexers/pascal.py +644 -0
  957. venv/Lib/site-packages/pygments/lexers/pawn.py +202 -0
  958. venv/Lib/site-packages/pygments/lexers/pddl.py +82 -0
  959. venv/Lib/site-packages/pygments/lexers/perl.py +733 -0
  960. venv/Lib/site-packages/pygments/lexers/phix.py +363 -0
  961. venv/Lib/site-packages/pygments/lexers/php.py +334 -0
  962. venv/Lib/site-packages/pygments/lexers/pointless.py +70 -0
  963. venv/Lib/site-packages/pygments/lexers/pony.py +93 -0
  964. venv/Lib/site-packages/pygments/lexers/praat.py +303 -0
  965. venv/Lib/site-packages/pygments/lexers/procfile.py +41 -0
  966. venv/Lib/site-packages/pygments/lexers/prolog.py +318 -0
  967. venv/Lib/site-packages/pygments/lexers/promql.py +176 -0
  968. venv/Lib/site-packages/pygments/lexers/prql.py +251 -0
  969. venv/Lib/site-packages/pygments/lexers/ptx.py +119 -0
  970. venv/Lib/site-packages/pygments/lexers/python.py +1201 -0
  971. venv/Lib/site-packages/pygments/lexers/q.py +187 -0
  972. venv/Lib/site-packages/pygments/lexers/qlik.py +117 -0
  973. venv/Lib/site-packages/pygments/lexers/qvt.py +153 -0
  974. venv/Lib/site-packages/pygments/lexers/r.py +196 -0
  975. venv/Lib/site-packages/pygments/lexers/rdf.py +468 -0
  976. venv/Lib/site-packages/pygments/lexers/rebol.py +419 -0
  977. venv/Lib/site-packages/pygments/lexers/rego.py +57 -0
  978. venv/Lib/site-packages/pygments/lexers/resource.py +83 -0
  979. venv/Lib/site-packages/pygments/lexers/ride.py +138 -0
  980. venv/Lib/site-packages/pygments/lexers/rita.py +42 -0
  981. venv/Lib/site-packages/pygments/lexers/rnc.py +66 -0
  982. venv/Lib/site-packages/pygments/lexers/roboconf.py +81 -0
  983. venv/Lib/site-packages/pygments/lexers/robotframework.py +551 -0
  984. venv/Lib/site-packages/pygments/lexers/ruby.py +518 -0
  985. venv/Lib/site-packages/pygments/lexers/rust.py +222 -0
  986. venv/Lib/site-packages/pygments/lexers/sas.py +227 -0
  987. venv/Lib/site-packages/pygments/lexers/savi.py +171 -0
  988. venv/Lib/site-packages/pygments/lexers/scdoc.py +85 -0
  989. venv/Lib/site-packages/pygments/lexers/scripting.py +1616 -0
  990. venv/Lib/site-packages/pygments/lexers/sgf.py +59 -0
  991. venv/Lib/site-packages/pygments/lexers/shell.py +902 -0
  992. venv/Lib/site-packages/pygments/lexers/sieve.py +78 -0
  993. venv/Lib/site-packages/pygments/lexers/slash.py +183 -0
  994. venv/Lib/site-packages/pygments/lexers/smalltalk.py +194 -0
  995. venv/Lib/site-packages/pygments/lexers/smithy.py +77 -0
  996. venv/Lib/site-packages/pygments/lexers/smv.py +78 -0
  997. venv/Lib/site-packages/pygments/lexers/snobol.py +82 -0
  998. venv/Lib/site-packages/pygments/lexers/solidity.py +87 -0
  999. venv/Lib/site-packages/pygments/lexers/soong.py +78 -0
  1000. venv/Lib/site-packages/pygments/lexers/sophia.py +102 -0
  1001. venv/Lib/site-packages/pygments/lexers/special.py +122 -0
  1002. venv/Lib/site-packages/pygments/lexers/spice.py +70 -0
  1003. venv/Lib/site-packages/pygments/lexers/sql.py +1109 -0
  1004. venv/Lib/site-packages/pygments/lexers/srcinfo.py +62 -0
  1005. venv/Lib/site-packages/pygments/lexers/stata.py +170 -0
  1006. venv/Lib/site-packages/pygments/lexers/supercollider.py +94 -0
  1007. venv/Lib/site-packages/pygments/lexers/tablegen.py +177 -0
  1008. venv/Lib/site-packages/pygments/lexers/tact.py +303 -0
  1009. venv/Lib/site-packages/pygments/lexers/tal.py +77 -0
  1010. venv/Lib/site-packages/pygments/lexers/tcl.py +148 -0
  1011. venv/Lib/site-packages/pygments/lexers/teal.py +88 -0
  1012. venv/Lib/site-packages/pygments/lexers/templates.py +2355 -0
  1013. venv/Lib/site-packages/pygments/lexers/teraterm.py +325 -0
  1014. venv/Lib/site-packages/pygments/lexers/testing.py +209 -0
  1015. venv/Lib/site-packages/pygments/lexers/text.py +27 -0
  1016. venv/Lib/site-packages/pygments/lexers/textedit.py +205 -0
  1017. venv/Lib/site-packages/pygments/lexers/textfmts.py +436 -0
  1018. venv/Lib/site-packages/pygments/lexers/theorem.py +410 -0
  1019. venv/Lib/site-packages/pygments/lexers/thingsdb.py +140 -0
  1020. venv/Lib/site-packages/pygments/lexers/tlb.py +59 -0
  1021. venv/Lib/site-packages/pygments/lexers/tls.py +54 -0
  1022. venv/Lib/site-packages/pygments/lexers/tnt.py +270 -0
  1023. venv/Lib/site-packages/pygments/lexers/trafficscript.py +51 -0
  1024. venv/Lib/site-packages/pygments/lexers/typoscript.py +216 -0
  1025. venv/Lib/site-packages/pygments/lexers/typst.py +160 -0
  1026. venv/Lib/site-packages/pygments/lexers/ul4.py +309 -0
  1027. venv/Lib/site-packages/pygments/lexers/unicon.py +413 -0
  1028. venv/Lib/site-packages/pygments/lexers/urbi.py +145 -0
  1029. venv/Lib/site-packages/pygments/lexers/usd.py +85 -0
  1030. venv/Lib/site-packages/pygments/lexers/varnish.py +189 -0
  1031. venv/Lib/site-packages/pygments/lexers/verification.py +113 -0
  1032. venv/Lib/site-packages/pygments/lexers/verifpal.py +65 -0
  1033. venv/Lib/site-packages/pygments/lexers/vip.py +150 -0
  1034. venv/Lib/site-packages/pygments/lexers/vyper.py +140 -0
  1035. venv/Lib/site-packages/pygments/lexers/web.py +24 -0
  1036. venv/Lib/site-packages/pygments/lexers/webassembly.py +119 -0
  1037. venv/Lib/site-packages/pygments/lexers/webidl.py +298 -0
  1038. venv/Lib/site-packages/pygments/lexers/webmisc.py +1006 -0
  1039. venv/Lib/site-packages/pygments/lexers/wgsl.py +406 -0
  1040. venv/Lib/site-packages/pygments/lexers/whiley.py +115 -0
  1041. venv/Lib/site-packages/pygments/lexers/wowtoc.py +120 -0
  1042. venv/Lib/site-packages/pygments/lexers/wren.py +98 -0
  1043. venv/Lib/site-packages/pygments/lexers/x10.py +66 -0
  1044. venv/Lib/site-packages/pygments/lexers/xorg.py +38 -0
  1045. venv/Lib/site-packages/pygments/lexers/yang.py +103 -0
  1046. venv/Lib/site-packages/pygments/lexers/yara.py +69 -0
  1047. venv/Lib/site-packages/pygments/lexers/zig.py +125 -0
  1048. venv/Lib/site-packages/pygments/modeline.py +43 -0
  1049. venv/Lib/site-packages/pygments/plugin.py +72 -0
  1050. venv/Lib/site-packages/pygments/regexopt.py +91 -0
  1051. venv/Lib/site-packages/pygments/scanner.py +104 -0
  1052. venv/Lib/site-packages/pygments/sphinxext.py +247 -0
  1053. venv/Lib/site-packages/pygments/style.py +203 -0
  1054. venv/Lib/site-packages/pygments/styles/__init__.py +61 -0
  1055. venv/Lib/site-packages/pygments/styles/_mapping.py +54 -0
  1056. venv/Lib/site-packages/pygments/styles/abap.py +32 -0
  1057. venv/Lib/site-packages/pygments/styles/algol.py +65 -0
  1058. venv/Lib/site-packages/pygments/styles/algol_nu.py +65 -0
  1059. venv/Lib/site-packages/pygments/styles/arduino.py +100 -0
  1060. venv/Lib/site-packages/pygments/styles/autumn.py +67 -0
  1061. venv/Lib/site-packages/pygments/styles/borland.py +53 -0
  1062. venv/Lib/site-packages/pygments/styles/bw.py +52 -0
  1063. venv/Lib/site-packages/pygments/styles/coffee.py +80 -0
  1064. venv/Lib/site-packages/pygments/styles/colorful.py +83 -0
  1065. venv/Lib/site-packages/pygments/styles/default.py +76 -0
  1066. venv/Lib/site-packages/pygments/styles/dracula.py +90 -0
  1067. venv/Lib/site-packages/pygments/styles/emacs.py +75 -0
  1068. venv/Lib/site-packages/pygments/styles/friendly.py +76 -0
  1069. venv/Lib/site-packages/pygments/styles/friendly_grayscale.py +80 -0
  1070. venv/Lib/site-packages/pygments/styles/fruity.py +47 -0
  1071. venv/Lib/site-packages/pygments/styles/gh_dark.py +113 -0
  1072. venv/Lib/site-packages/pygments/styles/gruvbox.py +118 -0
  1073. venv/Lib/site-packages/pygments/styles/igor.py +32 -0
  1074. venv/Lib/site-packages/pygments/styles/inkpot.py +72 -0
  1075. venv/Lib/site-packages/pygments/styles/lightbulb.py +110 -0
  1076. venv/Lib/site-packages/pygments/styles/lilypond.py +62 -0
  1077. venv/Lib/site-packages/pygments/styles/lovelace.py +100 -0
  1078. venv/Lib/site-packages/pygments/styles/manni.py +79 -0
  1079. venv/Lib/site-packages/pygments/styles/material.py +124 -0
  1080. venv/Lib/site-packages/pygments/styles/monokai.py +112 -0
  1081. venv/Lib/site-packages/pygments/styles/murphy.py +82 -0
  1082. venv/Lib/site-packages/pygments/styles/native.py +70 -0
  1083. venv/Lib/site-packages/pygments/styles/nord.py +156 -0
  1084. venv/Lib/site-packages/pygments/styles/onedark.py +63 -0
  1085. venv/Lib/site-packages/pygments/styles/paraiso_dark.py +124 -0
  1086. venv/Lib/site-packages/pygments/styles/paraiso_light.py +124 -0
  1087. venv/Lib/site-packages/pygments/styles/pastie.py +78 -0
  1088. venv/Lib/site-packages/pygments/styles/perldoc.py +73 -0
  1089. venv/Lib/site-packages/pygments/styles/rainbow_dash.py +95 -0
  1090. venv/Lib/site-packages/pygments/styles/rrt.py +40 -0
  1091. venv/Lib/site-packages/pygments/styles/sas.py +46 -0
  1092. venv/Lib/site-packages/pygments/styles/solarized.py +144 -0
  1093. venv/Lib/site-packages/pygments/styles/staroffice.py +31 -0
  1094. venv/Lib/site-packages/pygments/styles/stata_dark.py +42 -0
  1095. venv/Lib/site-packages/pygments/styles/stata_light.py +42 -0
  1096. venv/Lib/site-packages/pygments/styles/tango.py +143 -0
  1097. venv/Lib/site-packages/pygments/styles/trac.py +66 -0
  1098. venv/Lib/site-packages/pygments/styles/vim.py +67 -0
  1099. venv/Lib/site-packages/pygments/styles/vs.py +41 -0
  1100. venv/Lib/site-packages/pygments/styles/xcode.py +53 -0
  1101. venv/Lib/site-packages/pygments/styles/zenburn.py +83 -0
  1102. venv/Lib/site-packages/pygments/token.py +214 -0
  1103. venv/Lib/site-packages/pygments/unistring.py +153 -0
  1104. venv/Lib/site-packages/pygments/util.py +324 -0
  1105. venv/Lib/site-packages/pyproject_hooks/__init__.py +31 -0
  1106. venv/Lib/site-packages/pyproject_hooks/_impl.py +410 -0
  1107. venv/Lib/site-packages/pyproject_hooks/_in_process/__init__.py +21 -0
  1108. venv/Lib/site-packages/pyproject_hooks/_in_process/_in_process.py +389 -0
  1109. venv/Lib/site-packages/pyproject_hooks/py.typed +0 -0
  1110. venv/Lib/site-packages/readme_renderer/__init__.py +13 -0
  1111. venv/Lib/site-packages/readme_renderer/__main__.py +66 -0
  1112. venv/Lib/site-packages/readme_renderer/clean.py +89 -0
  1113. venv/Lib/site-packages/readme_renderer/markdown.py +123 -0
  1114. venv/Lib/site-packages/readme_renderer/py.typed +0 -0
  1115. venv/Lib/site-packages/readme_renderer/rst.py +135 -0
  1116. venv/Lib/site-packages/readme_renderer/txt.py +24 -0
  1117. venv/Lib/site-packages/requests/__init__.py +184 -0
  1118. venv/Lib/site-packages/requests/__version__.py +14 -0
  1119. venv/Lib/site-packages/requests/_internal_utils.py +50 -0
  1120. venv/Lib/site-packages/requests/adapters.py +696 -0
  1121. venv/Lib/site-packages/requests/api.py +157 -0
  1122. venv/Lib/site-packages/requests/auth.py +314 -0
  1123. venv/Lib/site-packages/requests/certs.py +17 -0
  1124. venv/Lib/site-packages/requests/compat.py +106 -0
  1125. venv/Lib/site-packages/requests/cookies.py +561 -0
  1126. venv/Lib/site-packages/requests/exceptions.py +151 -0
  1127. venv/Lib/site-packages/requests/help.py +134 -0
  1128. venv/Lib/site-packages/requests/hooks.py +33 -0
  1129. venv/Lib/site-packages/requests/models.py +1039 -0
  1130. venv/Lib/site-packages/requests/packages.py +23 -0
  1131. venv/Lib/site-packages/requests/sessions.py +831 -0
  1132. venv/Lib/site-packages/requests/status_codes.py +128 -0
  1133. venv/Lib/site-packages/requests/structures.py +99 -0
  1134. venv/Lib/site-packages/requests/utils.py +1086 -0
  1135. venv/Lib/site-packages/requests_toolbelt/__init__.py +34 -0
  1136. venv/Lib/site-packages/requests_toolbelt/_compat.py +302 -0
  1137. venv/Lib/site-packages/requests_toolbelt/adapters/__init__.py +15 -0
  1138. venv/Lib/site-packages/requests_toolbelt/adapters/appengine.py +206 -0
  1139. venv/Lib/site-packages/requests_toolbelt/adapters/fingerprint.py +48 -0
  1140. venv/Lib/site-packages/requests_toolbelt/adapters/host_header_ssl.py +43 -0
  1141. venv/Lib/site-packages/requests_toolbelt/adapters/socket_options.py +129 -0
  1142. venv/Lib/site-packages/requests_toolbelt/adapters/source.py +67 -0
  1143. venv/Lib/site-packages/requests_toolbelt/adapters/ssl.py +66 -0
  1144. venv/Lib/site-packages/requests_toolbelt/adapters/x509.py +196 -0
  1145. venv/Lib/site-packages/requests_toolbelt/auth/__init__.py +0 -0
  1146. venv/Lib/site-packages/requests_toolbelt/auth/_digest_auth_compat.py +29 -0
  1147. venv/Lib/site-packages/requests_toolbelt/auth/guess.py +146 -0
  1148. venv/Lib/site-packages/requests_toolbelt/auth/handler.py +142 -0
  1149. venv/Lib/site-packages/requests_toolbelt/auth/http_proxy_digest.py +103 -0
  1150. venv/Lib/site-packages/requests_toolbelt/cookies/__init__.py +0 -0
  1151. venv/Lib/site-packages/requests_toolbelt/cookies/forgetful.py +7 -0
  1152. venv/Lib/site-packages/requests_toolbelt/downloadutils/__init__.py +0 -0
  1153. venv/Lib/site-packages/requests_toolbelt/downloadutils/stream.py +176 -0
  1154. venv/Lib/site-packages/requests_toolbelt/downloadutils/tee.py +123 -0
  1155. venv/Lib/site-packages/requests_toolbelt/exceptions.py +25 -0
  1156. venv/Lib/site-packages/requests_toolbelt/multipart/__init__.py +31 -0
  1157. venv/Lib/site-packages/requests_toolbelt/multipart/decoder.py +156 -0
  1158. venv/Lib/site-packages/requests_toolbelt/multipart/encoder.py +655 -0
  1159. venv/Lib/site-packages/requests_toolbelt/sessions.py +89 -0
  1160. venv/Lib/site-packages/requests_toolbelt/streaming_iterator.py +116 -0
  1161. venv/Lib/site-packages/requests_toolbelt/threaded/__init__.py +97 -0
  1162. venv/Lib/site-packages/requests_toolbelt/threaded/pool.py +211 -0
  1163. venv/Lib/site-packages/requests_toolbelt/threaded/thread.py +53 -0
  1164. venv/Lib/site-packages/requests_toolbelt/utils/__init__.py +0 -0
  1165. venv/Lib/site-packages/requests_toolbelt/utils/deprecated.py +91 -0
  1166. venv/Lib/site-packages/requests_toolbelt/utils/dump.py +198 -0
  1167. venv/Lib/site-packages/requests_toolbelt/utils/formdata.py +108 -0
  1168. venv/Lib/site-packages/requests_toolbelt/utils/user_agent.py +143 -0
  1169. venv/Lib/site-packages/rfc3986/__init__.py +53 -0
  1170. venv/Lib/site-packages/rfc3986/_mixin.py +373 -0
  1171. venv/Lib/site-packages/rfc3986/abnf_regexp.py +275 -0
  1172. venv/Lib/site-packages/rfc3986/api.py +104 -0
  1173. venv/Lib/site-packages/rfc3986/builder.py +388 -0
  1174. venv/Lib/site-packages/rfc3986/compat.py +59 -0
  1175. venv/Lib/site-packages/rfc3986/exceptions.py +120 -0
  1176. venv/Lib/site-packages/rfc3986/iri.py +161 -0
  1177. venv/Lib/site-packages/rfc3986/misc.py +131 -0
  1178. venv/Lib/site-packages/rfc3986/normalizers.py +171 -0
  1179. venv/Lib/site-packages/rfc3986/parseresult.py +474 -0
  1180. venv/Lib/site-packages/rfc3986/uri.py +160 -0
  1181. venv/Lib/site-packages/rfc3986/validators.py +440 -0
  1182. venv/Lib/site-packages/rich/__init__.py +177 -0
  1183. venv/Lib/site-packages/rich/__main__.py +245 -0
  1184. venv/Lib/site-packages/rich/_cell_widths.py +454 -0
  1185. venv/Lib/site-packages/rich/_emoji_codes.py +3610 -0
  1186. venv/Lib/site-packages/rich/_emoji_replace.py +32 -0
  1187. venv/Lib/site-packages/rich/_export_format.py +76 -0
  1188. venv/Lib/site-packages/rich/_extension.py +10 -0
  1189. venv/Lib/site-packages/rich/_fileno.py +24 -0
  1190. venv/Lib/site-packages/rich/_inspect.py +268 -0
  1191. venv/Lib/site-packages/rich/_log_render.py +94 -0
  1192. venv/Lib/site-packages/rich/_loop.py +43 -0
  1193. venv/Lib/site-packages/rich/_null_file.py +69 -0
  1194. venv/Lib/site-packages/rich/_palettes.py +309 -0
  1195. venv/Lib/site-packages/rich/_pick.py +17 -0
  1196. venv/Lib/site-packages/rich/_ratio.py +153 -0
  1197. venv/Lib/site-packages/rich/_spinners.py +482 -0
  1198. venv/Lib/site-packages/rich/_stack.py +16 -0
  1199. venv/Lib/site-packages/rich/_timer.py +19 -0
  1200. venv/Lib/site-packages/rich/_win32_console.py +661 -0
  1201. venv/Lib/site-packages/rich/_windows.py +71 -0
  1202. venv/Lib/site-packages/rich/_windows_renderer.py +56 -0
  1203. venv/Lib/site-packages/rich/_wrap.py +93 -0
  1204. venv/Lib/site-packages/rich/abc.py +33 -0
  1205. venv/Lib/site-packages/rich/align.py +306 -0
  1206. venv/Lib/site-packages/rich/ansi.py +241 -0
  1207. venv/Lib/site-packages/rich/bar.py +93 -0
  1208. venv/Lib/site-packages/rich/box.py +474 -0
  1209. venv/Lib/site-packages/rich/cells.py +174 -0
  1210. venv/Lib/site-packages/rich/color.py +621 -0
  1211. venv/Lib/site-packages/rich/color_triplet.py +38 -0
  1212. venv/Lib/site-packages/rich/columns.py +187 -0
  1213. venv/Lib/site-packages/rich/console.py +2680 -0
  1214. venv/Lib/site-packages/rich/constrain.py +37 -0
  1215. venv/Lib/site-packages/rich/containers.py +167 -0
  1216. venv/Lib/site-packages/rich/control.py +219 -0
  1217. venv/Lib/site-packages/rich/default_styles.py +193 -0
  1218. venv/Lib/site-packages/rich/diagnose.py +39 -0
  1219. venv/Lib/site-packages/rich/emoji.py +91 -0
  1220. venv/Lib/site-packages/rich/errors.py +34 -0
  1221. venv/Lib/site-packages/rich/file_proxy.py +57 -0
  1222. venv/Lib/site-packages/rich/filesize.py +88 -0
  1223. venv/Lib/site-packages/rich/highlighter.py +232 -0
  1224. venv/Lib/site-packages/rich/json.py +139 -0
  1225. venv/Lib/site-packages/rich/jupyter.py +101 -0
  1226. venv/Lib/site-packages/rich/layout.py +442 -0
  1227. venv/Lib/site-packages/rich/live.py +400 -0
  1228. venv/Lib/site-packages/rich/live_render.py +106 -0
  1229. venv/Lib/site-packages/rich/logging.py +297 -0
  1230. venv/Lib/site-packages/rich/markdown.py +779 -0
  1231. venv/Lib/site-packages/rich/markup.py +251 -0
  1232. venv/Lib/site-packages/rich/measure.py +151 -0
  1233. venv/Lib/site-packages/rich/padding.py +141 -0
  1234. venv/Lib/site-packages/rich/pager.py +34 -0
  1235. venv/Lib/site-packages/rich/palette.py +100 -0
  1236. venv/Lib/site-packages/rich/panel.py +317 -0
  1237. venv/Lib/site-packages/rich/pretty.py +1016 -0
  1238. venv/Lib/site-packages/rich/progress.py +1715 -0
  1239. venv/Lib/site-packages/rich/progress_bar.py +223 -0
  1240. venv/Lib/site-packages/rich/prompt.py +400 -0
  1241. venv/Lib/site-packages/rich/protocol.py +42 -0
  1242. venv/Lib/site-packages/rich/py.typed +0 -0
  1243. venv/Lib/site-packages/rich/region.py +10 -0
  1244. venv/Lib/site-packages/rich/repr.py +149 -0
  1245. venv/Lib/site-packages/rich/rule.py +130 -0
  1246. venv/Lib/site-packages/rich/scope.py +86 -0
  1247. venv/Lib/site-packages/rich/screen.py +54 -0
  1248. venv/Lib/site-packages/rich/segment.py +752 -0
  1249. venv/Lib/site-packages/rich/spinner.py +132 -0
  1250. venv/Lib/site-packages/rich/status.py +131 -0
  1251. venv/Lib/site-packages/rich/style.py +792 -0
  1252. venv/Lib/site-packages/rich/styled.py +42 -0
  1253. venv/Lib/site-packages/rich/syntax.py +985 -0
  1254. venv/Lib/site-packages/rich/table.py +1006 -0
  1255. venv/Lib/site-packages/rich/terminal_theme.py +153 -0
  1256. venv/Lib/site-packages/rich/text.py +1361 -0
  1257. venv/Lib/site-packages/rich/theme.py +115 -0
  1258. venv/Lib/site-packages/rich/themes.py +5 -0
  1259. venv/Lib/site-packages/rich/traceback.py +899 -0
  1260. venv/Lib/site-packages/rich/tree.py +257 -0
  1261. venv/Lib/site-packages/setup_sdist.py +69 -0
  1262. venv/Lib/site-packages/twine/__init__.py +54 -0
  1263. venv/Lib/site-packages/twine/__main__.py +54 -0
  1264. venv/Lib/site-packages/twine/auth.py +307 -0
  1265. venv/Lib/site-packages/twine/cli.py +139 -0
  1266. venv/Lib/site-packages/twine/commands/__init__.py +93 -0
  1267. venv/Lib/site-packages/twine/commands/check.py +195 -0
  1268. venv/Lib/site-packages/twine/commands/register.py +87 -0
  1269. venv/Lib/site-packages/twine/commands/upload.py +253 -0
  1270. venv/Lib/site-packages/twine/distribution.py +8 -0
  1271. venv/Lib/site-packages/twine/exceptions.py +175 -0
  1272. venv/Lib/site-packages/twine/package.py +403 -0
  1273. venv/Lib/site-packages/twine/py.typed +0 -0
  1274. venv/Lib/site-packages/twine/repository.py +246 -0
  1275. venv/Lib/site-packages/twine/sdist.py +83 -0
  1276. venv/Lib/site-packages/twine/settings.py +360 -0
  1277. venv/Lib/site-packages/twine/utils.py +387 -0
  1278. venv/Lib/site-packages/twine/wheel.py +81 -0
  1279. venv/Lib/site-packages/urllib3/__init__.py +211 -0
  1280. venv/Lib/site-packages/urllib3/_base_connection.py +165 -0
  1281. venv/Lib/site-packages/urllib3/_collections.py +479 -0
  1282. venv/Lib/site-packages/urllib3/_request_methods.py +278 -0
  1283. venv/Lib/site-packages/urllib3/_version.py +21 -0
  1284. venv/Lib/site-packages/urllib3/connection.py +1093 -0
  1285. venv/Lib/site-packages/urllib3/connectionpool.py +1178 -0
  1286. venv/Lib/site-packages/urllib3/contrib/__init__.py +0 -0
  1287. venv/Lib/site-packages/urllib3/contrib/emscripten/__init__.py +16 -0
  1288. venv/Lib/site-packages/urllib3/contrib/emscripten/connection.py +255 -0
  1289. venv/Lib/site-packages/urllib3/contrib/emscripten/fetch.py +728 -0
  1290. venv/Lib/site-packages/urllib3/contrib/emscripten/request.py +22 -0
  1291. venv/Lib/site-packages/urllib3/contrib/emscripten/response.py +277 -0
  1292. venv/Lib/site-packages/urllib3/contrib/pyopenssl.py +564 -0
  1293. venv/Lib/site-packages/urllib3/contrib/socks.py +228 -0
  1294. venv/Lib/site-packages/urllib3/exceptions.py +335 -0
  1295. venv/Lib/site-packages/urllib3/fields.py +341 -0
  1296. venv/Lib/site-packages/urllib3/filepost.py +89 -0
  1297. venv/Lib/site-packages/urllib3/http2/__init__.py +53 -0
  1298. venv/Lib/site-packages/urllib3/http2/connection.py +356 -0
  1299. venv/Lib/site-packages/urllib3/http2/probe.py +87 -0
  1300. venv/Lib/site-packages/urllib3/poolmanager.py +653 -0
  1301. venv/Lib/site-packages/urllib3/py.typed +2 -0
  1302. venv/Lib/site-packages/urllib3/response.py +1307 -0
  1303. venv/Lib/site-packages/urllib3/util/__init__.py +42 -0
  1304. venv/Lib/site-packages/urllib3/util/connection.py +137 -0
  1305. venv/Lib/site-packages/urllib3/util/proxy.py +43 -0
  1306. venv/Lib/site-packages/urllib3/util/request.py +266 -0
  1307. venv/Lib/site-packages/urllib3/util/response.py +101 -0
  1308. venv/Lib/site-packages/urllib3/util/retry.py +533 -0
  1309. venv/Lib/site-packages/urllib3/util/ssl_.py +524 -0
  1310. venv/Lib/site-packages/urllib3/util/ssl_match_hostname.py +159 -0
  1311. venv/Lib/site-packages/urllib3/util/ssltransport.py +271 -0
  1312. venv/Lib/site-packages/urllib3/util/timeout.py +275 -0
  1313. venv/Lib/site-packages/urllib3/util/url.py +469 -0
  1314. venv/Lib/site-packages/urllib3/util/util.py +42 -0
  1315. venv/Lib/site-packages/urllib3/util/wait.py +124 -0
  1316. venv/Lib/site-packages/win32ctypes/__init__.py +8 -0
  1317. venv/Lib/site-packages/win32ctypes/core/__init__.py +60 -0
  1318. venv/Lib/site-packages/win32ctypes/core/_winerrors.py +9 -0
  1319. venv/Lib/site-packages/win32ctypes/core/cffi/__init__.py +11 -0
  1320. venv/Lib/site-packages/win32ctypes/core/cffi/_authentication.py +172 -0
  1321. venv/Lib/site-packages/win32ctypes/core/cffi/_common.py +29 -0
  1322. venv/Lib/site-packages/win32ctypes/core/cffi/_dll.py +30 -0
  1323. venv/Lib/site-packages/win32ctypes/core/cffi/_nl_support.py +18 -0
  1324. venv/Lib/site-packages/win32ctypes/core/cffi/_resource.py +132 -0
  1325. venv/Lib/site-packages/win32ctypes/core/cffi/_system_information.py +32 -0
  1326. venv/Lib/site-packages/win32ctypes/core/cffi/_time.py +18 -0
  1327. venv/Lib/site-packages/win32ctypes/core/cffi/_util.py +105 -0
  1328. venv/Lib/site-packages/win32ctypes/core/compat.py +10 -0
  1329. venv/Lib/site-packages/win32ctypes/core/ctypes/__init__.py +11 -0
  1330. venv/Lib/site-packages/win32ctypes/core/ctypes/_authentication.py +122 -0
  1331. venv/Lib/site-packages/win32ctypes/core/ctypes/_common.py +53 -0
  1332. venv/Lib/site-packages/win32ctypes/core/ctypes/_dll.py +21 -0
  1333. venv/Lib/site-packages/win32ctypes/core/ctypes/_nl_support.py +12 -0
  1334. venv/Lib/site-packages/win32ctypes/core/ctypes/_resource.py +148 -0
  1335. venv/Lib/site-packages/win32ctypes/core/ctypes/_system_information.py +36 -0
  1336. venv/Lib/site-packages/win32ctypes/core/ctypes/_time.py +15 -0
  1337. venv/Lib/site-packages/win32ctypes/core/ctypes/_util.py +78 -0
  1338. venv/Lib/site-packages/win32ctypes/pywin32/__init__.py +12 -0
  1339. venv/Lib/site-packages/win32ctypes/pywin32/pywintypes.py +67 -0
  1340. venv/Lib/site-packages/win32ctypes/pywin32/win32api.py +294 -0
  1341. venv/Lib/site-packages/win32ctypes/pywin32/win32cred.py +145 -0
  1342. venv/Lib/site-packages/win32ctypes/pywintypes.py +13 -0
  1343. venv/Lib/site-packages/win32ctypes/tests/__init__.py +21 -0
  1344. venv/Lib/site-packages/win32ctypes/tests/test_backends.py +36 -0
  1345. venv/Lib/site-packages/win32ctypes/tests/test_win32api.py +304 -0
  1346. venv/Lib/site-packages/win32ctypes/tests/test_win32cred.py +230 -0
  1347. venv/Lib/site-packages/win32ctypes/version.py +1 -0
  1348. venv/Lib/site-packages/win32ctypes/win32api.py +13 -0
  1349. venv/Lib/site-packages/win32ctypes/win32cred.py +13 -0
  1350. android_notify-1.59.3.dist-info/RECORD +0 -12
  1351. {android_notify-1.59.3.dist-info → android_notify-1.60.0.dist-info}/WHEEL +0 -0
android_notify/sword.py CHANGED
@@ -1,961 +1,1043 @@
1
- """This Module Contain Class for creating Notification With Java"""
2
- import traceback
3
- import os,re
4
- import threading
5
-
6
-
7
- from .an_types import Importance
8
- from .an_utils import can_accept_arguments
9
- from .styles import NotificationStyles
10
- from .base import BaseNotification
11
- DEV=0
12
- ON_ANDROID = False
13
-
14
- # noinspection PyBroadException
15
- try:
16
- # Android Imports
17
- from jnius import autoclass,cast
18
- from android import activity
19
- from android.config import ACTIVITY_CLASS_NAME
20
- from android.runnable import run_on_ui_thread
21
-
22
- try:
23
- from android import config
24
- ns = config.JAVA_NAMESPACE
25
- # print('This is Java name space:',ns)
26
- except (ImportError,AttributeError):
27
- ns='org.kivy.android'
28
-
29
- # Get the required Java classes needs to on android to import
30
- Bundle = autoclass('android.os.Bundle')
31
- PythonActivity = autoclass(ns+'.PythonActivity')
32
- String = autoclass('java.lang.String')
33
- Intent = autoclass('android.content.Intent')
34
- PendingIntent = autoclass('android.app.PendingIntent')
35
- context = PythonActivity.mActivity
36
- BitmapFactory = autoclass('android.graphics.BitmapFactory')
37
- BuildVersion = autoclass('android.os.Build$VERSION')
38
- VersionCodes = autoclass('android.os.Build$VERSION_CODES')
39
- NotificationManager = autoclass('android.app.NotificationManager')
40
- NotificationChannel = autoclass('android.app.NotificationChannel')
41
- IconCompat = autoclass('androidx.core.graphics.drawable.IconCompat')
42
- ON_ANDROID = True
43
- except Exception as e:
44
- if hasattr(e,'name') and e.name != 'android':
45
- print('Exception: ',e)
46
- print(traceback.format_exc())
47
-
48
- MESSAGE='This Package Only Runs on Android !!! ---> Check "https://github.com/Fector101/android_notify/" to see design patterns and more info.'
49
- # from .types_idea import *
50
- # print(MESSAGE) Already Printing in core.py
51
-
52
- # This is so no crashes when developing on PC
53
- from .an_utils import run_on_ui_thread
54
-
55
- if ON_ANDROID:
56
- try:
57
- from android.permissions import request_permissions, Permission,check_permission
58
- from android.storage import app_storage_path
59
-
60
- NotificationManagerCompat = autoclass('androidx.core.app.NotificationManagerCompat')
61
- NotificationCompat = autoclass('androidx.core.app.NotificationCompat')
62
-
63
- # Notification Design
64
- NotificationCompatBuilder = autoclass('androidx.core.app.NotificationCompat$Builder')
65
- NotificationCompatBigTextStyle = autoclass('androidx.core.app.NotificationCompat$BigTextStyle')
66
- NotificationCompatBigPictureStyle = autoclass('androidx.core.app.NotificationCompat$BigPictureStyle')
67
- NotificationCompatInboxStyle = autoclass('androidx.core.app.NotificationCompat$InboxStyle')
68
- # NotificationCompatDecoratedCustomViewStyle = autoclass('androidx.core.app.NotificationCompat$DecoratedCustomViewStyle')
69
- except Exception as e:
70
- print(e)
71
- print("""
72
- Dependency Error: Add the following in buildozer.spec:
73
- * android.gradle_dependencies = androidx.core:core-ktx:1.15.0, androidx.core:core:1.6.0
74
- * android.enable_androidx = True
75
- * android.permissions = POST_NOTIFICATIONS
76
- """)
77
-
78
- class Notification(BaseNotification):
79
- """
80
- Send a notification on Android.
81
-
82
- :param title: Title of the notification.
83
- :param message: Message body.
84
- :param style: Style of the notification
85
- ('simple', 'progress', 'big_text', 'inbox', 'big_picture', 'large_icon', 'both_imgs').
86
- both_imgs == using lager icon and big picture
87
- :param big_picture_path: Relative Path to the image resource.
88
- :param large_icon_path: Relative Path to the image resource.
89
- :param progress_current_value: integer To set progress bar current value.
90
- :param progress_max_value: integer To set Max range for progress bar.
91
- :param body: large text For `big_Text` style, while `message` acts as subtitle.
92
- :param lines_txt: text separated by newLine symbol For `inbox` style `use addLine method instead`
93
- ---
94
- (Advance Options)
95
- :param id: Pass in Old 'id' to use old instance
96
- :param callback: Function for notification Click.
97
- :param channel_name: - str Defaults to "Default Channel"
98
- :param channel_id: - str Defaults to "default_channel"
99
- ---
100
- (Options during Dev On PC)
101
- :param logs: - Bool Defaults to True
102
- """
103
-
104
- notification_ids = [0]
105
- button_ids=[0]
106
- btns_box={}
107
- main_functions={}
108
-
109
- # During Development (When running on PC)
110
- BaseNotification.logs=not ON_ANDROID
111
- def __init__(self,**kwargs): #@dataclass already does work
112
- super().__init__(**kwargs)
113
-
114
- self.__id = self.id or self.__get_unique_id() # Different use from self.name all notifications require `integers` id's not `strings`
115
- self.id = self.__id # To use same Notification in different instances
116
-
117
- # To Track progressbar last update (According to Android Docs Don't update bar to often, I also faced so issues when doing that)
118
- self.__update_timer = None
119
- self.__progress_bar_msg = ''
120
- self.__progress_bar_title = ''
121
- self.__cooldown = 0
122
-
123
- self.__built_parameter_filled=False
124
- self.__using_set_priority_method=False
125
-
126
- # For components
127
- self.__lines = []
128
-
129
- self.__format_channel(self.channel_name, self.channel_id)
130
- if not ON_ANDROID:
131
- return
132
-
133
- NotificationHandler.asks_permission()
134
- notification_service = context.getSystemService(context.NOTIFICATION_SERVICE)
135
- self.notification_manager = cast(NotificationManager, notification_service)
136
- self.__builder = NotificationCompatBuilder(context, self.channel_id)
137
-
138
- def addLine(self,text:str):
139
- self.__lines.append(text)
140
-
141
- def cancel(self,_id=0):
142
- """
143
- Removes a Notification instance from tray
144
- :param _id: not required uses Notification instance id as default
145
- """
146
- if ON_ANDROID:
147
- self.notification_manager.cancel(_id or self.__id)
148
- if self.logs:
149
- print('Removed Notification.')
150
-
151
- @classmethod
152
- def cancelAll(cls):
153
- """
154
- Removes all app Notifications from tray
155
- """
156
- if ON_ANDROID:
157
- cls.__return_notification_manger().cancelAll()
158
- if cls.logs:
159
- print('Removed All Notifications.')
160
-
161
- @classmethod
162
- def createChannel(cls, id, name:str, description='',importance:Importance='urgent'):
163
- """
164
- Creates a user visible toggle button for specific notifications, Required For Android 8.0+
165
- :param id: Used to send other notifications later through same channel.
166
- :param name: user-visible channel name.
167
- :param description: user-visible detail about channel (Not required defaults to empty str).
168
- :param importance: ['urgent', 'high', 'medium', 'low', 'none'] defaults to 'urgent' i.e. makes a sound and shows briefly
169
- :return: boolean if channel created
170
- """
171
-
172
- if not ON_ANDROID:
173
- return False
174
-
175
- notification_manager=cls.__return_notification_manger()
176
- android_importance_value = cls.__get_android_importance(importance)
177
-
178
- if BuildVersion.SDK_INT >= 26 and notification_manager.getNotificationChannel(id) is None:
179
- channel = NotificationChannel(id, name, android_importance_value)
180
- if description:
181
- channel.setDescription(description)
182
- notification_manager.createNotificationChannel(channel)
183
- return True
184
- return False
185
-
186
- @classmethod
187
- def deleteChannel(cls, channel_id):
188
- """Delete a Channel Matching channel_id"""
189
- if not ON_ANDROID:
190
- return None
191
-
192
- cls.__return_notification_manger().deleteNotificationChannel(channel_id)
193
-
194
- @classmethod
195
- def deleteAllChannel(cls):
196
- """Deletes all notification channel
197
- :returns amount deleted
198
- """
199
-
200
- amount = 0
201
- if not ON_ANDROID:
202
- return amount
203
-
204
- notification_manager = cls.__return_notification_manger()
205
- channels = cls.getChannels()
206
- for index in range(channels.size()):
207
- amount += 1
208
- channel = channels.get(index)
209
- channel_id = channel.getId()
210
- notification_manager.deleteNotificationChannel(channel_id)
211
- return amount
212
-
213
- def refresh(self):
214
- """TO apply new components on notification"""
215
- if self.__built_parameter_filled:
216
- # Don't dispatch before filling required values `self.__create_basic_notification`
217
- # We generally shouldn't dispatch till user call .send()
218
- self.__applyNewLinesIfAny()
219
- self.__dispatch_notification()
220
-
221
- def setBigPicture(self,path):
222
- """
223
- set a Big Picture at the bottom
224
- :param path: can be `Relative Path` or `URL`
225
- :return:
226
- """
227
- if ON_ANDROID:
228
- self.__build_img(path, NotificationStyles.BIG_PICTURE)
229
- elif self.logs:
230
- # When on android there are other logs
231
- print('Done setting big picture')
232
-
233
- def setSmallIcon(self,path):
234
- """
235
- sets small icon to the top left
236
- :param path: can be `Relative Path` or `URL`
237
- :return:
238
- """
239
- if ON_ANDROID:
240
- self.__insert_app_icon(path)
241
- elif self.logs:
242
- # When on android there are other logs
243
- print('Done setting small icon')
244
-
245
- def setLargeIcon(self,path):
246
- """
247
- sets Large icon to the right
248
- :param path: can be `Relative Path` or `URL`
249
- :return:
250
- """
251
- if ON_ANDROID:
252
- self.__build_img(path, NotificationStyles.LARGE_ICON)
253
- elif self.logs:
254
- #When on android there are other logs
255
- print('Done setting large icon')
256
-
257
- def setBigText(self,body):
258
- """Sets a big text for when drop down button is pressed
259
-
260
- :param body: The big text that will be displayed
261
- """
262
- if ON_ANDROID:
263
- big_text_style = NotificationCompatBigTextStyle()
264
- big_text_style.bigText(str(body))
265
- self.__builder.setStyle(big_text_style)
266
- elif self.logs:
267
- # When on android there are other logs
268
- print('Done setting big text')
269
-
270
- def showInfiniteProgressBar(self):
271
- """Displays an (Infinite) progress Bar in Notification, that continues loading indefinitely.
272
- Can be Removed By `removeProgressBar` Method
273
- """
274
- if self.logs:
275
- print('Showing infinite progressbar')
276
- if ON_ANDROID:
277
- self.__builder.setProgress(0,0, True)
278
- self.refresh()
279
-
280
- def updateTitle(self,new_title):
281
- """Changes Old Title
282
-
283
- Args:
284
- new_title (str): New Notification Title
285
- """
286
- self.title=str(new_title)
287
- if self.logs:
288
- print(f'new notification title: {self.title}')
289
- if ON_ANDROID:
290
- self.__builder.setContentTitle(String(self.title))
291
- self.refresh()
292
-
293
- def updateMessage(self,new_message):
294
- """Changes Old Message
295
-
296
- Args:
297
- new_message (str): New Notification Message
298
- """
299
- self.message=str(new_message)
300
- if self.logs:
301
- print(f'new notification message: {self.message}')
302
- if ON_ANDROID:
303
- self.__builder.setContentText(String(self.message))
304
- self.refresh()
305
-
306
- def updateProgressBar(self,current_value:int,message:str='',title:str='',cooldown=0.5):
307
- """Updates progress bar current value
308
-
309
- Args:
310
- current_value (int): the value from progressbar current progress
311
- message (str): defaults to last message
312
- title (str): defaults to last title
313
- cooldown (float, optional): Little Time to Wait before change actually reflects, to avoid android Ignoring Change, Defaults to 0.5secs
314
-
315
- NOTE: There is a 0.5sec delay for value change, if updating title,msg with progressbar frequently pass them in too to avoid update issues
316
- """
317
-
318
- # replacing new values for when timer is called
319
- self.progress_current_value = current_value
320
- self.__progress_bar_msg = message
321
- self.__progress_bar_title = title
322
-
323
- if self.__update_timer and self.__update_timer.is_alive():
324
- # Make Logs too Dirty
325
- # if self.logs:
326
- # remaining = self.__cooldown - (time.time() - self.__timer_start_time)
327
- # print(f'Progressbar update too soon, waiting for cooldown ({max(0, remaining):.2f}s)')
328
- return
329
-
330
- def delayed_update():
331
- if self.__update_timer is None: # Ensure we are not executing an old timer
332
- if self.logs:
333
- print('ProgressBar update skipped: bar has been removed.')
334
- return
335
- if self.logs:
336
- print(f'Progress Bar Update value: {self.progress_current_value}')
337
-
338
- if not ON_ANDROID:
339
- self.__update_timer = None
340
- return
341
-
342
- self.__builder.setProgress(self.progress_max_value, self.progress_current_value, False)
343
-
344
- if self.__progress_bar_msg:
345
- self.updateMessage(self.__progress_bar_msg)
346
- if self.__progress_bar_title:
347
- self.updateTitle(self.__progress_bar_title)
348
-
349
- self.refresh()
350
- self.__update_timer = None
351
-
352
-
353
- # Start a new timer that runs after 0.5 seconds
354
- # self.__timer_start_time = time.time() # for logs
355
- self.__cooldown = cooldown
356
- self.__update_timer = threading.Timer(cooldown, delayed_update)
357
- self.__update_timer.start()
358
-
359
- def removeProgressBar(self,message='',show_on_update=True, title:str='',cooldown=0.5):
360
- """Removes Progress Bar from Notification
361
-
362
- Args:
363
- message (str, optional): notification message. Defaults to 'last message'.
364
- show_on_update (bool, optional): To show notification briefly when progressbar removed. Defaults to True.
365
- title (str, optional): notification title. Defaults to 'last title'.
366
- cooldown (float, optional): Little Time to Wait before change actually reflects, to avoid android Ignoring Change, Defaults to 0.5secs
367
-
368
- In-Built Delay of 0.5sec According to Android Docs Don't Update Progressbar too Frequently
369
- """
370
-
371
- # To Cancel any queued timer from `updateProgressBar` method and to avoid race effect incase it somehow gets called while in this method
372
- # Avoiding Running `updateProgressBar.delayed_update` at all
373
- # so didn't just set `self.__progress_bar_title` and `self.progress_current_value` to 0
374
- if self.__update_timer:
375
- # Make Logs too Dirty
376
- # if self.logs:
377
- # print('cancelled progressbar stream update because about to remove',self.progress_current_value)
378
- self.__update_timer.cancel()
379
- self.__update_timer = None
380
-
381
-
382
- def delayed_update():
383
- if self.logs:
384
- msg = message or self.message
385
- title_=title or self.title
386
- print(f'removed progress bar with message: {msg} and title: {title_}')
387
-
388
- if not ON_ANDROID:
389
- return
390
-
391
- if message:
392
- self.updateMessage(message)
393
- if title:
394
- self.updateTitle(title)
395
- self.__builder.setOnlyAlertOnce(not show_on_update)
396
- self.__builder.setProgress(0, 0, False)
397
- self.refresh()
398
-
399
- # Incase `self.updateProgressBar delayed_update` is called right before this method, so android doesn't bounce update
400
- threading.Timer(cooldown, delayed_update).start()
401
-
402
- def setPriority(self,importance:Importance):
403
- """
404
- For devices less than android 8
405
- :param importance: ['urgent', 'high', 'medium', 'low', 'none'] defaults to 'urgent' i.e. makes a sound and shows briefly
406
- :return:
407
- """
408
- self.__using_set_priority_method=True
409
- if ON_ANDROID:
410
- android_importance_value = self.__get_android_importance(importance)
411
- if not isinstance(android_importance_value, str): # Can be an empty str if importance='none'
412
- self.__builder.setPriority(android_importance_value)
413
-
414
- def send(self,silent:bool=False,persistent=False,close_on_click=True):
415
- """Sends notification
416
-
417
- Args:
418
- silent (bool): True if you don't want to show briefly on screen
419
- persistent (bool): True To not remove Notification When User hits clears All notifications button
420
- close_on_click (bool): True if you want Notification to be removed when clicked
421
- """
422
- self.silent= silent or self.silent
423
- if ON_ANDROID:
424
- self.__start_notification_build(persistent, close_on_click)
425
- self.__dispatch_notification()
426
-
427
- if self.logs:
428
- string_to_display=''
429
- print("\n Sent Notification!!!")
430
- for name,value in vars(self).items():
431
- if value and name in ["title", "message", "style", "body", "large_icon_path", "big_picture_path", "progress_current_value", "progress_max_value", "channel_name",'body','name']:
432
- if name == "progress_max_value":
433
- if self.style == NotificationStyles.PROGRESS:
434
- string_to_display += f'\n {name}: {value}'
435
- elif name == "body":
436
- if self.style == NotificationStyles.BIG_TEXT:
437
- string_to_display += f'\n {name}: {value}'
438
- else:
439
- string_to_display += f'\n {name}: {value}'
440
-
441
- string_to_display +="\n (Won't Print Logs When Complied,except if selected `Notification.logs=True`)"
442
- print(string_to_display)
443
- if DEV:
444
- print(f'channel_name: {self.channel_name}, Channel ID: {self.channel_id}, __id: {self.__id}')
445
-
446
- def addButton(self, text:str,on_release):
447
- """For adding action buttons
448
-
449
- Args:
450
- text (str): Text For Button
451
- on_release: function to be called when button is clicked
452
- """
453
- if self.logs:
454
- print('Added Button: ', text)
455
-
456
- if not ON_ANDROID:
457
- return
458
-
459
- btn_id= self.__get_id_for_button()
460
- action = f"BTN_ACTION_{btn_id}"
461
-
462
- action_intent = Intent(context, PythonActivity)
463
- action_intent.setAction(action)
464
- action_intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
465
- bundle = Bundle()
466
- bundle.putString("title", self.title or 'Title Placeholder')
467
- bundle.putInt("key_int", 123)
468
- action_intent.putExtras(bundle)
469
- action_intent.putExtra("button_id", btn_id)
470
-
471
- self.btns_box[action] = on_release
472
- # action_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP)
473
-
474
- if self.logs:
475
- print('Button id: ',btn_id)
476
- pending_action_intent = PendingIntent.getActivity(
477
- context,
478
- 0,
479
- action_intent,
480
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
481
- )
482
- # Convert text to CharSequence
483
- action_text = cast('java.lang.CharSequence', String(text))
484
-
485
-
486
-
487
- # Add action with proper types
488
- self.__builder.addAction(
489
- int(context.getApplicationInfo().icon), # Cast icon to int
490
- action_text, # CharSequence text
491
- pending_action_intent # PendingIntent
492
- )
493
- # Set content intent for notification tap
494
- self.__builder.setContentIntent(pending_action_intent)
495
-
496
- def removeButtons(self):
497
- """Removes all notification buttons
498
- """
499
- if ON_ANDROID:
500
- self.__builder.mActions.clear()
501
- self.refresh()
502
- if self.logs:
503
- print('Removed Notification Buttons')
504
-
505
- @run_on_ui_thread
506
- def addNotificationStyle(self,style:str,already_sent=False):
507
- """Adds Style to Notification
508
- Version 1.51.2+ Exposes method to Users (Note): Always try to Call On UI Thread
509
-
510
- Args:
511
- style (str): required style
512
- already_sent (bool,False): If notification was already sent
513
- """
514
-
515
- if not ON_ANDROID:
516
- # TODO for logs when not on android and style related to imgs extract app path from buildozer.spec and print
517
- return False
518
-
519
- if style == NotificationStyles.BIG_TEXT:
520
- self.setBigText(self.body)
521
-
522
- elif style == NotificationStyles.INBOX and self.lines_txt:
523
- lines = self.lines_txt.split("\n")
524
- self.setLines(lines)
525
-
526
- elif (style == NotificationStyles.LARGE_ICON and self.large_icon_path) or (style == NotificationStyles.BIG_PICTURE and self.big_picture_path):
527
- img = self.large_icon_path if style == NotificationStyles.LARGE_ICON else self.big_picture_path
528
- self.__build_img(img, style)
529
-
530
- elif style == NotificationStyles.BOTH_IMGS and (self.big_picture_path or self.large_icon_path):
531
- if self.big_picture_path:
532
- self.setBigPicture(self.big_picture_path)
533
- if self.large_icon_path:
534
- self.setLargeIcon(self.large_icon_path)
535
-
536
- elif style == NotificationStyles.PROGRESS:
537
- self.__builder.setProgress(self.progress_max_value, self.progress_current_value, False)
538
-
539
- if already_sent:
540
- self.refresh()
541
-
542
- return True
543
-
544
- def setLines(self, lines: list):
545
- """Pass in a list of strings to be used for lines"""
546
- if not lines:
547
- return
548
- if ON_ANDROID:
549
- inbox_style = NotificationCompatInboxStyle()
550
- for line in lines:
551
- inbox_style.addLine(str(line))
552
- self.__builder.setStyle(inbox_style)
553
- print('Set Lines: ', lines)
554
-
555
- if self.logs:
556
- print('Added Lines: ', lines)
557
-
558
- def __dispatch_notification(self):
559
- if NotificationHandler.has_permission():
560
- self.notification_manager.notify(self.__id, self.__builder.build())
561
- else:
562
- print('Permission not granted to send notifications')
563
- # Not asking for permission too frequently, This makes dialog popup to stop showing
564
- # NotificationHandler.asks_permission()
565
-
566
- def __start_notification_build(self, persistent, close_on_click):
567
- self.__create_basic_notification(persistent, close_on_click)
568
- if self.style not in ['simple','']:
569
- self.addNotificationStyle(self.style)
570
- self.__applyNewLinesIfAny()
571
-
572
- def __applyNewLinesIfAny(self):
573
- if self.__lines:
574
- self.setLines(self.__lines)
575
- self.__lines=[] # for refresh method to known when new lines added
576
-
577
- def __create_basic_notification(self, persistent, close_on_click):
578
- if BuildVersion.SDK_INT >= 26 and self.notification_manager.getNotificationChannel(self.channel_id) is None:
579
- self.createChannel(self.channel_id, self.channel_name)
580
- elif not self.__using_set_priority_method:
581
- self.setPriority('medium' if self.silent else 'urgent')
582
- # Build the notification
583
- # str() This is to prevent Error When user does Notification.title='blah' instead of Notification(title='blah'
584
- # TODO fix this by creating a on_title method in other versions
585
- self.__builder.setContentTitle(str(self.title))
586
- self.__builder.setContentText(str(self.message))
587
- self.__insert_app_icon()
588
- self.__builder.setDefaults(NotificationCompat.DEFAULT_ALL)
589
- self.__builder.setOnlyAlertOnce(True)
590
- self.__builder.setOngoing(persistent)
591
- self.__builder.setAutoCancel(close_on_click)
592
- self.__add_intent_to_open_app()
593
- self.__built_parameter_filled = True
594
-
595
- def __insert_app_icon(self,path=''):
596
- if BuildVersion.SDK_INT >= 23 and (path or self.app_icon not in ['','Defaults to package app icon']):
597
- # Bitmap Insert as Icon Not available below Android 6
598
- if self.logs:
599
- print('getting custom icon...')
600
- self.__set_icon_from_bitmap(path or self.app_icon)
601
- else:
602
- if self.logs:
603
- print('using default icon...')
604
- self.__builder.setSmallIcon(context.getApplicationInfo().icon)
605
-
606
- def __build_img(self, user_img, img_style):
607
- if user_img.startswith('http://') or user_img.startswith('https://'):
608
- def callback(bitmap_):
609
- self.__apply_notification_image(bitmap_,img_style)
610
- thread = threading.Thread(
611
- target=self.__get_bitmap_from_url,
612
- args=[user_img,callback]
613
- )
614
- thread.start()
615
- else:
616
- bitmap = self.__get_img_from_path(user_img)
617
- if bitmap:
618
- self.__apply_notification_image(bitmap, img_style)
619
-
620
- def __set_icon_from_bitmap(self, img_path):
621
- """Path can be a link or relative path"""
622
- if img_path.startswith('http://') or img_path.startswith('https://'):
623
- def callback(bitmap_):
624
- if bitmap_:
625
- icon_ = IconCompat.createWithBitmap(bitmap_)
626
- self.__builder.setSmallIcon(icon_)
627
- else:
628
- if self.logs:
629
- print('Using Default Icon as fallback......')
630
- self.__builder.setSmallIcon(context.getApplicationInfo().icon)
631
- threading.Thread(
632
- target=self.__get_bitmap_from_url,
633
- args=[img_path,callback]
634
- ).start()
635
- else:
636
- bitmap = self.__get_img_from_path(img_path)
637
- if bitmap:
638
- icon = IconCompat.createWithBitmap(bitmap)
639
- self.__builder.setSmallIcon(icon)
640
- else:
641
- if self.logs:
642
- app_folder=os.path.join(app_storage_path(),'app')
643
- img_absolute_path = os.path.join(app_folder, img_path)
644
- print(f'Failed getting img for custom notification icon defaulting to app icon\n absolute path {img_absolute_path}')
645
- self.__builder.setSmallIcon(context.getApplicationInfo().icon)
646
-
647
- @staticmethod
648
- def __get_img_from_path(relative_path):
649
- app_folder=os.path.join(app_storage_path(),'app')
650
- output_path = os.path.join(app_folder, relative_path)
651
- if not os.path.exists(output_path):
652
- print(f"\nImage not found at path: {app_folder}, (Local images gotten from App Path)")
653
- try:
654
- print("- These are the existing files in your app Folder:")
655
- print('['+', '.join(os.listdir(app_folder)) + ']')
656
- except Exception as could_not_get_files_in_path_error:
657
- print('Exception: ', could_not_get_files_in_path_error)
658
- print("Couldn't get Files in App Folder")
659
- return None
660
- # TODO test with a badly written Image and catch error
661
- Uri = autoclass('android.net.Uri')
662
- uri = Uri.parse(f"file://{output_path}")
663
- return BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
664
-
665
- def __get_bitmap_from_url(self, url, callback):
666
- """Gets Bitmap from url
667
-
668
- Args:
669
- url (str): img url
670
- callback (function): method to be called after thread done -passes in bitmap data as argument
671
- """
672
- if self.logs:
673
- print("getting Bitmap from URL---")
674
- try:
675
- URL = autoclass('java.net.URL')
676
- url = URL(url)
677
- connection = url.openConnection()
678
- connection.connect()
679
- input_stream = connection.getInputStream()
680
- bitmap = BitmapFactory.decodeStream(input_stream)
681
- input_stream.close()
682
- if bitmap:
683
- callback(bitmap)
684
- else:
685
- print('Error No Bitmap for small icon ------------')
686
- except Exception as extracting_bitmap_frm_URL_error:
687
- callback(None)
688
- # TODO get all types of JAVA Error that can fail here
689
- print('Error Type ',extracting_bitmap_frm_URL_error)
690
- print('Failed to get Bitmap from URL ',traceback.format_exc())
691
-
692
- @run_on_ui_thread
693
- def __apply_notification_image(self, bitmap, img_style):
694
- try:
695
- if img_style == NotificationStyles.BIG_PICTURE and bitmap:
696
- big_picture_style = NotificationCompatBigPictureStyle().bigPicture(bitmap)
697
- self.__builder.setStyle(big_picture_style)
698
- elif img_style == NotificationStyles.LARGE_ICON and bitmap:
699
- self.__builder.setLargeIcon(bitmap)
700
- # LargeIcon requires smallIcon to be already set
701
- # 'setLarge, setBigPic' tries to dispatch before filling required values `self.__create_basic_notification`
702
- self.refresh()
703
- if self.logs:
704
- print('Done adding image to notification-------')
705
- except Exception as notification_image_error:
706
- img = self.large_icon_path if img_style == NotificationStyles.LARGE_ICON else self.big_picture_path
707
- print(f'Failed adding Image of style: {img_style} || From path: {img}, Exception {notification_image_error}')
708
- print('could not get Img traceback: ',traceback.format_exc())
709
-
710
- def __add_intent_to_open_app(self):
711
- intent = Intent(context, PythonActivity)
712
- action = str(self.name or self.__id)
713
- intent.setAction(action)
714
- self.__add_data_to_intent(intent)
715
- self.main_functions[action]=self.callback
716
- intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
717
-
718
- pending_intent = PendingIntent.getActivity(
719
- context, 0,
720
- intent, PendingIntent.FLAG_IMMUTABLE if BuildVersion.SDK_INT >= 31 else PendingIntent.FLAG_UPDATE_CURRENT
721
- )
722
- self.__builder.setContentIntent(pending_intent)
723
-
724
- def __add_data_to_intent(self, intent):
725
- """Persist Some data to notification object for later use"""
726
- bundle = Bundle()
727
- bundle.putString("title", self.title or 'Title Placeholder')
728
- # bundle.putInt("notify_id", self.__id)
729
- bundle.putInt("notify_id", 101)
730
- intent.putExtras(bundle)
731
-
732
- def __get_id_for_button(self):
733
- btn_id = self.button_ids[-1] + 1
734
- self.button_ids.append(btn_id)
735
- return btn_id
736
-
737
- def __format_channel(self, channel_name:str='Default Channel',channel_id:str='default_channel'):
738
- """
739
- Formats and sets self.channel_name and self.channel_id to formatted version
740
- :param channel_name:
741
- :param channel_id:
742
- :return:
743
- """
744
- # Shorten channel name # android docs as at most 40 chars
745
- if channel_name != 'Default Channel':
746
- cleaned_name = channel_name.strip()
747
- self.channel_name = cleaned_name[:40] if cleaned_name else 'Default Channel'
748
-
749
- # If no channel_id then generating channel_id from passed in channel_name
750
- if channel_id == 'default_channel':
751
- generated_id = self.__generate_channel_id(channel_name)
752
- self.channel_id = generated_id
753
-
754
- @staticmethod
755
- def __generate_channel_id(channel_name: str) -> str:
756
- """
757
- Generate a readable and consistent channel ID from a channel name.
758
-
759
- Args:
760
- channel_name (str): The name of the notification channel.
761
-
762
- Returns:
763
- str: A sanitized channel ID.
764
- """
765
- # Normalize the channel name
766
- channel_id = channel_name.strip().lower()
767
- # Replace spaces and special characters with underscores
768
- channel_id = re.sub(r'[^a-z0-9]+', '_', channel_id)
769
- # Remove leading/trailing underscores
770
- channel_id = channel_id.strip('_')
771
- return channel_id[:50]
772
-
773
- def __get_unique_id(self):
774
- notification_id = self.notification_ids[-1] + 1
775
- self.notification_ids.append(notification_id)
776
- return notification_id
777
-
778
- @staticmethod
779
- def __return_notification_manger():
780
- notification_service = context.getSystemService(context.NOTIFICATION_SERVICE)
781
- return cast(NotificationManager, notification_service)
782
-
783
- @classmethod
784
- def getChannels(cls):
785
- """Return all existing channels"""
786
- if not ON_ANDROID:
787
- return []
788
-
789
- return cls.__return_notification_manger().getNotificationChannels()
790
-
791
- @staticmethod
792
- def __get_android_importance(importance:Importance):
793
- """
794
- Returns Android Importance Values
795
- :param importance: ['urgent','high','medium','low','none']
796
- :return: Android equivalent int or empty str
797
- """
798
- value=''
799
- if importance == 'urgent':
800
- value = NotificationCompat.PRIORITY_HIGH if BuildVersion.SDK_INT <= 25 else NotificationManagerCompat.IMPORTANCE_HIGH
801
- elif importance == 'high':
802
- value = NotificationCompat.PRIORITY_DEFAULT if BuildVersion.SDK_INT <= 25 else NotificationManagerCompat.IMPORTANCE_DEFAULT
803
- elif importance == 'medium':
804
- value = NotificationCompat.PRIORITY_LOW if BuildVersion.SDK_INT <= 25 else NotificationManagerCompat.IMPORTANCE_LOW
805
- elif importance == 'low':
806
- value = NotificationCompat.PRIORITY_MIN if BuildVersion.SDK_INT <= 25 else NotificationManagerCompat.IMPORTANCE_MIN
807
- elif importance == 'none':
808
- value = '' if BuildVersion.SDK_INT <= 25 else NotificationManagerCompat.IMPORTANCE_NONE
809
-
810
- return value
811
- # side-note 'medium' = NotificationCompat.PRIORITY_LOW and 'low' = NotificationCompat.PRIORITY_MIN # weird but from docs
812
- # TODO method to create channel groups
813
-
814
-
815
- class NotificationHandler:
816
- """For Notification Operations """
817
- __name = None
818
- __bound = False
819
- __requesting_permission=False
820
- @classmethod
821
- def get_name(cls):
822
- """Returns name or id str for Clicked Notification."""
823
- if not cls.is_on_android():
824
- return "Not on Android"
825
-
826
- saved_intent = cls.__name
827
- cls.__name = None # so value won't be set when opening app not from notification
828
- # print('saved_intent ',saved_intent)
829
- # if not saved_intent or (isinstance(saved_intent, str) and saved_intent.startswith("android.intent")):
830
- # All other notifications are not None after First notification opens app
831
- # NOTE these notifications are also from Last time app was opened and they Still Give Value after first one opens App
832
- # TODO Find a way to get intent when App if Swiped From recents
833
- # Below action is always None
834
- # __PythonActivity = autoclass(ACTIVITY_CLASS_NAME)
835
- # __mactivity = __PythonActivity.mActivity
836
- # __context = cast('android.content.Context', __mactivity)
837
- # __Intent = autoclass('android.content.Intent')
838
- # __intent = __Intent(__context, __PythonActivity)
839
- # action = __intent.getAction()
840
- # print('Start up Intent ----', action)
841
- # print('start Up Title --->',__intent.getStringExtra("title"))
842
-
843
- return saved_intent
844
-
845
- @classmethod
846
- def __notification_handler(cls, intent):
847
- """Calls Function Attached to notification on click.
848
- Don't Call this function manual, it's Already Attach to Notification.
849
-
850
- Sets self.__name #action of Notification that was clicked from Notification.name or Notification.id
851
- """
852
- if not cls.is_on_android():
853
- return "Not on Android"
854
- buttons_object=Notification.btns_box
855
- notifty_functions=Notification.main_functions
856
- if DEV:
857
- print("notifty_functions ",notifty_functions)
858
- print("buttons_object", buttons_object)
859
- try:
860
- action = intent.getAction()
861
- cls.__name = action
862
-
863
- # print("The Action --> ",action)
864
- if action == "android.intent.action.MAIN": # Not Open From Notification
865
- cls.__name = None
866
- return 'Not notification'
867
-
868
- print(intent.getStringExtra("title"))
869
- try:
870
- if action in notifty_functions and notifty_functions[action]:
871
- notifty_functions[action]()
872
- elif action in buttons_object:
873
- buttons_object[action]()
874
- except Exception as notification_handler_function_error:
875
- print("Error Type ",notification_handler_function_error)
876
- print('Failed to run function: ', traceback.format_exc())
877
- except Exception as extracting_notification_props_error:
878
- print('Notify Handler Failed ',extracting_notification_props_error)
879
-
880
- @classmethod
881
- def bindNotifyListener(cls):
882
- """This Creates a Listener for All Notification Clicks and Functions"""
883
- if not cls.is_on_android():
884
- return "Not on Android"
885
- #TODO keep trying BroadcastReceiver
886
- if cls.__bound:
887
- print("binding done already ")
888
- return True
889
- try:
890
- activity.bind(on_new_intent=cls.__notification_handler)
891
- cls.__bound = True
892
- return True
893
- except Exception as binding_listener_error:
894
- print('Failed to bin notifications listener',binding_listener_error)
895
- return False
896
-
897
- @classmethod
898
- def unbindNotifyListener(cls):
899
- """Removes Listener for Notifications Click"""
900
- if not cls.is_on_android():
901
- return "Not on Android"
902
-
903
- #Beta TODO use BroadcastReceiver
904
- try:
905
- activity.unbind(on_new_intent=cls.__notification_handler)
906
- return True
907
- except Exception as unbinding_listener_error:
908
- print("Failed to unbind notifications listener: ",unbinding_listener_error)
909
- return False
910
-
911
- @staticmethod
912
- def is_on_android():
913
- """Utility to check if the app is running on Android."""
914
- return ON_ANDROID
915
-
916
- @staticmethod
917
- def has_permission():
918
- """
919
- Checks if device has permission to send notifications
920
- returns True if device has permission
921
- """
922
- if not ON_ANDROID:
923
- return True
924
- return check_permission(Permission.POST_NOTIFICATIONS)
925
-
926
- @classmethod
927
- @run_on_ui_thread
928
- def asks_permission(cls,callback=None):
929
- """
930
- Ask for permission to send notifications if needed.
931
- Passes True to callback if access granted
932
- """
933
- if cls.__requesting_permission or not ON_ANDROID:
934
- return True
935
-
936
- def on_permissions_result(permissions, grants):
937
- try:
938
- if callback:
939
- if can_accept_arguments(callback, True):
940
- callback(grants[0])
941
- else:
942
- callback()
943
- except Exception as request_permission_error:
944
- print('Exception: ',request_permission_error)
945
- print('Permission response callback error: ',traceback.format_exc())
946
- finally:
947
- cls.__requesting_permission = False
948
-
949
- if not cls.has_permission():
950
- cls.__requesting_permission = True
951
- request_permissions([Permission.POST_NOTIFICATIONS],on_permissions_result)
952
- else:
953
- cls.__requesting_permission = False
954
- if callback:
955
- if can_accept_arguments(callback,True):
956
- callback(True)
957
- else:
958
- callback()
959
-
960
-
961
- NotificationHandler.bindNotifyListener()
1
+ """This Module Contain Class for creating Notification With Java"""
2
+ import os, time, threading, traceback
3
+ from typing import Any, Callable
4
+ from .config import cast
5
+
6
+ from .an_types import Importance
7
+ from .an_utils import can_accept_arguments, get_python_activity_context, \
8
+ get_android_importance, generate_channel_id, get_img_from_path, setLayoutText, \
9
+ get_bitmap_from_url, add_data_to_intent
10
+
11
+ from .config import from_service_file, get_python_activity,get_notification_manager,ON_ANDROID,on_flet_app
12
+ from .config import (Bundle, String, BuildVersion,
13
+ Intent,PendingIntent,
14
+ IconCompat,app_storage_path,
15
+ NotificationChannel,RemoteViews,
16
+ run_on_ui_thread,
17
+ )
18
+ from .config import (NotificationCompat, NotificationCompatBuilder,
19
+ NotificationCompatBigTextStyle,NotificationCompatBigPictureStyle,
20
+ NotificationCompatInboxStyle, NotificationCompatDecoratedCustomViewStyle,
21
+ Color
22
+ )
23
+ from .styles import NotificationStyles
24
+ from .base import BaseNotification
25
+ DEV=0
26
+ PythonActivity = get_python_activity()
27
+ context = get_python_activity_context()
28
+
29
+ class Notification(BaseNotification):
30
+ """
31
+ Send a notification on Android.
32
+
33
+ :param title: Title of the notification.
34
+ :param message: Message body.
35
+ ---
36
+ (Style Options)
37
+ :param style: Style of the notification ('simple', 'progress', 'big_text', 'inbox', 'big_picture', 'large_icon', 'both_imgs'). both_imgs == using lager icon and big picture
38
+ :param big_picture_path: Relative Path to the image resource.
39
+ :param large_icon_path: Relative Path to the image resource.
40
+ :param progress_current_value: Integer To set progress bar current value.
41
+ :param progress_max_value: Integer To set Max range for progress bar.
42
+ :param body: Large text For `big_Text` style, while `message` acts as subtitle.
43
+ :param lines_txt: text separated by newLine symbol For `inbox` style `use addLine method instead`
44
+ ---
45
+ (Advance Options)
46
+ :param sub_text: str for additional information next to title
47
+ :param id: Pass in Old 'id' to use old instance
48
+ :param callback: Function for notification Click.
49
+ :param channel_name: - str Defaults to "Default Channel"
50
+ :param channel_id: - str Defaults to "default_channel"
51
+ ---
52
+ (Options during Dev On PC)
53
+ :param logs: - Bool Defaults to True
54
+ ---
55
+ (Custom Style Options)
56
+ :param title_color: title color str (to be safe use hex code)
57
+ :param message_color: message color str (to be safe use hex code)
58
+
59
+ """
60
+
61
+ notification_ids = [0]
62
+ button_ids=[0]
63
+ btns_box={}
64
+ main_functions={}
65
+ passed_check=False
66
+
67
+ # During Development (When running on PC)
68
+ BaseNotification.logs=not ON_ANDROID
69
+ def __init__(self,**kwargs): #@dataclass already does work
70
+ super().__init__(**kwargs)
71
+
72
+ self.__id = self.id or self.__get_unique_id() # Different use from self.name all notifications require `integers` id's not `strings`
73
+ self.id = self.__id # To use same Notification in different instances
74
+
75
+ # To Track progressbar last update (According to Android Docs Don't update bar to often, I also faced so issues when doing that)
76
+ self.__update_timer = None
77
+ self.__progress_bar_msg = ''
78
+ self.__progress_bar_title = ''
79
+ self.__cooldown = 0
80
+
81
+ self.__built_parameter_filled=False
82
+ self.__using_set_priority_method=False
83
+
84
+ # For components
85
+ self.__lines = []
86
+ self.__has_small_icon = False #important notification can't send without
87
+ self.__using_custom = self.message_color or self.title_color
88
+ self.__format_channel(self.channel_name, self.channel_id)
89
+ self.__builder = None # want to make builder always available for getter
90
+ self.notification_manager = None
91
+
92
+ if not ON_ANDROID:
93
+ return
94
+
95
+ if not from_service_file() and not NotificationHandler.has_permission():
96
+ NotificationHandler.asks_permission()
97
+
98
+ self.notification_manager = get_notification_manager()
99
+ self.__builder = NotificationCompatBuilder(context, self.channel_id)
100
+
101
+ def addLine(self,text:str):
102
+ self.__lines.append(text)
103
+
104
+ def cancel(self,_id=0):
105
+ """
106
+ Removes a Notification instance from tray
107
+ :param _id: not required uses Notification instance id as default
108
+ """
109
+ if ON_ANDROID:
110
+ self.notification_manager.cancel(_id or self.__id)
111
+ if self.logs:
112
+ print('Removed Notification.')
113
+
114
+ @classmethod
115
+ def cancelAll(cls):
116
+ """
117
+ Removes all app Notifications from tray
118
+ """
119
+ if ON_ANDROID:
120
+ get_notification_manager().cancelAll()
121
+ if cls.logs:
122
+ print('Removed All Notifications.')
123
+
124
+ @classmethod
125
+ def channelExists(cls, channel_id):
126
+ """
127
+ Checks if a notification channel exists
128
+ """
129
+ if not ON_ANDROID:
130
+ return False
131
+ notification_manager= get_notification_manager()
132
+ if BuildVersion.SDK_INT >= 26 and notification_manager.getNotificationChannel(channel_id):
133
+ return True
134
+ return False
135
+
136
+ @classmethod
137
+ def createChannel(cls, id, name:str, description='',importance:Importance='urgent'):
138
+ """
139
+ Creates a user visible toggle button for specific notifications, Required For Android 8.0+
140
+ :param id: Used to send other notifications later through same channel.
141
+ :param name: user-visible channel name.
142
+ :param description: user-visible detail about channel (Not required defaults to empty str).
143
+ :param importance: ['urgent', 'high', 'medium', 'low', 'none'] defaults to 'urgent' i.e. makes a sound and shows briefly
144
+ :return: boolean if channel created
145
+ """
146
+
147
+ if not ON_ANDROID:
148
+ return False
149
+
150
+ notification_manager= get_notification_manager()
151
+ android_importance_value = get_android_importance(importance)
152
+
153
+ if not cls.channelExists(id):
154
+ channel = NotificationChannel(id, name, android_importance_value)
155
+ if description:
156
+ channel.setDescription(description)
157
+ notification_manager.createNotificationChannel(channel)
158
+ return True
159
+ return False
160
+
161
+ @classmethod
162
+ def deleteChannel(cls, channel_id):
163
+ """Delete a Channel Matching channel_id"""
164
+ if not ON_ANDROID:
165
+ return None
166
+
167
+ if cls.channelExists(channel_id):
168
+ get_notification_manager().deleteNotificationChannel(channel_id)
169
+
170
+ @classmethod
171
+ def deleteAllChannel(cls):
172
+ """Deletes all notification channel
173
+ :returns amount deleted
174
+ """
175
+
176
+ amount = 0
177
+ if not ON_ANDROID:
178
+ return amount
179
+
180
+ notification_manager = get_notification_manager()
181
+ channels = cls.getChannels()
182
+ for index in range(channels.size()):
183
+ amount += 1
184
+ channel = channels.get(index)
185
+ channel_id = channel.getId()
186
+ notification_manager.deleteNotificationChannel(channel_id)
187
+ return amount
188
+
189
+ @classmethod
190
+ def doChannelsExist(cls,ids):
191
+ """Uses list of IDs to check if channel exists
192
+ returns list of channels that don't exist
193
+ """
194
+ if not ON_ANDROID:
195
+ return ids # Assume none exist on non-Android environments
196
+ missing_channels = []
197
+ notification_manager = get_notification_manager()
198
+ for channel_id in ids:
199
+ exists = (
200
+ BuildVersion.SDK_INT >= 26 and
201
+ notification_manager.getNotificationChannel(channel_id)
202
+ )
203
+ if not exists:
204
+ missing_channels.append(channel_id)
205
+ return missing_channels
206
+
207
+
208
+ def refresh(self):
209
+ """TO apply new components on notification"""
210
+ if self.__built_parameter_filled:
211
+ # Don't dispatch before filling required values `self.__create_basic_notification`
212
+ # We generally shouldn't dispatch till user call .send()
213
+ self.__applyNewLinesIfAny()
214
+ self.__dispatch_notification()
215
+
216
+ def setBigPicture(self,path):
217
+ """
218
+ set a Big Picture at the bottom
219
+ :param path: can be `Relative Path` or `URL`
220
+ :return:
221
+ """
222
+ if ON_ANDROID:
223
+ self.__build_img(path, NotificationStyles.BIG_PICTURE)
224
+ elif self.logs:
225
+ # When on android there are other logs
226
+ print('Done setting big picture')
227
+
228
+ def setSmallIcon(self,path):
229
+ """
230
+ sets small icon to the top left
231
+ :param path: can be `Relative Path` or `URL`
232
+ :return:
233
+ """
234
+ if ON_ANDROID:
235
+ self.__insert_app_icon(path)
236
+ elif self.logs:
237
+ # When on android there are other logs
238
+ print('Done setting small icon')
239
+
240
+ def setLargeIcon(self,path):
241
+ """
242
+ sets Large icon to the right
243
+ :param path: can be `Relative Path` or `URL`
244
+ :return:
245
+ """
246
+ if ON_ANDROID:
247
+ self.__build_img(path, NotificationStyles.LARGE_ICON)
248
+ elif self.logs:
249
+ #When on android there are other logs
250
+ print('Done setting large icon')
251
+
252
+ def setBigText(self,body):
253
+ """Sets a big text for when drop down button is pressed
254
+
255
+ :param body: The big text that will be displayed
256
+ """
257
+ if ON_ANDROID:
258
+ big_text_style = NotificationCompatBigTextStyle()
259
+ big_text_style.bigText(str(body))
260
+ self.__builder.setStyle(big_text_style)
261
+ elif self.logs:
262
+ # When on android, there are other logs
263
+ print('Done setting big text')
264
+
265
+ def setSubText(self, text):
266
+ """
267
+ In android version 7+ text displays in header next to title,
268
+ While in lesser versions displays in third line of text, where progress-bar occupies
269
+ :param text: str for subtext
270
+
271
+ """
272
+ self.sub_text = str(text)
273
+ if self.logs:
274
+ print(f'new notification sub text: {self.sub_text}')
275
+ if ON_ANDROID:
276
+ self.__builder.setSubText(self.sub_text)
277
+
278
+ def setColor(self,color:str):
279
+ """
280
+ Sets Notification accent color, visible change in SmallIcon color
281
+ :param color: str - red,pink,... (to be safe use hex code)
282
+ """
283
+ if self.logs:
284
+ print(f'new notification icon color: {color}')
285
+ if ON_ANDROID:
286
+ self.__builder.setColor(Color.parseColor(color))
287
+
288
+ def showInfiniteProgressBar(self):
289
+ """Displays an (Infinite) progress Bar in Notification, that continues loading indefinitely.
290
+ Can be Removed By `removeProgressBar` Method
291
+ """
292
+ if self.logs:
293
+ print('Showing infinite progressbar')
294
+ if ON_ANDROID:
295
+ self.__builder.setProgress(0,0, True)
296
+ self.refresh()
297
+
298
+ def updateTitle(self,new_title):
299
+ """Changes Old Title
300
+
301
+ Args:
302
+ new_title (str): New Notification Title
303
+ """
304
+ self.title=str(new_title)
305
+ if self.logs:
306
+ print(f'new notification title: {self.title}')
307
+ if ON_ANDROID:
308
+ if self.isUsingCustom():
309
+ self.__apply_basic_custom_style()
310
+ else:
311
+ self.__builder.setContentTitle(String(self.title))
312
+ self.refresh()
313
+
314
+ def updateMessage(self,new_message):
315
+ """Changes Old Message
316
+
317
+ Args:
318
+ new_message (str): New Notification Message
319
+ """
320
+ self.message=str(new_message)
321
+ if self.logs:
322
+ print(f'new notification message: {self.message}')
323
+ if ON_ANDROID:
324
+ if self.isUsingCustom():
325
+ self.__apply_basic_custom_style()
326
+ else:
327
+ self.__builder.setContentText(String(self.message))
328
+ self.refresh()
329
+
330
+ def updateProgressBar(self, current_value:int, message:str='', title:str='', cooldown=0.5, _callback:Callable=None):
331
+ """Updates progress bar current value
332
+
333
+ Args:
334
+ current_value (int): the value from progressbar current progress
335
+ message (str): defaults to last message
336
+ title (str): defaults to last title
337
+ cooldown (float, optional): Little Time to Wait before change actually reflects, to avoid android Ignoring Change, Defaults to 0.5secs
338
+ _callback (object): function for when change actual happens
339
+
340
+ NOTE: There is a 0.5 sec delay for value change, if updating title,msg with progressbar frequently pass them in too to avoid update issues
341
+ """
342
+
343
+ # replacing new values for when timer is called
344
+ self.progress_current_value = current_value
345
+ self.__progress_bar_msg = message or self.message
346
+ self.__progress_bar_title = title or self.title
347
+
348
+ if self.__update_timer and self.__update_timer.is_alive():
349
+ # Make Logs too Dirty
350
+ # if self.logs:
351
+ # remaining = self.__cooldown - (time.time() - self.__timer_start_time)
352
+ # print(f'Progressbar update too soon, waiting for cooldown ({max(0, remaining):.2f}s)')
353
+ return
354
+
355
+ def delayed_update():
356
+ if self.__update_timer is None: # Ensure we are not executing an old timer
357
+ if self.logs:
358
+ print('ProgressBar update skipped: bar has been removed.')
359
+ return
360
+ if self.logs:
361
+ print(f'Progress Bar Update value: {self.progress_current_value}')
362
+
363
+ if _callback:
364
+ try:
365
+ _callback()
366
+ except Exception as passed_in_callback_error:
367
+ print('Exception passed_in_callback_error:', passed_in_callback_error)
368
+ traceback.print_exc()
369
+
370
+ if not ON_ANDROID:
371
+ self.__update_timer = None
372
+ return
373
+
374
+ self.__builder.setProgress(self.progress_max_value, self.progress_current_value, False)
375
+
376
+ if self.__progress_bar_msg:
377
+ self.updateMessage(self.__progress_bar_msg)
378
+ if self.__progress_bar_title:
379
+ self.updateTitle(self.__progress_bar_title)
380
+
381
+ self.refresh()
382
+ self.__update_timer = None
383
+
384
+
385
+ # Start a new timer that runs after 0.5 seconds
386
+ # self.__timer_start_time = time.time() # for logs
387
+ self.__cooldown = cooldown
388
+ self.__update_timer = threading.Timer(cooldown, delayed_update)
389
+ self.__update_timer.start()
390
+
391
+ def removeProgressBar(self, message='', show_on_update=True, title:str='', cooldown=0.5, _callback:Callable=None):
392
+ """Removes Progress Bar from Notification
393
+
394
+ Args:
395
+ message (str, optional): notification message. Defaults to 'last message'.
396
+ show_on_update (bool, optional): To show notification briefly when progressbar removed. Defaults to True.
397
+ title (str, optional): notification title. Defaults to 'last title'.
398
+ cooldown (float, optional): Little Time to Wait before change actually reflects, to avoid android Ignoring Change, Defaults to 0.5secs
399
+ _callback (object): function for when change actual happens
400
+
401
+ In-Built Delay of 0.5 sec According to Android Docs Don't Update Progressbar too Frequently
402
+ """
403
+
404
+ # To Cancel any queued timer from `updateProgressBar` method and to avoid race effect incase it somehow gets called while in this method
405
+ # Avoiding Running `updateProgressBar.delayed_update` at all
406
+ # so didn't just set `self.__progress_bar_title` and `self.progress_current_value` to 0
407
+ if self.__update_timer:
408
+ # Make Logs too Dirty
409
+ # if self.logs:
410
+ # print('cancelled progressbar stream update because about to remove',self.progress_current_value)
411
+ self.__update_timer.cancel()
412
+ self.__update_timer = None
413
+
414
+ def delayed_update():
415
+ if self.logs:
416
+ msg = message or self.message
417
+ title_=title or self.title
418
+ print(f'removed progress bar with message: {msg} and title: {title_}')
419
+
420
+ if _callback:
421
+ try:
422
+ _callback()
423
+ except Exception as passed_in_callback_error:
424
+ print('Exception passed_in_callback_error:', passed_in_callback_error)
425
+ traceback.print_exc()
426
+
427
+ if not ON_ANDROID:
428
+ return
429
+
430
+ if message:
431
+ self.updateMessage(message)
432
+ if title:
433
+ self.updateTitle(title)
434
+ self.__builder.setOnlyAlertOnce(not show_on_update)
435
+ self.__builder.setProgress(0, 0, False)
436
+ self.refresh()
437
+
438
+ # Incase `self.updateProgressBar delayed_update` is called right before this method, so android doesn't bounce update
439
+ threading.Timer(cooldown, delayed_update).start()
440
+
441
+ def setPriority(self,importance:Importance):
442
+ """
443
+ For devices less than android 8
444
+ :param importance: ['urgent', 'high', 'medium', 'low', 'none'] defaults to 'urgent' i.e. makes a sound and shows briefly
445
+ :return:
446
+ """
447
+ self.__using_set_priority_method=True
448
+ if ON_ANDROID:
449
+ android_importance_value = get_android_importance(importance)
450
+ if not isinstance(android_importance_value, str): # Can be an empty str if importance='none'
451
+ self.__builder.setPriority(android_importance_value)
452
+
453
+ def send(self,silent:bool=False,persistent=False,close_on_click=True):
454
+ """Sends notification
455
+
456
+ Args:
457
+ silent (bool): True if you don't want to show briefly on screen
458
+ persistent (bool): True To not remove Notification When User hits clears All notifications button
459
+ close_on_click (bool): True if you want Notification to be removed when clicked
460
+ """
461
+ self.silent = silent or self.silent
462
+ if ON_ANDROID:
463
+ self.__start_notification_build(persistent, close_on_click)
464
+ self.__dispatch_notification()
465
+
466
+ self.__send_logs()
467
+
468
+ def send_(self,silent:bool=False,persistent=False,close_on_click=True):
469
+ """Sends notification without checking for additional notification permission
470
+
471
+ Args:
472
+ silent (bool): True if you don't want to show briefly on screen
473
+ persistent (bool): True To not remove Notification When User hits clears All notifications button
474
+ close_on_click (bool): True if you want Notification to be removed when clicked
475
+ """
476
+ self.passed_check = True
477
+ self.send(silent,persistent,close_on_click)
478
+
479
+ def __send_logs(self):
480
+ if not self.logs:
481
+ return
482
+ string_to_display=''
483
+ print("\n Sent Notification!!!")
484
+ displayed_args = [
485
+ "title", "message",
486
+ "style", "body", "large_icon_path", "big_picture_path",
487
+ "progress_max_value",
488
+ 'name', "channel_name",
489
+ ]
490
+ is_progress_not_default = isinstance(self.progress_current_value, int) or (isinstance(self.progress_current_value, float) and self.progress_current_value != 0.0)
491
+ for name,value in vars(self).items():
492
+ if value and name in displayed_args:
493
+ if name == "progress_max_value":
494
+ if is_progress_not_default:
495
+ string_to_display += f'\n progress_current_value: {self.progress_current_value}, {name}: {value}'
496
+ elif name == "channel_name":
497
+ string_to_display += f'\n {name}: {value}, channel_id: {self.channel_id}'
498
+ else:
499
+ string_to_display += f'\n {name}: {value}'
500
+
501
+ string_to_display +="\n (Won't Print Logs When Complied,except if selected `Notification.logs=True`)"
502
+ print(string_to_display)
503
+
504
+ def builder(self):
505
+ return self.__builder
506
+
507
+ def addButton(self, text:str,on_release):
508
+ """For adding action buttons
509
+
510
+ Args:
511
+ text (str): Text For Button
512
+ on_release: function to be called when button is clicked
513
+ """
514
+ if self.logs:
515
+ print('Added Button: ', text)
516
+
517
+ if not ON_ANDROID:
518
+ return
519
+
520
+ btn_id= self.__get_id_for_button()
521
+ action = f"BTN_ACTION_{btn_id}"
522
+
523
+ action_intent = Intent(context, PythonActivity)
524
+ action_intent.setAction(action)
525
+ action_intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
526
+ bundle = Bundle()
527
+ bundle.putString("title", self.title or 'Title Placeholder')
528
+ bundle.putInt("key_int", 123)
529
+ action_intent.putExtras(bundle)
530
+ action_intent.putExtra("button_id", btn_id)
531
+
532
+ self.btns_box[action] = on_release
533
+ # action_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP)
534
+
535
+ if self.logs:
536
+ print('Button id: ',btn_id)
537
+ pending_action_intent = PendingIntent.getActivity(
538
+ context,
539
+ 0,
540
+ action_intent,
541
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
542
+ )
543
+ # Convert text to CharSequence
544
+ action_text = cast('java.lang.CharSequence', String(text))
545
+
546
+
547
+
548
+ # Add action with proper types
549
+ self.__builder.addAction(
550
+ int(context.getApplicationInfo().icon), # Cast icon to int
551
+ action_text, # CharSequence text
552
+ pending_action_intent # PendingIntent
553
+ )
554
+ # Set content intent for notification tap
555
+ self.__builder.setContentIntent(pending_action_intent)
556
+
557
+ def removeButtons(self):
558
+ """Removes all notification buttons
559
+ """
560
+ if ON_ANDROID:
561
+ self.__builder.mActions.clear()
562
+ self.refresh()
563
+ if self.logs:
564
+ print('Removed Notification Buttons')
565
+
566
+ @run_on_ui_thread
567
+ def addNotificationStyle(self,style:str,already_sent=False):
568
+ """Adds Style to Notification
569
+ Version 1.51.2+ Exposes method to Users (Note): Always try to Call On UI Thread
570
+
571
+ Args:
572
+ style (str): required style
573
+ already_sent (bool,False): If notification was already sent
574
+ """
575
+
576
+ if not ON_ANDROID:
577
+ # TODO for logs when not on android and style related to imgs extract app path from buildozer.spec and print
578
+ return False
579
+
580
+ if self.body:
581
+ self.setBigText(self.body)
582
+
583
+ elif self.lines_txt:
584
+ lines = self.lines_txt.split("\n")
585
+ self.setLines(lines)
586
+
587
+ elif self.big_picture_path or self.large_icon_path:
588
+ if self.big_picture_path:
589
+ self.setBigPicture(self.big_picture_path)
590
+ if self.large_icon_path:
591
+ self.setLargeIcon(self.large_icon_path)
592
+
593
+ elif self.progress_max_value or self.progress_current_value:
594
+ self.__builder.setProgress(self.progress_max_value, self.progress_current_value or 0.1, False)
595
+
596
+ if already_sent:
597
+ self.refresh()
598
+
599
+ return True
600
+
601
+ def setLines(self, lines: list):
602
+ """Pass in a list of strings to be used for lines"""
603
+ if not lines:
604
+ return
605
+ if ON_ANDROID:
606
+ inbox_style = NotificationCompatInboxStyle()
607
+ for line in lines:
608
+ inbox_style.addLine(str(line))
609
+ self.__builder.setStyle(inbox_style)
610
+ print('Set Lines: ', lines)
611
+
612
+ if self.logs:
613
+ print('Added Lines: ', lines)
614
+
615
+ def __dispatch_notification(self):
616
+ # self.passed_check is for self.send_() some devices don't return true when checking for permission when it's actually True in settingsAdd commentMore actions
617
+ # And so users can do Notification.passed_check = True at top of their file and use regular .send()
618
+
619
+ if from_service_file(): # android has_permission has some internal error when checking from service
620
+ try:
621
+ self.notification_manager.notify(self.__id, self.__builder.build())
622
+ except Exception as sending_notification_from_service_error:
623
+ print('error sending notification from service:',sending_notification_from_service_error)
624
+ elif on_flet_app() or self.passed_check or NotificationHandler.has_permission():
625
+ try:
626
+ self.notification_manager.notify(self.__id, self.__builder.build())
627
+ except Exception as notify_error:
628
+ print('Exception:', notify_error)
629
+ print('Failed to send traceback:', traceback.format_exc())
630
+ else:
631
+ print('Permission not granted to send notifications')
632
+ # TODO find way to open app notification settings and not ask only through POP-UP
633
+ # Not asking for permission too frequently, This makes dialog popup to stop showing
634
+ # NotificationHandler.asks_permission()
635
+
636
+ def __start_notification_build(self, persistent, close_on_click):
637
+ self.__create_basic_notification(persistent, close_on_click)
638
+ if self.style not in ['simple','']:
639
+ self.addNotificationStyle(self.style)
640
+ self.__applyNewLinesIfAny()
641
+
642
+ def __applyNewLinesIfAny(self):
643
+ if self.__lines:
644
+ self.setLines(self.__lines)
645
+ self.__lines=[] # for refresh method to known when new lines added
646
+
647
+ def __create_basic_notification(self, persistent, close_on_click):
648
+ if not self.channelExists(self.channel_id):
649
+ self.createChannel(self.channel_id, self.channel_name)
650
+ elif not self.__using_set_priority_method:
651
+ self.setPriority('medium' if self.silent else 'urgent')
652
+
653
+ # Build the notification
654
+ if self.isUsingCustom():
655
+ self.__apply_basic_custom_style()
656
+ else:
657
+ self.__builder.setContentTitle(str(self.title))
658
+ self.__builder.setContentText(str(self.message))
659
+ self.__insert_app_icon()
660
+ self.__builder.setDefaults(NotificationCompat.DEFAULT_ALL)
661
+ self.__builder.setOnlyAlertOnce(True)
662
+ self.__builder.setOngoing(persistent)
663
+ self.__builder.setAutoCancel(close_on_click)
664
+
665
+ if not from_service_file():
666
+ try:
667
+ self.__add_intent_to_open_app()
668
+ except Exception as failed_to_add_intent_to_open_app:
669
+ #if self.logs:
670
+ #TODO remove this check and print error logs always
671
+ print('failed_to_add_intent_to_open_app Error: ',failed_to_add_intent_to_open_app)
672
+ traceback.print_exc()
673
+
674
+ self.__built_parameter_filled = True
675
+
676
+ def __insert_app_icon(self,path=''):
677
+ if BuildVersion.SDK_INT >= 23 and (path or self.app_icon not in ['','Defaults to package app icon']):
678
+ # Bitmap Insert as Icon Not available below Android 6
679
+ if self.logs:
680
+ print('getting custom icon...')
681
+ self.__set_icon_from_bitmap(path or self.app_icon)
682
+ else:
683
+ if self.logs:
684
+ print('using default icon...')
685
+ self.__has_small_icon = True
686
+ self.__builder.setSmallIcon(context.getApplicationInfo().icon)
687
+
688
+ def __build_img(self, user_img, img_style):
689
+ if user_img.startswith('http://') or user_img.startswith('https://'):
690
+ def callback(bitmap_):
691
+ self.__apply_notification_image(bitmap_,img_style)
692
+ thread = threading.Thread(
693
+ target=get_bitmap_from_url,
694
+ args=[user_img,callback,self.logs]
695
+ )
696
+ thread.start()
697
+ else:
698
+ bitmap = get_img_from_path(user_img)
699
+ if bitmap:
700
+ self.__apply_notification_image(bitmap, img_style)
701
+
702
+ def __set_icon_from_bitmap(self, img_path):
703
+ """Path can be a link or relative path"""
704
+ if img_path.startswith('http://') or img_path.startswith('https://'):
705
+ def callback(bitmap_):
706
+ if bitmap_:
707
+ icon_ = IconCompat.createWithBitmap(bitmap_)
708
+ self.__builder.setSmallIcon(icon_)
709
+ self.__has_small_icon = True
710
+ else:
711
+ if self.logs:
712
+ print('Using Default Icon as fallback......')
713
+ self.__has_small_icon = True
714
+ self.__builder.setSmallIcon(context.getApplicationInfo().icon)
715
+ threading.Thread(
716
+ target=get_bitmap_from_url,
717
+ args=[img_path,callback,self.logs]
718
+ ).start()
719
+ else:
720
+ bitmap = get_img_from_path(img_path)
721
+ if bitmap:
722
+ icon = IconCompat.createWithBitmap(bitmap)
723
+ self.__builder.setSmallIcon(icon)
724
+ else:
725
+ if self.logs:
726
+ app_folder=os.path.join(app_storage_path(),'app')
727
+ img_absolute_path = os.path.join(app_folder, img_path)
728
+ print(f'Failed getting img for custom notification icon defaulting to app icon\n absolute path {img_absolute_path}')
729
+ self.__builder.setSmallIcon(context.getApplicationInfo().icon)
730
+
731
+ @run_on_ui_thread
732
+ def __apply_notification_image(self, bitmap, img_style):
733
+ try:
734
+ if img_style == NotificationStyles.BIG_PICTURE and bitmap:
735
+ big_picture_style = NotificationCompatBigPictureStyle().bigPicture(bitmap)
736
+ self.__builder.setStyle(big_picture_style)
737
+ elif img_style == NotificationStyles.LARGE_ICON and bitmap:
738
+ self.__builder.setLargeIcon(bitmap)
739
+ # LargeIcon requires smallIcon to be already set
740
+ # 'setLarge, setBigPic' tries to dispatch before filling required values `self.__create_basic_notification`
741
+ self.refresh()
742
+ if self.logs:
743
+ print('Done adding image to notification-------')
744
+ except Exception as notification_image_error:
745
+ img = self.large_icon_path if img_style == NotificationStyles.LARGE_ICON else self.big_picture_path
746
+ print(f'Failed adding Image of style: {img_style} || From path: {img}, Exception {notification_image_error}')
747
+ print('could not get Img traceback: ',traceback.format_exc())
748
+
749
+ def __add_intent_to_open_app(self):
750
+ intent = Intent(context, PythonActivity)
751
+ action = str(self.name or self.__id)
752
+ intent.setAction(action)
753
+ add_data_to_intent(intent,self.title)
754
+ self.main_functions[action]=self.callback
755
+ intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
756
+
757
+ pending_intent = PendingIntent.getActivity(
758
+ context, 0,
759
+ intent, PendingIntent.FLAG_IMMUTABLE if BuildVersion.SDK_INT >= 31 else PendingIntent.FLAG_UPDATE_CURRENT
760
+ )
761
+ self.__builder.setContentIntent(pending_intent)
762
+
763
+ def __get_id_for_button(self):
764
+ btn_id = self.button_ids[-1] + 1
765
+ self.button_ids.append(btn_id)
766
+ return btn_id
767
+
768
+ def __format_channel(self, channel_name:str='Default Channel',channel_id:str='default_channel'):
769
+ """
770
+ Formats and sets self.channel_name and self.channel_id to a formatted version
771
+ :param channel_name:
772
+ :param channel_id:
773
+ :return:
774
+ """
775
+ # Shorten channel name # android docs as at most 40 chars
776
+ if channel_name != 'Default Channel':
777
+ cleaned_name = channel_name.strip()
778
+ self.channel_name = cleaned_name[:40] if cleaned_name else 'Default Channel'
779
+
780
+ # If no channel_id then generating channel_id from passed in channel_name
781
+ if channel_id == 'default_channel':
782
+ generated_id = generate_channel_id(channel_name)
783
+ self.channel_id = generated_id
784
+
785
+ def __get_unique_id(self):
786
+ if from_service_file():
787
+ max_int = 2_147_483_647
788
+ return int(time.time() * 1000) % max_int
789
+
790
+ notification_id = self.notification_ids[-1] + 1
791
+ self.notification_ids.append(notification_id)
792
+ return notification_id
793
+
794
+ @classmethod
795
+ def getChannels(cls) -> list[Any] | Any:
796
+ """Return all existing channels"""
797
+ if not ON_ANDROID:
798
+ return []
799
+
800
+ return get_notification_manager().getNotificationChannels()
801
+
802
+ def __apply_basic_custom_style(self):
803
+
804
+ # Load layout
805
+ resources = context.getResources()
806
+ package_name = context.getPackageName()
807
+
808
+ # ids
809
+ small_layout_id = resources.getIdentifier("an_colored_basic_small", "layout", package_name)
810
+ large_layout_id = resources.getIdentifier("an_colored_basic_large", "layout", package_name)
811
+ title_id = resources.getIdentifier("title", "id", package_name)
812
+ message_id = resources.getIdentifier("message", "id", package_name)
813
+
814
+ # Layout
815
+ notificationLayout = RemoteViews(package_name, small_layout_id)
816
+ notificationLayoutExpanded = RemoteViews(package_name, large_layout_id)
817
+
818
+ if DEV:
819
+ print('small: ',small_layout_id, 'notificationLayout: ',notificationLayout)
820
+
821
+ # Notification Content
822
+ setLayoutText(
823
+ layout=notificationLayout, id=title_id,
824
+ text=self.title, color=self.title_color
825
+ )
826
+ setLayoutText(
827
+ layout=notificationLayoutExpanded, id=title_id,
828
+ text=self.title, color=self.title_color
829
+ )
830
+ setLayoutText(
831
+ layout=notificationLayoutExpanded, id=message_id,
832
+ text=self.message, color=self.message_color
833
+ )
834
+ # self.__setLayoutText(
835
+ # layout=notificationLayout, id=message_id,
836
+ # text=self.message, color=self.message_color
837
+ # )
838
+ if not self.__built_parameter_filled:
839
+ current_time_mills = int(time.time() * 1000)
840
+ self.__builder.setWhen(current_time_mills)
841
+ self.__builder.setShowWhen(True)
842
+ self.__builder.setStyle(NotificationCompatDecoratedCustomViewStyle())
843
+ self.__builder.setCustomContentView(notificationLayout)
844
+ self.__builder.setCustomBigContentView(notificationLayoutExpanded)
845
+
846
+ def isUsingCustom(self):
847
+ self.__using_custom = self.title_color or self.message_color
848
+ return bool(self.__using_custom)
849
+
850
+ # TODO method to create channel groups
851
+
852
+
853
+ class NotificationHandler:
854
+ """For Notification Operations """
855
+ __name = None
856
+ __bound = False
857
+ __requesting_permission=False
858
+ android_activity=None
859
+ if ON_ANDROID and not on_flet_app():
860
+ from android import activity
861
+ android_activity = activity
862
+ @classmethod
863
+ def get_name(cls):
864
+ """Returns name or id str for Clicked Notification."""
865
+ if not cls.is_on_android():
866
+ return "Not on Android"
867
+
868
+ saved_intent = cls.__name
869
+ cls.__name = None # so value won't be set when opening app not from notification
870
+ # print('saved_intent ',saved_intent)
871
+ # if not saved_intent or (isinstance(saved_intent, str) and saved_intent.startswith("android.intent")):
872
+ # All other notifications are not None after First notification opens app
873
+ # NOTE these notifications are also from Last time app was opened and they Still Give Value after first one opens App
874
+ # TODO Find a way to get intent when App if Swiped From recents
875
+ # Below action is always None
876
+ # __PythonActivity = autoclass(ACTIVITY_CLASS_NAME)
877
+ # __mactivity = __PythonActivity.mActivity
878
+ # __context = cast('android.content.Context', __mactivity)
879
+ # __Intent = autoclass('android.content.Intent')
880
+ # __intent = __Intent(__context, __PythonActivity)
881
+ # action = __intent.getAction()
882
+ # print('Start up Intent ----', action)
883
+ # print('start Up Title --->',__intent.getStringExtra("title"))
884
+
885
+ return saved_intent
886
+
887
+ @classmethod
888
+ def __notification_handler(cls, intent):
889
+ """Calls Function Attached to notification on click.
890
+ Don't Call this function manual, it's Already Attach to Notification.
891
+
892
+ Sets self.__name #action of Notification that was clicked from Notification.name or Notification.id
893
+ """
894
+ if not cls.is_on_android():
895
+ return "Not on Android"
896
+ buttons_object=Notification.btns_box
897
+ notifty_functions=Notification.main_functions
898
+ if DEV:
899
+ print("notifty_functions ",notifty_functions)
900
+ print("buttons_object", buttons_object)
901
+ try:
902
+ action = intent.getAction()
903
+ cls.__name = action
904
+
905
+ # print("The Action --> ",action)
906
+ if action == "android.intent.action.MAIN": # Not Open From Notification
907
+ cls.__name = None
908
+ return 'Not notification'
909
+
910
+ print(intent.getStringExtra("title"))
911
+ try:
912
+ if action in notifty_functions and notifty_functions[action]:
913
+ notifty_functions[action]()
914
+ elif action in buttons_object:
915
+ buttons_object[action]()
916
+ except Exception as notification_handler_function_error:
917
+ print("Error Type ",notification_handler_function_error)
918
+ print('Failed to run function: ', traceback.format_exc())
919
+ except Exception as extracting_notification_props_error:
920
+ print('Notify Handler Failed ',extracting_notification_props_error)
921
+
922
+ @classmethod
923
+ def bindNotifyListener(cls):
924
+ """This Creates a Listener for All Notification Clicks and Functions"""
925
+ if on_flet_app():
926
+ return False
927
+
928
+ if not cls.is_on_android():
929
+ return "Not on Android"
930
+ #TODO keep trying BroadcastReceiver
931
+ if cls.__bound:
932
+ print("binding done already ")
933
+ return True
934
+ try:
935
+ cls.android_activity.bind(on_new_intent=cls.__notification_handler)
936
+ cls.__bound = True
937
+ return True
938
+ except Exception as binding_listener_error:
939
+ print('Failed to bin notifications listener',binding_listener_error)
940
+ return False
941
+
942
+ @classmethod
943
+ def unbindNotifyListener(cls):
944
+ """Removes Listener for Notifications Click"""
945
+ if not cls.is_on_android():
946
+ return "Not on Android"
947
+
948
+ #Beta TODO use BroadcastReceiver
949
+ if on_flet_app() or from_service_file():
950
+ return False # error 'NoneType' object has no attribute 'registerNewIntentListener'
951
+ try:
952
+ cls.android_activity.unbind(on_new_intent=cls.__notification_handler)
953
+ return True
954
+ except Exception as unbinding_listener_error:
955
+ print("Failed to unbind notifications listener: ",unbinding_listener_error)
956
+ return False
957
+
958
+ @staticmethod
959
+ def is_on_android():
960
+ """Utility to check if the app is running on Android."""
961
+ return ON_ANDROID
962
+
963
+ @staticmethod
964
+ def has_permission():
965
+ """
966
+ Checks if device has permission to send notifications
967
+ returns True if device has permission
968
+ """
969
+ if not ON_ANDROID:
970
+ return True
971
+
972
+ if on_flet_app():
973
+ from .config import autoclass
974
+ ContextCompat = autoclass('androidx.core.content.ContextCompat')
975
+ Manifest = autoclass('android.Manifest$permission')
976
+ VERSION_CODES = autoclass('android.os.Build$VERSION_CODES')
977
+
978
+ if BuildVersion.SDK_INT >= VERSION_CODES.TIRAMISU:
979
+ permission = Manifest.POST_NOTIFICATIONS
980
+ return ContextCompat.checkSelfPermission(context, permission)
981
+ else:
982
+ print("android_notify- On Low android version don't need permission")
983
+ return True #doesn't need permission
984
+ else:
985
+ from android.permissions import Permission, check_permission
986
+ return check_permission(Permission.POST_NOTIFICATIONS)
987
+
988
+ @classmethod
989
+ @run_on_ui_thread
990
+ def asks_permission(cls,callback=None):
991
+ """
992
+ Ask for permission to send notifications if needed.
993
+ Passes True to callback if access granted
994
+ """
995
+ if cls.__requesting_permission or not ON_ANDROID:
996
+ return True
997
+
998
+ def on_permissions_result(permissions, grants):
999
+ try:
1000
+ if callback:
1001
+ if can_accept_arguments(callback, True):
1002
+ callback(grants[0])
1003
+ else:
1004
+ callback()
1005
+ except Exception as request_permission_error:
1006
+ print('Exception: ',request_permission_error)
1007
+ print('Permission response callback error: ',traceback.format_exc())
1008
+ finally:
1009
+ cls.__requesting_permission = False
1010
+
1011
+ if not cls.has_permission():
1012
+ if on_flet_app():
1013
+ from .config import autoclass
1014
+ ActivityCompat = autoclass('androidx.core.app.ActivityCompat')
1015
+ Manifest = autoclass('android.Manifest$permission')
1016
+ permission = Manifest.POST_NOTIFICATIONS
1017
+ ActivityCompat.requestPermissions(context, [permission], 101)
1018
+ return None
1019
+ # TODO Callback when user answers request question
1020
+ else:
1021
+ from android.permissions import request_permissions, Permission
1022
+ cls.__requesting_permission = True
1023
+ request_permissions([Permission.POST_NOTIFICATIONS],on_permissions_result)
1024
+ return None
1025
+ else:
1026
+ cls.__requesting_permission = False
1027
+ if callback:
1028
+ if can_accept_arguments(callback,True):
1029
+ callback(True)
1030
+ else:
1031
+ callback()
1032
+ return None
1033
+
1034
+
1035
+ if not on_flet_app() and from_service_file():
1036
+ print("didn't bind listener, In service file")
1037
+ elif ON_ANDROID:
1038
+ try:
1039
+ NotificationHandler.bindNotifyListener()
1040
+ except Exception as bind_error:
1041
+ # error 'NoneType' object has no attribute 'registerNewIntentListener'
1042
+ print("notification listener bind error:",bind_error)
1043
+ traceback.print_exc()