reader 3.21__tar.gz → 3.22__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. {reader-3.21 → reader-3.22}/CHANGES.rst +57 -4
  2. {reader-3.21 → reader-3.22}/MANIFEST.in +3 -1
  3. {reader-3.21/src/reader.egg-info → reader-3.22}/PKG-INFO +9 -13
  4. {reader-3.21 → reader-3.22}/README.rst +7 -11
  5. reader-3.22/docs/app.rst +141 -0
  6. {reader-3.21 → reader-3.22}/docs/cli.rst +4 -10
  7. {reader-3.21 → reader-3.22}/docs/conf.py +2 -0
  8. reader-3.22/docs/config.rst +30 -0
  9. {reader-3.21 → reader-3.22}/docs/dev.rst +30 -37
  10. {reader-3.21 → reader-3.22}/docs/guide.rst +3 -3
  11. {reader-3.21 → reader-3.22}/docs/plugins.rst +17 -16
  12. reader-3.22/docs/screenshots/entries-filters-light.png +0 -0
  13. reader-3.22/docs/screenshots/entries.png +0 -0
  14. reader-3.22/docs/screenshots/entry-image-light.png +0 -0
  15. reader-3.22/docs/screenshots/entry.png +0 -0
  16. reader-3.22/docs/screenshots/feed.png +0 -0
  17. reader-3.22/docs/screenshots/feeds.png +0 -0
  18. reader-3.22/examples/config.toml +26 -0
  19. {reader-3.21 → reader-3.22}/pyproject.toml +7 -4
  20. {reader-3.21 → reader-3.22}/run.sh +1 -1
  21. {reader-3.21 → reader-3.22}/scripts/bench.py +1 -2
  22. reader-3.22/scripts/vendor_app_stuff.py +41 -0
  23. {reader-3.21 → reader-3.22}/src/reader/__init__.py +1 -10
  24. reader-3.22/src/reader/_app/__init__.py +364 -0
  25. {reader-3.21 → reader-3.22}/src/reader/_app/cli.py +14 -10
  26. reader-3.22/src/reader/_app/ext.py +52 -0
  27. {reader-3.21/src/reader/_app/v2 → reader-3.22/src/reader/_app}/forms.py +73 -21
  28. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/__init__.py +27 -59
  29. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/templates/layout.html +4 -5
  30. reader-3.22/src/reader/_app/legacy/wsgi.py +28 -0
  31. reader-3.22/src/reader/_app/static/style.css +70 -0
  32. reader-3.22/src/reader/_app/static/vendor/README +1 -0
  33. reader-3.22/src/reader/_app/static/vendor/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css +5 -0
  34. reader-3.22/src/reader/_app/static/vendor/bootstrap-icons@1.13.1/font/fonts/bootstrap-icons.woff +0 -0
  35. reader-3.22/src/reader/_app/static/vendor/bootstrap-icons@1.13.1/font/fonts/bootstrap-icons.woff2 +0 -0
  36. reader-3.22/src/reader/_app/static/vendor/bootstrap@5.3.8/dist/css/bootstrap.min.css +6 -0
  37. reader-3.22/src/reader/_app/static/vendor/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js +7 -0
  38. reader-3.22/src/reader/_app/static/vendor/htmx-ext-response-targets@2.0.4/dist/response-targets.min.js +1 -0
  39. reader-3.22/src/reader/_app/static/vendor/htmx.org@2.0.8/dist/htmx.min.js +1 -0
  40. reader-3.22/src/reader/_app/templates/add_feed.html +46 -0
  41. reader-3.22/src/reader/_app/templates/change_feed_title.html +56 -0
  42. reader-3.22/src/reader/_app/templates/delete_feed.html +37 -0
  43. reader-3.22/src/reader/_app/templates/entries.html +189 -0
  44. reader-3.22/src/reader/_app/templates/entry.html +135 -0
  45. reader-3.22/src/reader/_app/templates/feeds.html +81 -0
  46. reader-3.22/src/reader/_app/templates/layout.html +1 -0
  47. reader-3.21/src/reader/_app/v2/templates/v2/layout.html → reader-3.22/src/reader/_app/templates/layout_base.html +27 -29
  48. reader-3.22/src/reader/_app/templates/macros.html +304 -0
  49. reader-3.22/src/reader/_app/wsgi.py +28 -0
  50. {reader-3.21 → reader-3.22}/src/reader/_cli.py +103 -132
  51. reader-3.22/src/reader/_config_utils.py +166 -0
  52. {reader-3.21 → reader-3.22}/src/reader/_parser/__init__.py +15 -0
  53. {reader-3.21 → reader-3.22}/src/reader/_parser/requests/__init__.py +0 -1
  54. reader-3.22/src/reader/_plugins/__init__.py +7 -0
  55. {reader-3.21 → reader-3.22}/src/reader/_plugins/cli_status.py +8 -4
  56. reader-3.22/src/reader/_plugins/legacy/__init__.py +3 -0
  57. {reader-3.21/src/reader/_plugins → reader-3.22/src/reader/_plugins/legacy}/enclosure_tags.py +2 -2
  58. {reader-3.21/src/reader/_plugins → reader-3.22/src/reader/_plugins/legacy}/preview_feed_list.py +4 -4
  59. {reader-3.21/src/reader/_plugins → reader-3.22/src/reader/_plugins/legacy}/share.py +2 -2
  60. {reader-3.21 → reader-3.22}/src/reader/_plugins/sqlite_releases.py +2 -2
  61. {reader-3.21 → reader-3.22}/src/reader/_plugins/timer.py +1 -1
  62. {reader-3.21 → reader-3.22}/src/reader/_storage/__init__.py +0 -2
  63. {reader-3.21 → reader-3.22}/src/reader/_storage/_entries.py +1 -1
  64. {reader-3.21 → reader-3.22}/src/reader/_storage/_sqlite_utils.py +1 -1
  65. {reader-3.21 → reader-3.22}/src/reader/_types.py +2 -2
  66. {reader-3.21 → reader-3.22}/src/reader/_utils.py +8 -0
  67. {reader-3.21 → reader-3.22}/src/reader/core.py +41 -25
  68. reader-3.22/src/reader/plugins/__init__.py +53 -0
  69. reader-3.22/src/reader/plugins/_loader.py +82 -0
  70. {reader-3.21 → reader-3.22}/src/reader/plugins/enclosure_dedupe.py +4 -2
  71. {reader-3.21 → reader-3.22}/src/reader/plugins/entry_dedupe.py +4 -2
  72. {reader-3.21 → reader-3.22}/src/reader/plugins/mark_as_read.py +4 -2
  73. {reader-3.21 → reader-3.22}/src/reader/plugins/readtime.py +4 -2
  74. {reader-3.21 → reader-3.22}/src/reader/plugins/ua_fallback.py +4 -2
  75. {reader-3.21 → reader-3.22/src/reader.egg-info}/PKG-INFO +9 -13
  76. {reader-3.21 → reader-3.22}/src/reader.egg-info/SOURCES.txt +49 -37
  77. {reader-3.21 → reader-3.22}/src/reader.egg-info/requires.txt +1 -1
  78. reader-3.22/tests/_plugins/builtin.py +2 -0
  79. reader-3.22/tests/_plugins/error_during_import.py +1 -0
  80. reader-3.22/tests/_plugins/error_import_error.py +1 -0
  81. reader-3.21/tests/test_app.py → reader-3.22/tests/test_app_legacy.py +9 -9
  82. {reader-3.21 → reader-3.22}/tests/test_app_wsgi.py +3 -3
  83. {reader-3.21 → reader-3.22}/tests/test_cli.py +37 -151
  84. reader-3.22/tests/test_config_utils.py +107 -0
  85. {reader-3.21 → reader-3.22}/tests/test_lazy_imports.py +3 -1
  86. {reader-3.21 → reader-3.22}/tests/test_plugins_cli_status.py +2 -4
  87. {reader-3.21 → reader-3.22}/tests/test_plugins_enclosure_dedupe.py +1 -1
  88. {reader-3.21 → reader-3.22}/tests/test_plugins_entry_dedupe.py +1 -1
  89. reader-3.22/tests/test_plugins_loader.py +103 -0
  90. {reader-3.21 → reader-3.22}/tests/test_plugins_mark_as_read.py +5 -7
  91. {reader-3.21 → reader-3.22}/tests/test_plugins_preview_feed_list.py +6 -6
  92. {reader-3.21 → reader-3.22}/tests/test_plugins_readtime.py +4 -4
  93. {reader-3.21 → reader-3.22}/tests/test_plugins_sqlite_releases.py +2 -2
  94. {reader-3.21 → reader-3.22}/tests/test_plugins_ua_fallback.py +2 -2
  95. {reader-3.21 → reader-3.22}/tests/test_reader.py +2 -6
  96. {reader-3.21 → reader-3.22}/tests/test_reader_filter.py +4 -2
  97. {reader-3.21 → reader-3.22}/tests/test_reader_search.py +10 -2
  98. {reader-3.21 → reader-3.22}/tests/test_reader_sort.py +7 -0
  99. reader-3.21/docs/app.rst +0 -155
  100. reader-3.21/docs/config.rst +0 -37
  101. reader-3.21/docs/dev-app.rst +0 -138
  102. reader-3.21/docs/images/redesign-01.png +0 -0
  103. reader-3.21/docs/screenshots/dillo.png +0 -0
  104. reader-3.21/docs/screenshots/entries-feed.png +0 -0
  105. reader-3.21/docs/screenshots/entries-v2-dark.png +0 -0
  106. reader-3.21/docs/screenshots/entries-v2-filters-light.png +0 -0
  107. reader-3.21/docs/screenshots/entries.png +0 -0
  108. reader-3.21/docs/screenshots/entry-one.png +0 -0
  109. reader-3.21/docs/screenshots/entry-two.png +0 -0
  110. reader-3.21/docs/screenshots/feeds.png +0 -0
  111. reader-3.21/docs/screenshots/lynx.png +0 -0
  112. reader-3.21/docs/screenshots/search.png +0 -0
  113. reader-3.21/examples/config.yaml +0 -100
  114. reader-3.21/src/reader/_app/v2/__init__.py +0 -123
  115. reader-3.21/src/reader/_app/v2/static/style.css +0 -27
  116. reader-3.21/src/reader/_app/v2/templates/v2/entries.html +0 -234
  117. reader-3.21/src/reader/_app/v2/templates/v2/macros.html +0 -47
  118. reader-3.21/src/reader/_app/wsgi.py +0 -42
  119. reader-3.21/src/reader/_config.py +0 -161
  120. reader-3.21/src/reader/_plugins/__init__.py +0 -65
  121. reader-3.21/src/reader/plugins/__init__.py +0 -64
  122. reader-3.21/tests/reader_test_plugins/good.py +0 -2
  123. reader-3.21/tests/reader_test_plugins/init_error.py +0 -2
  124. reader-3.21/tests/reader_test_plugins/missing_dependency.py +0 -1
  125. reader-3.21/tests/reader_test_plugins/missing_entry_point.py +0 -1
  126. reader-3.21/tests/test_config.py +0 -116
  127. reader-3.21/tests/test_reader_plugins.py +0 -87
  128. {reader-3.21 → reader-3.22}/LICENSE +0 -0
  129. {reader-3.21 → reader-3.22}/docs/api.rst +0 -0
  130. {reader-3.21 → reader-3.22}/docs/changelog.rst +0 -0
  131. {reader-3.21 → reader-3.22}/docs/contributing.rst +0 -0
  132. {reader-3.21 → reader-3.22}/docs/index.rst +0 -0
  133. {reader-3.21 → reader-3.22}/docs/install.rst +0 -0
  134. {reader-3.21 → reader-3.22}/docs/internal.rst +0 -0
  135. {reader-3.21 → reader-3.22}/docs/tutorial.rst +0 -0
  136. {reader-3.21 → reader-3.22}/docs/why.rst +0 -0
  137. {reader-3.21 → reader-3.22}/examples/custom_headers.py +0 -0
  138. {reader-3.21 → reader-3.22}/examples/feed_slugs.py +0 -0
  139. {reader-3.21 → reader-3.22}/examples/parser_only.py +0 -0
  140. {reader-3.21 → reader-3.22}/examples/podcast.py +0 -0
  141. {reader-3.21 → reader-3.22}/examples/terminal.py +0 -0
  142. {reader-3.21 → reader-3.22}/scripts/backup.sh +0 -0
  143. {reader-3.21 → reader-3.22}/scripts/debug_storage_stats.py +0 -0
  144. {reader-3.21 → reader-3.22}/scripts/entry_dedupe_backtest.py +0 -0
  145. {reader-3.21 → reader-3.22}/scripts/jscontrols.html +0 -0
  146. {reader-3.21 → reader-3.22}/scripts/jscontrols.py +0 -0
  147. {reader-3.21 → reader-3.22}/scripts/lines.sh +0 -0
  148. {reader-3.21 → reader-3.22}/scripts/release.py +0 -0
  149. {reader-3.21 → reader-3.22}/setup.cfg +0 -0
  150. {reader-3.21 → reader-3.22}/src/reader/__main__.py +0 -0
  151. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/api_thing.py +0 -0
  152. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/static/controls.js +0 -0
  153. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/static/style.css +0 -0
  154. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/templates/add_entry.html +0 -0
  155. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/templates/entries.html +0 -0
  156. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/templates/entry.html +0 -0
  157. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/templates/feeds.html +0 -0
  158. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/templates/macros.html +0 -0
  159. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/templates/metadata.html +0 -0
  160. {reader-3.21/src/reader/_app → reader-3.22/src/reader/_app/legacy}/templates/tags.html +0 -0
  161. {reader-3.21/src/reader/_app/v2 → reader-3.22/src/reader/_app}/static/theme.js +0 -0
  162. {reader-3.21 → reader-3.22}/src/reader/_hash_utils.py +0 -0
  163. {reader-3.21 → reader-3.22}/src/reader/_parser/_http_utils.py +0 -0
  164. {reader-3.21 → reader-3.22}/src/reader/_parser/_lazy.py +0 -0
  165. {reader-3.21 → reader-3.22}/src/reader/_parser/_url_utils.py +0 -0
  166. {reader-3.21 → reader-3.22}/src/reader/_parser/feedparser.py +0 -0
  167. {reader-3.21 → reader-3.22}/src/reader/_parser/file.py +0 -0
  168. {reader-3.21 → reader-3.22}/src/reader/_parser/http.py +0 -0
  169. {reader-3.21 → reader-3.22}/src/reader/_parser/jsonfeed.py +0 -0
  170. {reader-3.21 → reader-3.22}/src/reader/_parser/requests/_lazy.py +0 -0
  171. {reader-3.21/src/reader/_plugins → reader-3.22/src/reader/_plugins/legacy}/templates/preview_feed_list.html +0 -0
  172. {reader-3.21 → reader-3.22}/src/reader/_storage/_base.py +0 -0
  173. {reader-3.21 → reader-3.22}/src/reader/_storage/_changes.py +0 -0
  174. {reader-3.21 → reader-3.22}/src/reader/_storage/_feeds.py +0 -0
  175. {reader-3.21 → reader-3.22}/src/reader/_storage/_html_utils.py +0 -0
  176. {reader-3.21 → reader-3.22}/src/reader/_storage/_schema.py +0 -0
  177. {reader-3.21 → reader-3.22}/src/reader/_storage/_search.py +0 -0
  178. {reader-3.21 → reader-3.22}/src/reader/_storage/_sql_utils.py +0 -0
  179. {reader-3.21 → reader-3.22}/src/reader/_storage/_tags.py +0 -0
  180. {reader-3.21 → reader-3.22}/src/reader/_update.py +0 -0
  181. {reader-3.21 → reader-3.22}/src/reader/_vendor/__init__.py +0 -0
  182. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/__init__.py +0 -0
  183. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/api.py +0 -0
  184. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/datetimes/__init__.py +0 -0
  185. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/datetimes/asctime.py +0 -0
  186. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/datetimes/greek.py +0 -0
  187. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/datetimes/hungarian.py +0 -0
  188. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/datetimes/iso8601.py +0 -0
  189. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/datetimes/korean.py +0 -0
  190. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/datetimes/perforce.py +0 -0
  191. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/datetimes/rfc822.py +0 -0
  192. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/datetimes/w3dtf.py +0 -0
  193. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/encodings.py +0 -0
  194. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/exceptions.py +0 -0
  195. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/html.py +0 -0
  196. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/http.py +0 -0
  197. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/mixin.py +0 -0
  198. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/namespaces/__init__.py +0 -0
  199. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/namespaces/_base.py +0 -0
  200. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/namespaces/admin.py +0 -0
  201. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/namespaces/cc.py +0 -0
  202. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/namespaces/dc.py +0 -0
  203. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/namespaces/georss.py +0 -0
  204. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/namespaces/itunes.py +0 -0
  205. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/namespaces/mediarss.py +0 -0
  206. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/namespaces/psc.py +0 -0
  207. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/parsers/__init__.py +0 -0
  208. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/parsers/json.py +0 -0
  209. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/parsers/loose.py +0 -0
  210. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/parsers/strict.py +0 -0
  211. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/py.typed +0 -0
  212. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/sanitizer.py +0 -0
  213. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/sgml.py +0 -0
  214. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/urls.py +0 -0
  215. {reader-3.21 → reader-3.22}/src/reader/_vendor/feedparser/util.py +0 -0
  216. {reader-3.21 → reader-3.22}/src/reader/exceptions.py +0 -0
  217. {reader-3.21 → reader-3.22}/src/reader/py.typed +0 -0
  218. {reader-3.21 → reader-3.22}/src/reader/types.py +0 -0
  219. {reader-3.21 → reader-3.22}/src/reader/utils.py +0 -0
  220. {reader-3.21 → reader-3.22}/src/reader.egg-info/dependency_links.txt +0 -0
  221. {reader-3.21 → reader-3.22}/src/reader.egg-info/top_level.txt +0 -0
  222. {reader-3.21/tests/reader_test_plugins → reader-3.22/tests/_plugins}/__init__.py +0 -0
  223. {reader-3.21 → reader-3.22}/tests/conftest.py +0 -0
  224. {reader-3.21 → reader-3.22}/tests/data/10.json +0 -0
  225. {reader-3.21 → reader-3.22}/tests/data/10.json.py +0 -0
  226. {reader-3.21 → reader-3.22}/tests/data/custom +0 -0
  227. {reader-3.21 → reader-3.22}/tests/data/empty.atom +0 -0
  228. {reader-3.21 → reader-3.22}/tests/data/empty.atom.py +0 -0
  229. {reader-3.21 → reader-3.22}/tests/data/empty.json +0 -0
  230. {reader-3.21 → reader-3.22}/tests/data/empty.json.py +0 -0
  231. {reader-3.21 → reader-3.22}/tests/data/empty.rss +0 -0
  232. {reader-3.21 → reader-3.22}/tests/data/empty.rss.py +0 -0
  233. {reader-3.21 → reader-3.22}/tests/data/full.atom +0 -0
  234. {reader-3.21 → reader-3.22}/tests/data/full.atom.py +0 -0
  235. {reader-3.21 → reader-3.22}/tests/data/full.json +0 -0
  236. {reader-3.21 → reader-3.22}/tests/data/full.json.py +0 -0
  237. {reader-3.21 → reader-3.22}/tests/data/full.rss +0 -0
  238. {reader-3.21 → reader-3.22}/tests/data/full.rss.py +0 -0
  239. {reader-3.21 → reader-3.22}/tests/data/invalid.json +0 -0
  240. {reader-3.21 → reader-3.22}/tests/data/invalid.json.py +0 -0
  241. {reader-3.21 → reader-3.22}/tests/data/relative.atom +0 -0
  242. {reader-3.21 → reader-3.22}/tests/data/relative.atom.py +0 -0
  243. {reader-3.21 → reader-3.22}/tests/data/relative.rss +0 -0
  244. {reader-3.21 → reader-3.22}/tests/data/relative.rss.py +0 -0
  245. {reader-3.21 → reader-3.22}/tests/data/sqlite_releases.html +0 -0
  246. {reader-3.21 → reader-3.22}/tests/data/unknown.json +0 -0
  247. {reader-3.21 → reader-3.22}/tests/data/unknown.json.py +0 -0
  248. {reader-3.21 → reader-3.22}/tests/fakeparser.py +0 -0
  249. {reader-3.21 → reader-3.22}/tests/reader_methods.py +0 -0
  250. {reader-3.21 → reader-3.22}/tests/test__types.py +0 -0
  251. {reader-3.21 → reader-3.22}/tests/test__utils.py +0 -0
  252. {reader-3.21 → reader-3.22}/tests/test_bench.py +0 -0
  253. {reader-3.21 → reader-3.22}/tests/test_changes.py +0 -0
  254. {reader-3.21 → reader-3.22}/tests/test_exceptions.py +0 -0
  255. {reader-3.21 → reader-3.22}/tests/test_hash_utils.py +0 -0
  256. {reader-3.21 → reader-3.22}/tests/test_html_utils.py +0 -0
  257. {reader-3.21 → reader-3.22}/tests/test_parser.py +0 -0
  258. {reader-3.21 → reader-3.22}/tests/test_reader_counts.py +0 -0
  259. {reader-3.21 → reader-3.22}/tests/test_reader_deprecations.py +0 -0
  260. {reader-3.21 → reader-3.22}/tests/test_reader_hooks.py +0 -0
  261. {reader-3.21 → reader-3.22}/tests/test_reader_integration.py +0 -0
  262. {reader-3.21 → reader-3.22}/tests/test_reader_lifecycle.py +0 -0
  263. {reader-3.21 → reader-3.22}/tests/test_reader_private.py +0 -0
  264. {reader-3.21 → reader-3.22}/tests/test_reader_update.py +0 -0
  265. {reader-3.21 → reader-3.22}/tests/test_reader_utils.py +0 -0
  266. {reader-3.21 → reader-3.22}/tests/test_search.py +0 -0
  267. {reader-3.21 → reader-3.22}/tests/test_sql_utils.py +0 -0
  268. {reader-3.21 → reader-3.22}/tests/test_sqlite_utils.py +0 -0
  269. {reader-3.21 → reader-3.22}/tests/test_storage.py +0 -0
  270. {reader-3.21 → reader-3.22}/tests/test_tags.py +0 -0
  271. {reader-3.21 → reader-3.22}/tests/test_types.py +0 -0
  272. {reader-3.21 → reader-3.22}/tests/utils.py +0 -0
  273. {reader-3.21 → reader-3.22}/tox.ini +0 -0
