android-notify 1.59.4__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 -992
  10. {android_notify-1.59.4.dist-info → android_notify-1.60.0.dist-info}/METADATA +73 -28
  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.4.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.4.dist-info/RECORD +0 -12
  1351. {android_notify-1.59.4.dist-info → android_notify-1.60.0.dist-info}/WHEEL +0 -0
android_notify/sword.py CHANGED
@@ -1,992 +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
- passed_check = False
109
-
110
- # During Development (When running on PC)
111
- BaseNotification.logs=not ON_ANDROID
112
- def __init__(self,**kwargs): #@dataclass already does work
113
- super().__init__(**kwargs)
114
-
115
- self.__id = self.id or self.__get_unique_id() # Different use from self.name all notifications require `integers` id's not `strings`
116
- self.id = self.__id # To use same Notification in different instances
117
-
118
- # To Track progressbar last update (According to Android Docs Don't update bar to often, I also faced so issues when doing that)
119
- self.__update_timer = None
120
- self.__progress_bar_msg = ''
121
- self.__progress_bar_title = ''
122
- self.__cooldown = 0
123
-
124
- self.__built_parameter_filled=False
125
- self.__using_set_priority_method=False
126
-
127
- # For components
128
- self.__lines = []
129
- self.__builder = None # want to make builder always available for getter
130
- self.notification_manager = None
131
-
132
- self.__format_channel(self.channel_name, self.channel_id)
133
- if not ON_ANDROID:
134
- return
135
-
136
- NotificationHandler.asks_permission()
137
- notification_service = context.getSystemService(context.NOTIFICATION_SERVICE)
138
- self.notification_manager = cast(NotificationManager, notification_service)
139
- self.__builder = NotificationCompatBuilder(context, self.channel_id)
140
-
141
- def addLine(self,text:str):
142
- self.__lines.append(text)
143
-
144
- def cancel(self,_id=0):
145
- """
146
- Removes a Notification instance from tray
147
- :param _id: not required uses Notification instance id as default
148
- """
149
- if ON_ANDROID:
150
- self.notification_manager.cancel(_id or self.__id)
151
- if self.logs:
152
- print('Removed Notification.')
153
-
154
- @classmethod
155
- def cancelAll(cls):
156
- """
157
- Removes all app Notifications from tray
158
- """
159
- if ON_ANDROID:
160
- cls.__return_notification_manger().cancelAll()
161
- if cls.logs:
162
- print('Removed All Notifications.')
163
-
164
- @classmethod
165
- def createChannel(cls, id, name:str, description='',importance:Importance='urgent'):
166
- """
167
- Creates a user visible toggle button for specific notifications, Required For Android 8.0+
168
- :param id: Used to send other notifications later through same channel.
169
- :param name: user-visible channel name.
170
- :param description: user-visible detail about channel (Not required defaults to empty str).
171
- :param importance: ['urgent', 'high', 'medium', 'low', 'none'] defaults to 'urgent' i.e. makes a sound and shows briefly
172
- :return: boolean if channel created
173
- """
174
-
175
- if not ON_ANDROID:
176
- return False
177
-
178
- notification_manager=cls.__return_notification_manger()
179
- android_importance_value = cls.__get_android_importance(importance)
180
-
181
- if BuildVersion.SDK_INT >= 26 and notification_manager.getNotificationChannel(id) is None:
182
- channel = NotificationChannel(id, name, android_importance_value)
183
- if description:
184
- channel.setDescription(description)
185
- notification_manager.createNotificationChannel(channel)
186
- return True
187
- return False
188
-
189
- @classmethod
190
- def deleteChannel(cls, channel_id):
191
- """Delete a Channel Matching channel_id"""
192
- if not ON_ANDROID:
193
- return None
194
-
195
- cls.__return_notification_manger().deleteNotificationChannel(channel_id)
196
-
197
- @classmethod
198
- def deleteAllChannel(cls):
199
- """Deletes all notification channel
200
- :returns amount deleted
201
- """
202
-
203
- amount = 0
204
- if not ON_ANDROID:
205
- return amount
206
-
207
- notification_manager = cls.__return_notification_manger()
208
- channels = cls.getChannels()
209
- for index in range(channels.size()):
210
- amount += 1
211
- channel = channels.get(index)
212
- channel_id = channel.getId()
213
- notification_manager.deleteNotificationChannel(channel_id)
214
- return amount
215
-
216
- def refresh(self):
217
- """TO apply new components on notification"""
218
- if self.__built_parameter_filled:
219
- # Don't dispatch before filling required values `self.__create_basic_notification`
220
- # We generally shouldn't dispatch till user call .send()
221
- self.__applyNewLinesIfAny()
222
- self.__dispatch_notification()
223
-
224
- def setBigPicture(self,path):
225
- """
226
- set a Big Picture at the bottom
227
- :param path: can be `Relative Path` or `URL`
228
- :return:
229
- """
230
- if ON_ANDROID:
231
- self.__build_img(path, NotificationStyles.BIG_PICTURE)
232
- elif self.logs:
233
- # When on android there are other logs
234
- print('Done setting big picture')
235
-
236
- def setSmallIcon(self,path):
237
- """
238
- sets small icon to the top left
239
- :param path: can be `Relative Path` or `URL`
240
- :return:
241
- """
242
- if ON_ANDROID:
243
- self.__insert_app_icon(path)
244
- elif self.logs:
245
- # When on android there are other logs
246
- print('Done setting small icon')
247
-
248
- def setLargeIcon(self,path):
249
- """
250
- sets Large icon to the right
251
- :param path: can be `Relative Path` or `URL`
252
- :return:
253
- """
254
- if ON_ANDROID:
255
- self.__build_img(path, NotificationStyles.LARGE_ICON)
256
- elif self.logs:
257
- #When on android there are other logs
258
- print('Done setting large icon')
259
-
260
- def setBigText(self,body):
261
- """Sets a big text for when drop down button is pressed
262
-
263
- :param body: The big text that will be displayed
264
- """
265
- if ON_ANDROID:
266
- big_text_style = NotificationCompatBigTextStyle()
267
- big_text_style.bigText(str(body))
268
- self.__builder.setStyle(big_text_style)
269
- elif self.logs:
270
- # When on android there are other logs
271
- print('Done setting big text')
272
-
273
- def showInfiniteProgressBar(self):
274
- """Displays an (Infinite) progress Bar in Notification, that continues loading indefinitely.
275
- Can be Removed By `removeProgressBar` Method
276
- """
277
- if self.logs:
278
- print('Showing infinite progressbar')
279
- if ON_ANDROID:
280
- self.__builder.setProgress(0,0, True)
281
- self.refresh()
282
-
283
- def updateTitle(self,new_title):
284
- """Changes Old Title
285
-
286
- Args:
287
- new_title (str): New Notification Title
288
- """
289
- self.title=str(new_title)
290
- if self.logs:
291
- print(f'new notification title: {self.title}')
292
- if ON_ANDROID:
293
- self.__builder.setContentTitle(String(self.title))
294
- self.refresh()
295
-
296
- def updateMessage(self,new_message):
297
- """Changes Old Message
298
-
299
- Args:
300
- new_message (str): New Notification Message
301
- """
302
- self.message=str(new_message)
303
- if self.logs:
304
- print(f'new notification message: {self.message}')
305
- if ON_ANDROID:
306
- self.__builder.setContentText(String(self.message))
307
- self.refresh()
308
-
309
- def updateProgressBar(self,current_value:int,message:str='',title:str='',cooldown=0.5):
310
- """Updates progress bar current value
311
-
312
- Args:
313
- current_value (int): the value from progressbar current progress
314
- message (str): defaults to last message
315
- title (str): defaults to last title
316
- cooldown (float, optional): Little Time to Wait before change actually reflects, to avoid android Ignoring Change, Defaults to 0.5secs
317
-
318
- 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
319
- """
320
-
321
- # replacing new values for when timer is called
322
- self.progress_current_value = current_value
323
- self.__progress_bar_msg = message
324
- self.__progress_bar_title = title
325
-
326
- if self.__update_timer and self.__update_timer.is_alive():
327
- # Make Logs too Dirty
328
- # if self.logs:
329
- # remaining = self.__cooldown - (time.time() - self.__timer_start_time)
330
- # print(f'Progressbar update too soon, waiting for cooldown ({max(0, remaining):.2f}s)')
331
- return
332
-
333
- def delayed_update():
334
- if self.__update_timer is None: # Ensure we are not executing an old timer
335
- if self.logs:
336
- print('ProgressBar update skipped: bar has been removed.')
337
- return
338
- if self.logs:
339
- print(f'Progress Bar Update value: {self.progress_current_value}')
340
-
341
- if not ON_ANDROID:
342
- self.__update_timer = None
343
- return
344
-
345
- self.__builder.setProgress(self.progress_max_value, self.progress_current_value, False)
346
-
347
- if self.__progress_bar_msg:
348
- self.updateMessage(self.__progress_bar_msg)
349
- if self.__progress_bar_title:
350
- self.updateTitle(self.__progress_bar_title)
351
-
352
- self.refresh()
353
- self.__update_timer = None
354
-
355
-
356
- # Start a new timer that runs after 0.5 seconds
357
- # self.__timer_start_time = time.time() # for logs
358
- self.__cooldown = cooldown
359
- self.__update_timer = threading.Timer(cooldown, delayed_update)
360
- self.__update_timer.start()
361
-
362
- def removeProgressBar(self,message='',show_on_update=True, title:str='',cooldown=0.5):
363
- """Removes Progress Bar from Notification
364
-
365
- Args:
366
- message (str, optional): notification message. Defaults to 'last message'.
367
- show_on_update (bool, optional): To show notification briefly when progressbar removed. Defaults to True.
368
- title (str, optional): notification title. Defaults to 'last title'.
369
- cooldown (float, optional): Little Time to Wait before change actually reflects, to avoid android Ignoring Change, Defaults to 0.5secs
370
-
371
- In-Built Delay of 0.5sec According to Android Docs Don't Update Progressbar too Frequently
372
- """
373
-
374
- # To Cancel any queued timer from `updateProgressBar` method and to avoid race effect incase it somehow gets called while in this method
375
- # Avoiding Running `updateProgressBar.delayed_update` at all
376
- # so didn't just set `self.__progress_bar_title` and `self.progress_current_value` to 0
377
- if self.__update_timer:
378
- # Make Logs too Dirty
379
- # if self.logs:
380
- # print('cancelled progressbar stream update because about to remove',self.progress_current_value)
381
- self.__update_timer.cancel()
382
- self.__update_timer = None
383
-
384
-
385
- def delayed_update():
386
- if self.logs:
387
- msg = message or self.message
388
- title_=title or self.title
389
- print(f'removed progress bar with message: {msg} and title: {title_}')
390
-
391
- if not ON_ANDROID:
392
- return
393
-
394
- if message:
395
- self.updateMessage(message)
396
- if title:
397
- self.updateTitle(title)
398
- self.__builder.setOnlyAlertOnce(not show_on_update)
399
- self.__builder.setProgress(0, 0, False)
400
- self.refresh()
401
-
402
- # Incase `self.updateProgressBar delayed_update` is called right before this method, so android doesn't bounce update
403
- threading.Timer(cooldown, delayed_update).start()
404
-
405
- def setPriority(self,importance:Importance):
406
- """
407
- For devices less than android 8
408
- :param importance: ['urgent', 'high', 'medium', 'low', 'none'] defaults to 'urgent' i.e. makes a sound and shows briefly
409
- :return:
410
- """
411
- self.__using_set_priority_method=True
412
- if ON_ANDROID:
413
- android_importance_value = self.__get_android_importance(importance)
414
- if not isinstance(android_importance_value, str): # Can be an empty str if importance='none'
415
- self.__builder.setPriority(android_importance_value)
416
-
417
- def send(self,silent:bool=False,persistent=False,close_on_click=True):
418
- """Sends notification
419
-
420
- Args:
421
- silent (bool): True if you don't want to show briefly on screen
422
- persistent (bool): True To not remove Notification When User hits clears All notifications button
423
- close_on_click (bool): True if you want Notification to be removed when clicked
424
- """
425
- self.silent = silent or self.silent
426
- if ON_ANDROID:
427
- self.__start_notification_build(persistent, close_on_click)
428
- self.__dispatch_notification()
429
-
430
- self.__send_logs()
431
-
432
- def send_(self,silent:bool=False,persistent=False,close_on_click=True):
433
- """Sends notification without checking for additional notification permission
434
-
435
- Args:
436
- silent (bool): True if you don't want to show briefly on screen
437
- persistent (bool): True To not remove Notification When User hits clears All notifications button
438
- close_on_click (bool): True if you want Notification to be removed when clicked
439
- """
440
- self.passed_check = True
441
- self.send(silent,persistent,close_on_click)
442
-
443
- def __send_logs(self):
444
- if not self.logs:
445
- return
446
- string_to_display=''
447
- print("\n Sent Notification!!!")
448
- displayed_args = [
449
- "title", "message",
450
- "style", "body", "large_icon_path", "big_picture_path",
451
- "progress_max_value",
452
- 'name', "channel_name",
453
- ]
454
- is_progress_not_default = isinstance(self.progress_current_value, int) or (isinstance(self.progress_current_value, float) and self.progress_current_value != 0.0)
455
- for name,value in vars(self).items():
456
- if value and name in displayed_args:
457
- if name == "progress_max_value":
458
- if is_progress_not_default:
459
- string_to_display += f'\n progress_current_value: {self.progress_current_value}, {name}: {value}'
460
- elif name == "channel_name":
461
- string_to_display += f'\n {name}: {value}, channel_id: {self.channel_id}'
462
- else:
463
- string_to_display += f'\n {name}: {value}'
464
-
465
- string_to_display +="\n (Won't Print Logs When Complied,except if selected `Notification.logs=True`)"
466
- print(string_to_display)
467
-
468
- def builder(self):
469
- return self.__builder
470
-
471
- def addButton(self, text:str,on_release):
472
- """For adding action buttons
473
-
474
- Args:
475
- text (str): Text For Button
476
- on_release: function to be called when button is clicked
477
- """
478
- if self.logs:
479
- print('Added Button: ', text)
480
-
481
- if not ON_ANDROID:
482
- return
483
-
484
- btn_id= self.__get_id_for_button()
485
- action = f"BTN_ACTION_{btn_id}"
486
-
487
- action_intent = Intent(context, PythonActivity)
488
- action_intent.setAction(action)
489
- action_intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
490
- bundle = Bundle()
491
- bundle.putString("title", self.title or 'Title Placeholder')
492
- bundle.putInt("key_int", 123)
493
- action_intent.putExtras(bundle)
494
- action_intent.putExtra("button_id", btn_id)
495
-
496
- self.btns_box[action] = on_release
497
- # action_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP)
498
-
499
- if self.logs:
500
- print('Button id: ',btn_id)
501
- pending_action_intent = PendingIntent.getActivity(
502
- context,
503
- 0,
504
- action_intent,
505
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
506
- )
507
- # Convert text to CharSequence
508
- action_text = cast('java.lang.CharSequence', String(text))
509
-
510
-
511
-
512
- # Add action with proper types
513
- self.__builder.addAction(
514
- int(context.getApplicationInfo().icon), # Cast icon to int
515
- action_text, # CharSequence text
516
- pending_action_intent # PendingIntent
517
- )
518
- # Set content intent for notification tap
519
- self.__builder.setContentIntent(pending_action_intent)
520
-
521
- def removeButtons(self):
522
- """Removes all notification buttons
523
- """
524
- if ON_ANDROID:
525
- self.__builder.mActions.clear()
526
- self.refresh()
527
- if self.logs:
528
- print('Removed Notification Buttons')
529
-
530
- @run_on_ui_thread
531
- def addNotificationStyle(self,style:str,already_sent=False):
532
- """Adds Style to Notification
533
- Version 1.51.2+ Exposes method to Users (Note): Always try to Call On UI Thread
534
-
535
- Args:
536
- style (str): required style
537
- already_sent (bool,False): If notification was already sent
538
- """
539
-
540
- if not ON_ANDROID:
541
- # TODO for logs when not on android and style related to imgs extract app path from buildozer.spec and print
542
- return False
543
-
544
- if style == NotificationStyles.BIG_TEXT:
545
- self.setBigText(self.body)
546
-
547
- elif style == NotificationStyles.INBOX and self.lines_txt:
548
- lines = self.lines_txt.split("\n")
549
- self.setLines(lines)
550
-
551
- elif (style == NotificationStyles.LARGE_ICON and self.large_icon_path) or (style == NotificationStyles.BIG_PICTURE and self.big_picture_path):
552
- img = self.large_icon_path if style == NotificationStyles.LARGE_ICON else self.big_picture_path
553
- self.__build_img(img, style)
554
-
555
- elif style == NotificationStyles.BOTH_IMGS and (self.big_picture_path or self.large_icon_path):
556
- if self.big_picture_path:
557
- self.setBigPicture(self.big_picture_path)
558
- if self.large_icon_path:
559
- self.setLargeIcon(self.large_icon_path)
560
-
561
- elif style == NotificationStyles.PROGRESS:
562
- self.__builder.setProgress(self.progress_max_value, self.progress_current_value, False)
563
-
564
- if already_sent:
565
- self.refresh()
566
-
567
- return True
568
-
569
- def setLines(self, lines: list):
570
- """Pass in a list of strings to be used for lines"""
571
- if not lines:
572
- return
573
- if ON_ANDROID:
574
- inbox_style = NotificationCompatInboxStyle()
575
- for line in lines:
576
- inbox_style.addLine(str(line))
577
- self.__builder.setStyle(inbox_style)
578
- print('Set Lines: ', lines)
579
-
580
- if self.logs:
581
- print('Added Lines: ', lines)
582
-
583
- def __dispatch_notification(self):
584
- # self.passed_check is for self.send_() some devices don't return true when checking for permission when it's actually True in settings
585
- # And so users can do Notification.passed_check = True at top of their file and use regular .send()
586
- if self.passed_check or NotificationHandler.has_permission():
587
- try:
588
- self.notification_manager.notify(self.__id, self.__builder.build())
589
- except Exception as notify_error:
590
- print('Exception:', notify_error)
591
- print('Failed to send traceback:', traceback.format_exc())
592
- else:
593
- print('Permission not granted to send notifications')
594
- # Not asking for permission too frequently, This makes dialog popup to stop showing
595
- # NotificationHandler.asks_permission()
596
-
597
- def __start_notification_build(self, persistent, close_on_click):
598
- self.__create_basic_notification(persistent, close_on_click)
599
- if self.style not in ['simple','']:
600
- self.addNotificationStyle(self.style)
601
- self.__applyNewLinesIfAny()
602
-
603
- def __applyNewLinesIfAny(self):
604
- if self.__lines:
605
- self.setLines(self.__lines)
606
- self.__lines=[] # for refresh method to known when new lines added
607
-
608
- def __create_basic_notification(self, persistent, close_on_click):
609
- if BuildVersion.SDK_INT >= 26 and self.notification_manager.getNotificationChannel(self.channel_id) is None:
610
- self.createChannel(self.channel_id, self.channel_name)
611
- elif not self.__using_set_priority_method:
612
- self.setPriority('medium' if self.silent else 'urgent')
613
- # Build the notification
614
- # str() This is to prevent Error When user does Notification.title='blah' instead of Notification(title='blah'
615
- # TODO fix this by creating a on_title method in other versions
616
- self.__builder.setContentTitle(str(self.title))
617
- self.__builder.setContentText(str(self.message))
618
- self.__insert_app_icon()
619
- self.__builder.setDefaults(NotificationCompat.DEFAULT_ALL)
620
- self.__builder.setOnlyAlertOnce(True)
621
- self.__builder.setOngoing(persistent)
622
- self.__builder.setAutoCancel(close_on_click)
623
- self.__add_intent_to_open_app()
624
- self.__built_parameter_filled = True
625
-
626
- def __insert_app_icon(self,path=''):
627
- if BuildVersion.SDK_INT >= 23 and (path or self.app_icon not in ['','Defaults to package app icon']):
628
- # Bitmap Insert as Icon Not available below Android 6
629
- if self.logs:
630
- print('getting custom icon...')
631
- self.__set_icon_from_bitmap(path or self.app_icon)
632
- else:
633
- if self.logs:
634
- print('using default icon...')
635
- self.__builder.setSmallIcon(context.getApplicationInfo().icon)
636
-
637
- def __build_img(self, user_img, img_style):
638
- if user_img.startswith('http://') or user_img.startswith('https://'):
639
- def callback(bitmap_):
640
- self.__apply_notification_image(bitmap_,img_style)
641
- thread = threading.Thread(
642
- target=self.__get_bitmap_from_url,
643
- args=[user_img,callback]
644
- )
645
- thread.start()
646
- else:
647
- bitmap = self.__get_img_from_path(user_img)
648
- if bitmap:
649
- self.__apply_notification_image(bitmap, img_style)
650
-
651
- def __set_icon_from_bitmap(self, img_path):
652
- """Path can be a link or relative path"""
653
- if img_path.startswith('http://') or img_path.startswith('https://'):
654
- def callback(bitmap_):
655
- if bitmap_:
656
- icon_ = IconCompat.createWithBitmap(bitmap_)
657
- self.__builder.setSmallIcon(icon_)
658
- else:
659
- if self.logs:
660
- print('Using Default Icon as fallback......')
661
- self.__builder.setSmallIcon(context.getApplicationInfo().icon)
662
- threading.Thread(
663
- target=self.__get_bitmap_from_url,
664
- args=[img_path,callback]
665
- ).start()
666
- else:
667
- bitmap = self.__get_img_from_path(img_path)
668
- if bitmap:
669
- icon = IconCompat.createWithBitmap(bitmap)
670
- self.__builder.setSmallIcon(icon)
671
- else:
672
- if self.logs:
673
- app_folder=os.path.join(app_storage_path(),'app')
674
- img_absolute_path = os.path.join(app_folder, img_path)
675
- print(f'Failed getting img for custom notification icon defaulting to app icon\n absolute path {img_absolute_path}')
676
- self.__builder.setSmallIcon(context.getApplicationInfo().icon)
677
-
678
- @staticmethod
679
- def __get_img_from_path(relative_path):
680
- app_folder=os.path.join(app_storage_path(),'app')
681
- output_path = os.path.join(app_folder, relative_path)
682
- if not os.path.exists(output_path):
683
- print(f"\nImage not found at path: {app_folder}, (Local images gotten from App Path)")
684
- try:
685
- print("- These are the existing files in your app Folder:")
686
- print('['+', '.join(os.listdir(app_folder)) + ']')
687
- except Exception as could_not_get_files_in_path_error:
688
- print('Exception: ', could_not_get_files_in_path_error)
689
- print("Couldn't get Files in App Folder")
690
- return None
691
- # TODO test with a badly written Image and catch error
692
- Uri = autoclass('android.net.Uri')
693
- uri = Uri.parse(f"file://{output_path}")
694
- return BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
695
-
696
- def __get_bitmap_from_url(self, url, callback):
697
- """Gets Bitmap from url
698
-
699
- Args:
700
- url (str): img url
701
- callback (function): method to be called after thread done -passes in bitmap data as argument
702
- """
703
- if self.logs:
704
- print("getting Bitmap from URL---")
705
- try:
706
- URL = autoclass('java.net.URL')
707
- url = URL(url)
708
- connection = url.openConnection()
709
- connection.connect()
710
- input_stream = connection.getInputStream()
711
- bitmap = BitmapFactory.decodeStream(input_stream)
712
- input_stream.close()
713
- if bitmap:
714
- callback(bitmap)
715
- else:
716
- print('Error No Bitmap for small icon ------------')
717
- except Exception as extracting_bitmap_frm_URL_error:
718
- callback(None)
719
- # TODO get all types of JAVA Error that can fail here
720
- print('Error Type ',extracting_bitmap_frm_URL_error)
721
- print('Failed to get Bitmap from URL ',traceback.format_exc())
722
-
723
- @run_on_ui_thread
724
- def __apply_notification_image(self, bitmap, img_style):
725
- try:
726
- if img_style == NotificationStyles.BIG_PICTURE and bitmap:
727
- big_picture_style = NotificationCompatBigPictureStyle().bigPicture(bitmap)
728
- self.__builder.setStyle(big_picture_style)
729
- elif img_style == NotificationStyles.LARGE_ICON and bitmap:
730
- self.__builder.setLargeIcon(bitmap)
731
- # LargeIcon requires smallIcon to be already set
732
- # 'setLarge, setBigPic' tries to dispatch before filling required values `self.__create_basic_notification`
733
- self.refresh()
734
- if self.logs:
735
- print('Done adding image to notification-------')
736
- except Exception as notification_image_error:
737
- img = self.large_icon_path if img_style == NotificationStyles.LARGE_ICON else self.big_picture_path
738
- print(f'Failed adding Image of style: {img_style} || From path: {img}, Exception {notification_image_error}')
739
- print('could not get Img traceback: ',traceback.format_exc())
740
-
741
- def __add_intent_to_open_app(self):
742
- intent = Intent(context, PythonActivity)
743
- action = str(self.name or self.__id)
744
- intent.setAction(action)
745
- self.__add_data_to_intent(intent)
746
- self.main_functions[action]=self.callback
747
- intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
748
-
749
- pending_intent = PendingIntent.getActivity(
750
- context, 0,
751
- intent, PendingIntent.FLAG_IMMUTABLE if BuildVersion.SDK_INT >= 31 else PendingIntent.FLAG_UPDATE_CURRENT
752
- )
753
- self.__builder.setContentIntent(pending_intent)
754
-
755
- def __add_data_to_intent(self, intent):
756
- """Persist Some data to notification object for later use"""
757
- bundle = Bundle()
758
- bundle.putString("title", self.title or 'Title Placeholder')
759
- # bundle.putInt("notify_id", self.__id)
760
- bundle.putInt("notify_id", 101)
761
- intent.putExtras(bundle)
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 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 = self.__generate_channel_id(channel_name)
783
- self.channel_id = generated_id
784
-
785
- @staticmethod
786
- def __generate_channel_id(channel_name: str) -> str:
787
- """
788
- Generate a readable and consistent channel ID from a channel name.
789
-
790
- Args:
791
- channel_name (str): The name of the notification channel.
792
-
793
- Returns:
794
- str: A sanitized channel ID.
795
- """
796
- # Normalize the channel name
797
- channel_id = channel_name.strip().lower()
798
- # Replace spaces and special characters with underscores
799
- channel_id = re.sub(r'[^a-z0-9]+', '_', channel_id)
800
- # Remove leading/trailing underscores
801
- channel_id = channel_id.strip('_')
802
- return channel_id[:50]
803
-
804
- def __get_unique_id(self):
805
- notification_id = self.notification_ids[-1] + 1
806
- self.notification_ids.append(notification_id)
807
- return notification_id
808
-
809
- @staticmethod
810
- def __return_notification_manger():
811
- notification_service = context.getSystemService(context.NOTIFICATION_SERVICE)
812
- return cast(NotificationManager, notification_service)
813
-
814
- @classmethod
815
- def getChannels(cls):
816
- """Return all existing channels"""
817
- if not ON_ANDROID:
818
- return []
819
-
820
- return cls.__return_notification_manger().getNotificationChannels()
821
-
822
- @staticmethod
823
- def __get_android_importance(importance:Importance):
824
- """
825
- Returns Android Importance Values
826
- :param importance: ['urgent','high','medium','low','none']
827
- :return: Android equivalent int or empty str
828
- """
829
- value=''
830
- if importance == 'urgent':
831
- value = NotificationCompat.PRIORITY_HIGH if BuildVersion.SDK_INT <= 25 else NotificationManagerCompat.IMPORTANCE_HIGH
832
- elif importance == 'high':
833
- value = NotificationCompat.PRIORITY_DEFAULT if BuildVersion.SDK_INT <= 25 else NotificationManagerCompat.IMPORTANCE_DEFAULT
834
- elif importance == 'medium':
835
- value = NotificationCompat.PRIORITY_LOW if BuildVersion.SDK_INT <= 25 else NotificationManagerCompat.IMPORTANCE_LOW
836
- elif importance == 'low':
837
- value = NotificationCompat.PRIORITY_MIN if BuildVersion.SDK_INT <= 25 else NotificationManagerCompat.IMPORTANCE_MIN
838
- elif importance == 'none':
839
- value = '' if BuildVersion.SDK_INT <= 25 else NotificationManagerCompat.IMPORTANCE_NONE
840
-
841
- return value
842
- # side-note 'medium' = NotificationCompat.PRIORITY_LOW and 'low' = NotificationCompat.PRIORITY_MIN # weird but from docs
843
- # TODO method to create channel groups
844
-
845
-
846
- class NotificationHandler:
847
- """For Notification Operations """
848
- __name = None
849
- __bound = False
850
- __requesting_permission=False
851
- @classmethod
852
- def get_name(cls):
853
- """Returns name or id str for Clicked Notification."""
854
- if not cls.is_on_android():
855
- return "Not on Android"
856
-
857
- saved_intent = cls.__name
858
- cls.__name = None # so value won't be set when opening app not from notification
859
- # print('saved_intent ',saved_intent)
860
- # if not saved_intent or (isinstance(saved_intent, str) and saved_intent.startswith("android.intent")):
861
- # All other notifications are not None after First notification opens app
862
- # NOTE these notifications are also from Last time app was opened and they Still Give Value after first one opens App
863
- # TODO Find a way to get intent when App if Swiped From recents
864
- # Below action is always None
865
- # __PythonActivity = autoclass(ACTIVITY_CLASS_NAME)
866
- # __mactivity = __PythonActivity.mActivity
867
- # __context = cast('android.content.Context', __mactivity)
868
- # __Intent = autoclass('android.content.Intent')
869
- # __intent = __Intent(__context, __PythonActivity)
870
- # action = __intent.getAction()
871
- # print('Start up Intent ----', action)
872
- # print('start Up Title --->',__intent.getStringExtra("title"))
873
-
874
- return saved_intent
875
-
876
- @classmethod
877
- def __notification_handler(cls, intent):
878
- """Calls Function Attached to notification on click.
879
- Don't Call this function manual, it's Already Attach to Notification.
880
-
881
- Sets self.__name #action of Notification that was clicked from Notification.name or Notification.id
882
- """
883
- if not cls.is_on_android():
884
- return "Not on Android"
885
- buttons_object=Notification.btns_box
886
- notifty_functions=Notification.main_functions
887
- if DEV:
888
- print("notifty_functions ",notifty_functions)
889
- print("buttons_object", buttons_object)
890
- try:
891
- action = intent.getAction()
892
- cls.__name = action
893
-
894
- # print("The Action --> ",action)
895
- if action == "android.intent.action.MAIN": # Not Open From Notification
896
- cls.__name = None
897
- return 'Not notification'
898
-
899
- print(intent.getStringExtra("title"))
900
- try:
901
- if action in notifty_functions and notifty_functions[action]:
902
- notifty_functions[action]()
903
- elif action in buttons_object:
904
- buttons_object[action]()
905
- except Exception as notification_handler_function_error:
906
- print("Error Type ",notification_handler_function_error)
907
- print('Failed to run function: ', traceback.format_exc())
908
- except Exception as extracting_notification_props_error:
909
- print('Notify Handler Failed ',extracting_notification_props_error)
910
-
911
- @classmethod
912
- def bindNotifyListener(cls):
913
- """This Creates a Listener for All Notification Clicks and Functions"""
914
- if not cls.is_on_android():
915
- return "Not on Android"
916
- #TODO keep trying BroadcastReceiver
917
- if cls.__bound:
918
- print("binding done already ")
919
- return True
920
- try:
921
- activity.bind(on_new_intent=cls.__notification_handler)
922
- cls.__bound = True
923
- return True
924
- except Exception as binding_listener_error:
925
- print('Failed to bin notifications listener',binding_listener_error)
926
- return False
927
-
928
- @classmethod
929
- def unbindNotifyListener(cls):
930
- """Removes Listener for Notifications Click"""
931
- if not cls.is_on_android():
932
- return "Not on Android"
933
-
934
- #Beta TODO use BroadcastReceiver
935
- try:
936
- activity.unbind(on_new_intent=cls.__notification_handler)
937
- return True
938
- except Exception as unbinding_listener_error:
939
- print("Failed to unbind notifications listener: ",unbinding_listener_error)
940
- return False
941
-
942
- @staticmethod
943
- def is_on_android():
944
- """Utility to check if the app is running on Android."""
945
- return ON_ANDROID
946
-
947
- @staticmethod
948
- def has_permission():
949
- """
950
- Checks if device has permission to send notifications
951
- returns True if device has permission
952
- """
953
- if not ON_ANDROID:
954
- return True
955
- return check_permission(Permission.POST_NOTIFICATIONS)
956
-
957
- @classmethod
958
- @run_on_ui_thread
959
- def asks_permission(cls,callback=None):
960
- """
961
- Ask for permission to send notifications if needed.
962
- Passes True to callback if access granted
963
- """
964
- if cls.__requesting_permission or not ON_ANDROID:
965
- return True
966
-
967
- def on_permissions_result(permissions, grants):
968
- try:
969
- if callback:
970
- if can_accept_arguments(callback, True):
971
- callback(grants[0])
972
- else:
973
- callback()
974
- except Exception as request_permission_error:
975
- print('Exception: ',request_permission_error)
976
- print('Permission response callback error: ',traceback.format_exc())
977
- finally:
978
- cls.__requesting_permission = False
979
-
980
- if not cls.has_permission():
981
- cls.__requesting_permission = True
982
- request_permissions([Permission.POST_NOTIFICATIONS],on_permissions_result)
983
- else:
984
- cls.__requesting_permission = False
985
- if callback:
986
- if can_accept_arguments(callback,True):
987
- callback(True)
988
- else:
989
- callback()
990
-
991
-
992
- 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()