@@ -6,6 +6,59 @@ Changelog
6
6
  :no-index:
7
7
 
8
8
 
9
+ Version 3.22
10
+ ------------
11
+
12
+ Released 2026-04-01
13
+
14
+ * :func:`make_reader` plugin loading improvements. (:issue:`395`)
15
+
16
+ * ``plugins`` now supports arbitrary import paths.
17
+ * :ref:`Built-in plugins <built-in plugins>` now use the
18
+ ``.<plugin>`` naming scheme, instead of ``reader.<plugin>``;
19
+ support for the latter is deprecated and will be removed in version 4.0.
20
+
21
+ * :meth:`~Reader.get_feeds`, :meth:`~Reader.get_entries`, and
22
+ :meth:`~Reader.search_entries` now raise exceptions
23
+ for invalid ``query`` and ``starting_after`` eagerly,
24
+ before the iterable is consumed.
25
+ Thanks to `Omprakash Choudhary`_ for the PR.
26
+ (:issue:`388`)
27
+
28
+ * :doc:`app` improvements.
29
+
30
+ * Finish the web app re-design MVP,
31
+ including:
32
+ add / list / filter / delete feeds,
33
+ list / filter articles,
34
+ article view,
35
+ mark articles as read / (un)important,
36
+ article view,
37
+ custom feed titles,
38
+ dark mode,
39
+ CSRF protection,
40
+ vendored CSS / JS dependencies.
41
+
42
+ * Make the new web app the default (entry point ``reader._app.wsgi:app``);
43
+ the :ref:`legacy web app <legacy web app>` remains available
44
+ at ``reader._app.legacy.wsgi:app``.
45
+
46
+ * Update both web apps to use the new configuration infrastructure (see below).
47
+
48
+ * :doc:`CLI <cli>` and :doc:`config file <config>` breaking changes. (:issue:`395`)
49
+
50
+ * The config file format changed from YAML to TOML,
51
+ and follows the shape of the CLI.
52
+ * The ``reader serve`` command was renamed to ``reader web``.
53
+ * Plugin loading environment variables changed:
54
+ ``READER_PLUGIN`` -> ``READER_PLUGINS``,
55
+ ``READER_CLI_PLUGIN`` -> ``READER_CLI_PLUGINS``,
56
+ ``READER_APP_PLUGIN`` -> ``READER_WEB_PLUGINS``.
57
+
58
+
59
+ .. _Omprakash Choudhary: https://github.com/omseervi098
60
+
61
+
9
62
  Version 3.21
10
63
  ------------
11
64
 
@@ -251,7 +304,7 @@ Released 2024-07-23
251
304
  * Fix bug in the :mod:`~reader.plugins.entry_dedupe` plugin causing entries
252
305
  to flip-flop if there were multiple *new* duplicates of the same issue
253
306
  (on the first update, one entry remains, on the second update, the other);
254
- related to the bug fixed in `version 3.2 <Version 3.2_>`_.
307
+ related to the bug fixed in `version 3.2 <Version 3.2_>`__.
255
308
  (:issue:`340`)
256
309
 
257
310
  * :mod:`~reader._plugins.enclosure_tags` plugin improvements. (:issue:`344`)
@@ -294,7 +347,7 @@ Released 2024-06-19
294
347
  * Update an entry whenever its :attr:`~Entry.updated` changes
295
348
  (don't require it to be newer).
296
349
 
297
- * Fix bug introduced in `version 3.12 <Version 3.12_>`_ causing an assertion error
350
+ * Fix bug introduced in `version 3.12 <Version 3.12_>`__ causing an assertion error
298
351
  when there are multiple entries with the same id in the same feed,
299
352
  or when parallel :meth:`~Reader.update_feeds` calls add the same entry.
300
353
  The fix restores the pre-3.12 first-entry-wins / last-write-wins behavior.
@@ -445,7 +498,7 @@ Released 2023-08-20
445
498
 
446
499
  * Add werkzeug dependency,
447
500
  instead of vendoring selected :mod:`werkzeug.http` utilities.
448
- * Rework lazy imports introduced in `version 3.3 <Version 3.3_>`_.
501
+ * Rework lazy imports introduced in `version 3.3 <Version 3.3_>`__.
449
502
  (:issue:`316`)
450
503
  * Make :mod:`reader._parser` a package, and move parsing-related modules into it.
451
504
  (:issue:`316`)
@@ -506,7 +559,7 @@ Released 2023-03-19
506
559
  so one can express "explicitly unimportant" (*don't care*)
507
560
  by setting it to :const:`False`.
508
561
  This replaces the semantics for *don't care* introduced
509
- in `version 2.2 <Version 2.2_>`_.
562
+ in `version 2.2 <Version 2.2_>`__.
510
563
  (:issue:`254`)
511
564
 
512
565
  .. warning::
@@ -1,7 +1,9 @@
1
1
  recursive-include src/reader/_app/templates *
2
2
  recursive-include src/reader/_app/static *
3
- recursive-include src/reader/_app/v2 *
4
3
  recursive-include src/reader/_plugins/templates *
4
+ recursive-include src/reader/_app/legacy/templates *
5
+ recursive-include src/reader/_app/legacy/static *
6
+ recursive-include src/reader/_plugins/legacy/templates *
5
7
  recursive-include src/reader *.pyi
6
8
  recursive-include src/reader py.typed
7
9
  include run.sh CHANGES.rst LICENSE tox.ini
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reader
3
- Version: 3.21
3
+ Version: 3.22
4
4
  Summary: A Python feed reader library.
5
5
  Author: lemon24
6
6
  License: BSD-3-Clause
@@ -45,12 +45,12 @@ Provides-Extra: all
45
45
  Requires-Dist: reader[app,cli,unstable-plugins]; extra == "all"
46
46
  Provides-Extra: cli
47
47
  Requires-Dist: click>=7; extra == "cli"
48
- Requires-Dist: PyYAML; extra == "cli"
49
48
  Provides-Extra: app
50
49
  Requires-Dist: flask>=0.10; extra == "app"
51
50
  Requires-Dist: humanize>=4; extra == "app"
52
51
  Requires-Dist: PyYAML; extra == "app"
53
52
  Requires-Dist: WTForms; extra == "app"
53
+ Requires-Dist: Flask-WTF; extra == "app"
54
54
  Requires-Dist: jinja2-fragments; extra == "app"
55
55
  Provides-Extra: unstable-plugins
56
56
  Requires-Dist: requests; extra == "unstable-plugins"
@@ -68,7 +68,9 @@ Dynamic: license-file
68
68
 
69
69
  It is designed to allow writing feed reader applications
70
70
  without any business code,
71
- and without depending on a particular framework.
71
+ and without depending on a particular framework;
72
+ in MVC terms,
73
+ you'd probably call it a fat model.
72
74
 
73
75
  .. end-intro
74
76
 
@@ -122,19 +124,13 @@ and without depending on a particular framework.
122
124
 
123
125
  What *reader* doesn't do:
124
126
 
125
- * provide an UI
126
- * provide a REST API (yet)
127
127
  * depend on a web framework
128
- * have an opinion of how/where you use it
128
+ * have an opinion of how or where you use it
129
129
 
130
- The following exist, but are optional (and frankly, a bit unpolished):
130
+ In addition, *reader* provides:
131
131
 
132
- * a minimal web interface
133
-
134
- * that works even with text-only browsers
135
- * with automatic tag fixing for podcasts (MP3 enclosures)
136
-
137
- * a command-line interface
132
+ * an optional web application based on Flask, Bootstrap, and htmx
133
+ * an optional command-line interface
138
134
 
139
135
  .. end-features
140
136
 
@@ -4,7 +4,9 @@
4
4
 
5
5
  It is designed to allow writing feed reader applications
6
6
  without any business code,
7
- and without depending on a particular framework.
7
+ and without depending on a particular framework;
8
+ in MVC terms,
9
+ you'd probably call it a fat model.
8
10
 
9
11
  .. end-intro
10
12
 
@@ -58,19 +60,13 @@ and without depending on a particular framework.
58
60
 
59
61
  What *reader* doesn't do:
60
62
 
61
- * provide an UI
62
- * provide a REST API (yet)
63
63
  * depend on a web framework
64
- * have an opinion of how/where you use it
64
+ * have an opinion of how or where you use it
65
65
 
66
- The following exist, but are optional (and frankly, a bit unpolished):
66
+ In addition, *reader* provides:
67
67
 
68
- * a minimal web interface
69
-
70
- * that works even with text-only browsers
71
- * with automatic tag fixing for podcasts (MP3 enclosures)
72
-
73
- * a command-line interface
68
+ * an optional web application based on Flask, Bootstrap, and htmx
69
+ * an optional command-line interface
74
70
 
75
71
  .. end-features
76
72
 
@@ -0,0 +1,141 @@
1
+
2
+ Web application
3
+ ===============
4
+
5
+ *reader* comes with a web application
6
+ based on `Flask`_, `Bootstrap`_, and `htmx`_,
7
+ intended to work across all browsers,
8
+ including mobile and light-weight / text-only ones.
9
+
10
+ .. _Flask: https://flask.palletsprojects.com/
11
+ .. _Bootstrap: https://getbootstrap.com/
12
+ .. _htmx: https://htmx.org/
13
+
14
+ Features, as of *reader* version |version|:
15
+
16
+ * add / list / filter / delete feeds
17
+ * list / filter articles
18
+ * mark articles as read / (un)important
19
+ * article view
20
+ * custom feed titles
21
+ * dark mode
22
+
23
+ More features already implemented in the library
24
+ and the :ref:`legacy web app <legacy web app>`
25
+ should be added in the next releases;
26
+ see the :ref:`roadmap <app roadmap>` for details.
27
+
28
+
29
+
30
+ .. _app screenshots:
31
+
32
+ Screenshots
33
+ -----------
34
+
35
+ .. figure:: screenshots/entries.png
36
+ :width: 240px
37
+
38
+ main page (dark mode)
39
+
40
+ .. figure:: screenshots/entries-filters-light.png
41
+ :width: 240px
42
+
43
+ main page – more filters (light mode)
44
+
45
+ .. figure:: screenshots/feed.png
46
+ :width: 240px
47
+
48
+ feed page (dark mode)
49
+
50
+ .. figure:: screenshots/feeds.png
51
+ :width: 240px
52
+
53
+ feeds page (dark mode)
54
+
55
+ .. figure:: screenshots/entry.png
56
+ :width: 240px
57
+
58
+ article view (dark mode)
59
+
60
+ .. figure:: screenshots/entry-image-light.png
61
+ :width: 240px
62
+
63
+ article view (light mode)
64
+
65
+
66
+
67
+ Serving the web app
68
+ -------------------
69
+
70
+ .. note::
71
+
72
+ The web application is optional, use the ``app`` extra to install
73
+ its :ref:`dependencies <Optional dependencies>`.
74
+
75
+
76
+ *reader* exposes a standard WSGI application as ``reader._app.wsgi:app``.
77
+ See the `Flask documentation`_ for more details on how to deploy it.
78
+ The path to the reader database can be configured through the
79
+ :doc:`config file <config>`
80
+ or the ``READER_DB`` environment variable.
81
+
82
+ .. warning::
83
+
84
+ The web application has no authentication / authorization whatsoever;
85
+ it is expected a server / middleware will provide that.
86
+
87
+
88
+ An example uWSGI configuration file (probably not idiomatic, from `here`_)::
89
+
90
+ [uwsgi]
91
+ socket = /apps/reader/uwsgi/sock
92
+ manage-script-name = true
93
+ mount = /reader=reader._app.wsgi:app
94
+ plugin = python3
95
+ virtualenv = /apps/reader/
96
+ env = READER_CONFIG=/apps/reader/reader.toml
97
+
98
+
99
+ You can also run the web application with the ``web`` command.
100
+ ``web`` uses `Werkzeug's development server`_,
101
+ so it probably won't scale well past a single user.
102
+
103
+ .. note::
104
+
105
+ For privacy reasons,
106
+ you may want to configure your web server to not send a ``Referer`` header
107
+ (by setting ``Referrer-Policy`` header to ``same-origin``
108
+ for all responses; `nginx example`_).
109
+ The ``web`` command does it by default.
110
+
111
+
112
+ If running on a personal computer, you can use cron to run it at boot::
113
+
114
+ @reboot sleep 60; reader web -p 8080 2>&1 ) >>"/tmp/$LOGNAME.reader.web.run.boot.log"
115
+
116
+
117
+ .. _here: https://github.com/lemon24/owncloud/blob/8009f227ef60ebaab621e7bb3363ec9071d8a2e8/reader.yaml#L103-L116
118
+ .. _nginx example: https://github.com/lemon24/owncloud/blob/8009f227ef60ebaab621e7bb3363ec9071d8a2e8/secure.conf#L23
119
+ .. _Flask documentation: https://flask.palletsprojects.com/en/stable/deploying/
120
+ .. _Werkzeug's development server: https://werkzeug.palletsprojects.com/en/stable/serving/#werkzeug.serving.run_simple
121
+
122
+
123
+
124
+ .. _legacy web app:
125
+
126
+ Legacy web app
127
+ --------------
128
+
129
+ Before the current web application,
130
+ there was another one,
131
+ serving as test bed for new features.
132
+ It is usable, if a bit unpolished,
133
+ but was never meant to be a long-term thing,
134
+ hence the new app;
135
+ you can find screenshots
136
+ `here <https://github.com/lemon24/reader/blob/3.21/docs/app.rst#screenshots-legacy>`_.
137
+
138
+ The WSGI entry point is ``reader._app.legacy.wsgi:app``.
139
+
140
+ The legacy web app should remain available
141
+ until the new app reaches feature parity.
@@ -2,18 +2,12 @@
2
2
  Command-line interface
3
3
  ======================
4
4
 
5
- *reader* comes with a command-line interface
6
- that exposes basic management functionality.
7
-
8
-
9
- .. warning::
10
-
11
- The CLI is is not fully stable,
12
- see the :ref:`roadmap <cli roadmap>` for details.
5
+ *reader* comes with a CLI
6
+ that exposes management functionality.
13
7
 
14
8
  .. note::
15
9
 
16
- The command-line interface is optional, use the ``cli`` extra to install
10
+ The CLI is optional, use the ``cli`` extra to install
17
11
  its :ref:`dependencies <Optional dependencies>`.
18
12
 
19
13
  Most commands need a database to work. The following are equivalent:
@@ -42,7 +36,7 @@ Serve the web application locally (at http://localhost:8080/):
42
36
 
43
37
  .. code-block:: bash
44
38
 
45
- python -m reader serve
39
+ python -m reader web
46
40
 
47
41
 
48
42
  .. _cli-update:
@@ -17,6 +17,7 @@ for name in [
17
17
  'flask.signals',
18
18
  'werkzeug',
19
19
  'werkzeug.datastructures',
20
+ 'werkzeug.exceptions',
20
21
  'werkzeug.http',
21
22
  'yaml',
22
23
  ]:
@@ -45,6 +46,7 @@ autodoc_mock_imports = [
45
46
  'bs4',
46
47
  'mutagen',
47
48
  'flask',
49
+ 'flask_wtf',
48
50
  'werkzeug',
49
51
  'humanize',
50
52
  'markupsafe',
@@ -0,0 +1,30 @@
1
+
2
+ Configuration
3
+ =============
4
+
5
+ Both the :doc:`CLI <cli>` and the :doc:`web application <app>` can
6
+ be configured from a TOML file.
7
+
8
+ .. note::
9
+
10
+ Configuration file loading dependencies get installed automatically when
11
+ installing the CLI or the web application
12
+ :ref:`extras <Optional dependencies>`.
13
+
14
+
15
+ The configuration file path can be specified either through the ``--config``
16
+ CLI option or through the ``READER_CONFIG`` environment variable
17
+ (also usable with the web application).
18
+
19
+ The configuration file matches the shape of the :doc:`CLI <cli>`
20
+ (the ``reader`` section has options for the ``reader`` command,
21
+ the ``reader.update`` section has options for the ``reader update`` command, etc.).
22
+ In general, option names match those in the CLI
23
+ (``--feed-root`` -> ``feed_root``);
24
+ options that can be passed multiple times in the CLI
25
+ are pluralized in the config
26
+ (``--cli-plugin`` -> ``cli_plugins``).
27
+
28
+ Example:
29
+
30
+ .. literalinclude:: ../examples/config.toml
@@ -59,22 +59,22 @@ but I will prioritize supporting :doc:`contributors <contributing>`
59
59
  * resource tags
60
60
 
61
61
  * :ref:`searchable tag values <searchable tags>`, e.g. for comments
62
- * :ref:`unification with entry.read/important <entry flag unification>`
63
62
  * optimistic locking, :issue:`308`
64
63
  * filter tags by prefix, :issue:`309`
65
64
 
66
-
67
- * HTTP compliance, likely as plugins
65
+ * HTTP behavior / compliance, likely as plugins, :issue:`377`
68
66
 
69
67
  * 301 Moved Permanently, :issue:`246`
70
68
  * 410 Gone, :issue:`246`
71
- * 429 Too Many Requests, :issue:`307`
69
+ * slow down on throttling / max-age, :issue:`378`
70
+ * match the rhythm of the feed, :issue:`382`
72
71
 
73
72
  * add more fields to data objects
74
73
 
74
+ * .links attribute, :issue:`320`
75
+ * .authors attribute, :issue:`391`
75
76
  * extra data, as an escape hatch, :issue:`277`
76
77
 
77
- * :ref:`multiple storage implementations <multiple storage implementations>`
78
78
  * :ref:`batch get methods <batch get methods>`
79
79
  * :doc:`internal` stabilization
80
80
  * arbitrary website scraping, :issue:`222`
@@ -93,15 +93,16 @@ but I will prioritize supporting :doc:`contributors <contributing>`
93
93
  Command-line interface
94
94
  ~~~~~~~~~~~~~~~~~~~~~~
95
95
 
96
- The :doc:`cli` is more or less stable,\ [*]_
97
- although both the output and config loading need more polish
98
- and additional tests.
96
+ The :doc:`cli` is more or less stable,
97
+ although it could use additional tests.
99
98
 
100
- A full-blown terminal feed reader is *not* in scope,
99
+ A terminal feed reader is *not* in scope,
101
100
  since I don't need one,
102
- but I'm not opposed to the idea.
101
+ but I'm not opposed to the idea;
102
+ note that the web app should already
103
+ work with text-based browsers such as `Lynx`_.
103
104
 
104
- .. [*] With the exception of ``serve``, which is provided by the web app.
105
+ .. _Lynx: https://en.wikipedia.org/wiki/Lynx_(web_browser)
105
106
 
106
107
 
107
108
  .. _app roadmap:
@@ -109,27 +110,23 @@ but I'm not opposed to the idea.
109
110
  Web application
110
111
  ~~~~~~~~~~~~~~~
111
112
 
112
- The :doc:`app` is "unsupported",
113
- in that it's not all that polished,
114
- and I don't have time to do major improvments.
115
- But, I am using it daily,
116
- and it will keep working until a better one exists.
117
-
118
- Long term, I'd like to:
119
-
120
- * re-design it from scratch to improve usability
121
- (see :issue:`318` for a wishlist)
122
- * switch to `htmx`_ instead of using a home-grown solution
123
- * spin it off into a separate package/project
113
+ The new :doc:`app` is under active development.
114
+ I am working on adding features
115
+ already implemented in the library
116
+ and the :ref:`legacy web app <legacy web app>`,
117
+ and possibly on a hosted version.
124
118
 
125
- **2025 update**:
126
- I've started working on a re-design based on `htmx`_ and `Bootstrap`_;
127
- some :ref:`screenshots <app screenshots>`.
128
- The new app will be available in parallel with the old one
129
- until it reaches feature parity.
119
+ Like with the library,
120
+ the goal is to keep it simple to use
121
+ and sustainable to maintain long-term;
122
+ the decision to use `Flask`_, `Bootstrap`_, and `htmx`_ is part of this
123
+ (if they were around for ~15 years,
124
+ they should be around for 15 more).
130
125
 
131
- .. _htmx: https://htmx.org/
126
+ .. _Flask: https://flask.palletsprojects.com/
132
127
  .. _Bootstrap: https://getbootstrap.com/
128
+ .. _htmx: https://htmx.org/
129
+
133
130
 
134
131
 
135
132
  .. _compat:
@@ -677,7 +674,10 @@ Why I want to postpone batch update/set methods:
677
674
  tl:dr: Performance is likely a non-issue with SQLite,
678
675
  convenience can be added on top as a plugin.
679
676
 
680
- (2025) Why it may be worth adding batch interfaces anyway (even if underneath the storage implementation doesn't actually batch) – it allows for future optimization: https://blog.glyph.im/2022/12/potato-programming.html
677
+ (2025 update) Why it may be worth adding batch interfaces anyway
678
+ (even if underneath the storage implementation doesn't actually batch)
679
+ – it allows for future optimization:
680
+ https://blog.glyph.im/2022/12/potato-programming.html
681
681
 
682
682
  See the 2.12 reader._app.ResourceTags class for an idea of how to
683
683
  represent a bunch of tags in a reserved-name-scheme-agnostic way
@@ -771,10 +771,3 @@ REST API
771
771
 
772
772
  Some early thoughts: :issue:`192#issuecomment-700773138`
773
773
  (closed with `wontfix`, for now).
774
-
775
-
776
- Web application
777
- ~~~~~~~~~~~~~~~
778
-
779
- .. toctree::
780
- dev-app
@@ -21,7 +21,7 @@ The Reader object
21
21
  Most *reader* functionality is available through a :class:`Reader` instance,
22
22
  which persists feed and entry state
23
23
  and provides operations on them;
24
- in :abbr:`MVC (model–view–controller)` parlance,
24
+ in :abbr:`MVC (model–view–controller)` terms,
25
25
  you would probably call it a fat model.
26
26
 
27
27
 
@@ -747,8 +747,8 @@ Plugins
747
747
  To use a built-in plugin, pass the plugin name to :func:`make_reader`::
748
748
 
749
749
  >>> reader = make_reader("db.sqlite", plugins=[
750
- ... "reader.enclosure_dedupe",
751
- ... "reader.entry_dedupe",
750
+ ... ".enclosure_dedupe",
751
+ ... ".entry_dedupe",
752
752
  ... ])
753
753
 
754
754
 
@@ -39,11 +39,19 @@ use the entry point as a :ref:`custom plugin <custom plugins>`::
39
39
 
40
40
 
41
41
  .. automodule:: reader._plugins.cli_status
42
- .. automodule:: reader._plugins.preview_feed_list
43
- .. automodule:: reader._plugins.enclosure_tags
44
42
  .. automodule:: reader._plugins.sqlite_releases
45
43
  .. automodule:: reader._plugins.timer
46
- .. automodule:: reader._plugins.share
44
+
45
+
46
+
47
+ Legacy web app plugins
48
+ ----------------------
49
+
50
+ Following are experimental plugins that work with the legacy web app:
51
+
52
+ .. automodule:: reader._plugins.legacy.preview_feed_list
53
+ .. automodule:: reader._plugins.legacy.enclosure_tags
54
+ .. automodule:: reader._plugins.legacy.share
47
55
 
48
56
 
49
57
 
@@ -92,30 +100,23 @@ You can still find the code on GitHub:
92
100
  Loading plugins from the CLI and the web application
93
101
  ----------------------------------------------------
94
102
 
95
- There is experimental support of plugins in the CLI and the web application.
96
-
97
- .. warning::
98
-
99
- The plugin system/hooks are not stable yet and may change without any notice.
100
-
101
-
102
- To load plugins, set the ``READER_PLUGIN`` environment variable to the plugin
103
+ To load plugins, set the ``READER_PLUGINS`` environment variable to the plugin
103
104
  entry point (e.g. ``package.module:entry_point``); multiple entry points should
104
- be separated by one space::
105
+ be separated by space::
105
106
 
106
- READER_PLUGIN='first.plugin:entry_point second_plugin:main' \
107
+ READER_PLUGINS='first.plugin:entry_point second_plugin' \
107
108
  python -m reader some-command
108
109
 
109
- For `built-in plugins`_, it is enough to use the plugin name (``reader.XYZ``).
110
+ For `built-in plugins`_, it is enough to use the plugin name (``.plugin``).
110
111
 
111
112
  .. note::
112
113
 
113
114
  :func:`make_reader` ignores the plugin environment variables.
114
115
 
115
116
 
116
- To load web application plugins, set the ``READER_APP_PLUGIN`` environment variable.
117
+ To load web application plugins, set the ``READER_WEB_PLUGINS`` environment variable.
117
118
  To load CLI plugins (that customize the CLI),
118
- set the ``READER_CLI_PLUGIN`` environment variable.
119
+ set the ``READER_CLI_PLUGINS`` environment variable.
119
120
 
120
121
 
121
122
 
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,26 @@
1
+ # The config file consists of default values for CLI options.
2
+
3
+ # Global options go in the [reader] section.
4
+
5
+ [reader]
6
+ url = "/path/to/db.sqlite"
7
+ feed_root = "/path/to/feeds"
8
+ # Options that can be passed multiple times take a list of values
9
+ # (unlike other settings, plugins are merged with commandline options).
10
+ plugins = [
11
+ "reader._plugins.sqlite_releases",
12
+ ".ua_fallback",
13
+ ]
14
+
15
+ # Subcommand defaults go in nested tables.
16
+
17
+ # add --update
18
+ [reader.add]
19
+ # Flags take a boolean value.
20
+ update = true
21
+
22
+ # update --workers 10 -vv
23
+ [reader.update]
24
+ workers = 10
25
+ # Flags that can be repeated take an integer.
26
+ verbose = 2