codex 1.7.3a2__py3-none-any.whl → 1.7.5__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 codex might be problematic. Click here for more details.

Files changed (632) hide show
  1. codex/asgi.py +2 -1
  2. codex/choices/__init__.py +1 -0
  3. codex/{choices.py → choices/admin.py} +47 -146
  4. codex/choices/browser.py +85 -0
  5. codex/{choices_to_json.py → choices/choices_to_json.py} +25 -19
  6. codex/choices/notifications.py +16 -0
  7. codex/choices/reader.py +33 -0
  8. codex/db.py +2 -2
  9. codex/exceptions.py +7 -8
  10. codex/librarian/bookmark/bookmarkd.py +8 -4
  11. codex/librarian/bookmark/update.py +84 -49
  12. codex/librarian/covers/create.py +10 -8
  13. codex/librarian/covers/path.py +6 -5
  14. codex/librarian/covers/purge.py +4 -4
  15. codex/librarian/importer/aggregate.py +2 -2
  16. codex/librarian/importer/cache.py +1 -4
  17. codex/librarian/importer/create_comics.py +2 -2
  18. codex/librarian/importer/create_covers.py +1 -1
  19. codex/librarian/importer/create_fks.py +4 -3
  20. codex/librarian/importer/deleted.py +3 -3
  21. codex/librarian/importer/extract.py +56 -37
  22. codex/librarian/importer/failed_imports.py +1 -1
  23. codex/librarian/importer/importer.py +8 -3
  24. codex/librarian/importer/importerd.py +3 -3
  25. codex/librarian/importer/link_comics.py +2 -1
  26. codex/librarian/importer/moved.py +2 -7
  27. codex/librarian/importer/query_fks.py +1 -4
  28. codex/librarian/importer/tasks.py +1 -1
  29. codex/librarian/janitor/integrity.py +27 -20
  30. codex/librarian/janitor/janitor.py +1 -1
  31. codex/librarian/janitor/latest_version.py +1 -1
  32. codex/librarian/janitor/update.py +5 -2
  33. codex/librarian/janitor/vacuum.py +1 -1
  34. codex/librarian/librariand.py +3 -2
  35. codex/librarian/notifier/notifierd.py +2 -1
  36. codex/librarian/notifier/tasks.py +17 -3
  37. codex/librarian/search/optimize.py +1 -1
  38. codex/librarian/search/remove.py +1 -1
  39. codex/librarian/search/update.py +4 -4
  40. codex/librarian/telemeter/stats.py +7 -6
  41. codex/librarian/telemeter/telemeter.py +0 -1
  42. codex/librarian/watchdog/db_snapshot.py +3 -3
  43. codex/librarian/watchdog/dir_snapshot_diff.py +3 -4
  44. codex/librarian/watchdog/emitter.py +4 -4
  45. codex/librarian/watchdog/event_batcherd.py +2 -1
  46. codex/librarian/watchdog/events.py +1 -2
  47. codex/librarian/watchdog/observers.py +15 -10
  48. codex/logger/logging.py +1 -1
  49. codex/memory.py +3 -2
  50. codex/migrations/0001_init.py +1 -2
  51. codex/migrations/0014_pdf_issue_suffix_remove_cover_image_sort_name.py +1 -2
  52. codex/migrations/0018_rename_userbookmark_bookmark.py +1 -2
  53. codex/migrations/0028_telemeter.py +1 -5
  54. codex/models/base.py +3 -1
  55. codex/models/bookmark.py +4 -7
  56. codex/models/comic.py +2 -2
  57. codex/models/functions.py +12 -5
  58. codex/models/groups.py +1 -1
  59. codex/models/library.py +1 -1
  60. codex/models/paths.py +4 -4
  61. codex/models/query.py +8 -4
  62. codex/models/util.py +1 -1
  63. codex/permissions.py +1 -1
  64. codex/run.py +1 -1
  65. codex/serializers/admin/libraries.py +1 -3
  66. codex/serializers/admin/stats.py +4 -4
  67. codex/serializers/admin/tasks.py +12 -2
  68. codex/serializers/auth.py +4 -2
  69. codex/serializers/browser/choices.py +87 -9
  70. codex/serializers/browser/filters.py +9 -37
  71. codex/serializers/browser/metadata.py +2 -1
  72. codex/serializers/browser/mixins.py +7 -3
  73. codex/serializers/browser/mtime.py +3 -5
  74. codex/serializers/browser/page.py +5 -4
  75. codex/serializers/browser/settings.py +8 -6
  76. codex/serializers/fields/__init__.py +37 -0
  77. codex/serializers/fields/auth.py +45 -0
  78. codex/serializers/fields/browser.py +85 -0
  79. codex/serializers/fields/group.py +13 -0
  80. codex/serializers/fields/reader.py +22 -0
  81. codex/serializers/fields/sanitized.py +13 -0
  82. codex/serializers/fields/session.py +16 -0
  83. codex/serializers/fields/stats.py +36 -0
  84. codex/serializers/fields/vuetify.py +62 -0
  85. codex/serializers/models/base.py +1 -1
  86. codex/serializers/models/comic.py +2 -2
  87. codex/serializers/models/groups.py +0 -2
  88. codex/serializers/models/named.py +1 -1
  89. codex/serializers/models/pycountry.py +1 -1
  90. codex/serializers/opds/authentication.py +4 -2
  91. codex/serializers/opds/urls.py +2 -1
  92. codex/serializers/opds/v1.py +4 -3
  93. codex/serializers/opds/v2/feed.py +2 -1
  94. codex/serializers/opds/v2/links.py +23 -21
  95. codex/serializers/opds/v2/metadata.py +4 -8
  96. codex/serializers/opds/v2/progression.py +5 -3
  97. codex/serializers/opds/v2/publication.py +16 -18
  98. codex/serializers/opds/v2/unused.py +15 -8
  99. codex/serializers/reader.py +16 -14
  100. codex/serializers/redirect.py +2 -1
  101. codex/serializers/route.py +6 -4
  102. codex/serializers/settings.py +5 -3
  103. codex/serializers/versions.py +2 -1
  104. codex/settings/settings.py +4 -3
  105. codex/signals/django_signals.py +1 -1
  106. codex/startup.py +2 -2
  107. codex/static_root/assets/{VCheckbox-FaT6MGfu.f6732060f734.js → VCheckbox-CWBDr4kF.6da5bf3a4d90.js} +1 -1
  108. codex/static_root/assets/VCheckbox-CWBDr4kF.6da5bf3a4d90.js.br +0 -0
  109. codex/static_root/assets/VCheckbox-CWBDr4kF.6da5bf3a4d90.js.gz +0 -0
  110. codex/static_root/assets/{VCheckbox-FaT6MGfu.js → VCheckbox-CWBDr4kF.js} +1 -1
  111. codex/static_root/assets/VCheckbox-CWBDr4kF.js.br +0 -0
  112. codex/static_root/assets/VCheckbox-CWBDr4kF.js.gz +0 -0
  113. codex/static_root/assets/{VCheckboxBtn-CZ_P-qUM.847452d574cf.js → VCheckboxBtn-COaoh3uF.fc880a386827.js} +1 -1
  114. codex/static_root/assets/VCheckboxBtn-COaoh3uF.fc880a386827.js.br +0 -0
  115. codex/static_root/assets/VCheckboxBtn-COaoh3uF.fc880a386827.js.gz +0 -0
  116. codex/static_root/assets/{VCheckboxBtn-CZ_P-qUM.js → VCheckboxBtn-COaoh3uF.js} +1 -1
  117. codex/static_root/assets/VCheckboxBtn-COaoh3uF.js.br +0 -0
  118. codex/static_root/assets/VCheckboxBtn-COaoh3uF.js.gz +0 -0
  119. codex/static_root/assets/{VCombobox-C8QLNlSl.6f431e19a453.js → VCombobox-DkOruNH0.f30f163ee632.js} +1 -1
  120. codex/static_root/assets/VCombobox-DkOruNH0.f30f163ee632.js.br +0 -0
  121. codex/static_root/assets/VCombobox-DkOruNH0.f30f163ee632.js.gz +0 -0
  122. codex/static_root/assets/{VCombobox-C8QLNlSl.js → VCombobox-DkOruNH0.js} +1 -1
  123. codex/static_root/assets/VCombobox-DkOruNH0.js.br +0 -0
  124. codex/static_root/assets/VCombobox-DkOruNH0.js.gz +0 -0
  125. codex/static_root/assets/{VDialog-RVLeW7je.c0c7eef71eec.js → VDialog-Dr7SuC2S.b6ec7df390f4.js} +1 -1
  126. codex/static_root/assets/VDialog-Dr7SuC2S.b6ec7df390f4.js.br +0 -0
  127. codex/static_root/assets/VDialog-Dr7SuC2S.b6ec7df390f4.js.gz +0 -0
  128. codex/static_root/assets/{VDialog-RVLeW7je.js → VDialog-Dr7SuC2S.js} +1 -1
  129. codex/static_root/assets/VDialog-Dr7SuC2S.js.br +0 -0
  130. codex/static_root/assets/VDialog-Dr7SuC2S.js.gz +0 -0
  131. codex/static_root/assets/{VDivider-D1Ot4vR2.9dbee744fb3c.js → VDivider-By4u2EsM.fd5ee9cce906.js} +1 -1
  132. codex/static_root/assets/VDivider-By4u2EsM.fd5ee9cce906.js.br +0 -0
  133. codex/static_root/assets/VDivider-By4u2EsM.fd5ee9cce906.js.gz +0 -0
  134. codex/static_root/assets/{VDivider-D1Ot4vR2.js → VDivider-By4u2EsM.js} +1 -1
  135. codex/static_root/assets/VDivider-By4u2EsM.js.br +0 -0
  136. codex/static_root/assets/VDivider-By4u2EsM.js.gz +0 -0
  137. codex/static_root/assets/{VExpansionPanels-DQilGHZk.43f06d0a45e0.js → VExpansionPanels-BhO9oj0a.e99bea455c78.js} +1 -1
  138. codex/static_root/assets/VExpansionPanels-BhO9oj0a.e99bea455c78.js.br +0 -0
  139. codex/static_root/assets/VExpansionPanels-BhO9oj0a.e99bea455c78.js.gz +0 -0
  140. codex/static_root/assets/{VExpansionPanels-DQilGHZk.js → VExpansionPanels-BhO9oj0a.js} +1 -1
  141. codex/static_root/assets/VExpansionPanels-BhO9oj0a.js.br +0 -0
  142. codex/static_root/assets/VExpansionPanels-BhO9oj0a.js.gz +0 -0
  143. codex/static_root/assets/VForm-XhA6T0Lc.70c9c6fcb9e3.js +1 -0
  144. codex/static_root/assets/VForm-XhA6T0Lc.70c9c6fcb9e3.js.br +0 -0
  145. codex/static_root/assets/VForm-XhA6T0Lc.70c9c6fcb9e3.js.gz +0 -0
  146. codex/static_root/assets/VForm-XhA6T0Lc.js +1 -0
  147. codex/static_root/assets/VForm-XhA6T0Lc.js.br +0 -0
  148. codex/static_root/assets/VForm-XhA6T0Lc.js.gz +0 -0
  149. codex/static_root/assets/{VRadioGroup-DoayJpcS.fe5e0e74ffee.js → VRadioGroup-C1WCG0rO.6ebc88e4f144.js} +1 -1
  150. codex/static_root/assets/VRadioGroup-C1WCG0rO.6ebc88e4f144.js.br +3 -0
  151. codex/static_root/assets/VRadioGroup-C1WCG0rO.6ebc88e4f144.js.gz +0 -0
  152. codex/static_root/assets/{VRadioGroup-DoayJpcS.js → VRadioGroup-C1WCG0rO.js} +1 -1
  153. codex/static_root/assets/VRadioGroup-C1WCG0rO.js.br +3 -0
  154. codex/static_root/assets/VRadioGroup-C1WCG0rO.js.gz +0 -0
  155. codex/static_root/assets/VSelect-Bbt1vrBg.ec45ee26818a.js +1 -0
  156. codex/static_root/assets/VSelect-Bbt1vrBg.ec45ee26818a.js.br +0 -0
  157. codex/static_root/assets/VSelect-Bbt1vrBg.ec45ee26818a.js.gz +0 -0
  158. codex/static_root/assets/VSelect-Bbt1vrBg.js +1 -0
  159. codex/static_root/assets/VSelect-Bbt1vrBg.js.br +0 -0
  160. codex/static_root/assets/VSelect-Bbt1vrBg.js.gz +0 -0
  161. codex/static_root/assets/{VSelectionControl-TaKCeZgb.ad6c96efe57c.js → VSelectionControl-BkZZAsWo.ba6eca944e2e.js} +1 -1
  162. codex/static_root/assets/VSelectionControl-BkZZAsWo.ba6eca944e2e.js.br +0 -0
  163. codex/static_root/assets/VSelectionControl-BkZZAsWo.ba6eca944e2e.js.gz +0 -0
  164. codex/static_root/assets/{VSelectionControl-TaKCeZgb.js → VSelectionControl-BkZZAsWo.js} +1 -1
  165. codex/static_root/assets/VSelectionControl-BkZZAsWo.js.br +0 -0
  166. codex/static_root/assets/VSelectionControl-BkZZAsWo.js.gz +0 -0
  167. codex/static_root/assets/{VTable-BfcOiEpa.77ef3973bb54.js → VTable-D7P2eIc2.5e94bf2a515b.js} +1 -1
  168. codex/static_root/assets/VTable-D7P2eIc2.5e94bf2a515b.js.br +0 -0
  169. codex/static_root/assets/VTable-D7P2eIc2.5e94bf2a515b.js.gz +0 -0
  170. codex/static_root/assets/{VTable-BfcOiEpa.js → VTable-D7P2eIc2.js} +1 -1
  171. codex/static_root/assets/VTable-D7P2eIc2.js.br +0 -0
  172. codex/static_root/assets/VTable-D7P2eIc2.js.gz +0 -0
  173. codex/static_root/assets/VWindowItem-Dm2szrjK.e77444188aa3.js +1 -0
  174. codex/static_root/assets/VWindowItem-Dm2szrjK.e77444188aa3.js.br +0 -0
  175. codex/static_root/assets/VWindowItem-Dm2szrjK.e77444188aa3.js.gz +0 -0
  176. codex/static_root/assets/VWindowItem-Dm2szrjK.js +1 -0
  177. codex/static_root/assets/VWindowItem-Dm2szrjK.js.br +0 -0
  178. codex/static_root/assets/VWindowItem-Dm2szrjK.js.gz +0 -0
  179. codex/static_root/assets/{admin-80eqCqtz.d6deb9edb8cb.js → admin-B4z2nA5P.da0c92500311.js} +1 -1
  180. codex/static_root/assets/admin-B4z2nA5P.da0c92500311.js.br +0 -0
  181. codex/static_root/assets/admin-B4z2nA5P.da0c92500311.js.gz +0 -0
  182. codex/static_root/assets/{admin-80eqCqtz.js → admin-B4z2nA5P.js} +1 -1
  183. codex/static_root/assets/admin-B4z2nA5P.js.br +0 -0
  184. codex/static_root/assets/admin-B4z2nA5P.js.gz +0 -0
  185. codex/static_root/assets/admin-BhW3PNO0.e444048e548d.js +1 -0
  186. codex/static_root/assets/admin-BhW3PNO0.e444048e548d.js.br +0 -0
  187. codex/static_root/assets/admin-BhW3PNO0.e444048e548d.js.gz +0 -0
  188. codex/static_root/assets/admin-BhW3PNO0.js +1 -0
  189. codex/static_root/assets/admin-BhW3PNO0.js.br +0 -0
  190. codex/static_root/assets/admin-BhW3PNO0.js.gz +0 -0
  191. codex/static_root/assets/{admin-menu-_aAGknKO.0c08c9bd2e7d.js → admin-menu-CL7S-xqR.92b6d84c4b70.js} +1 -1
  192. codex/static_root/assets/admin-menu-CL7S-xqR.92b6d84c4b70.js.br +0 -0
  193. codex/static_root/assets/admin-menu-CL7S-xqR.92b6d84c4b70.js.gz +0 -0
  194. codex/static_root/assets/{admin-menu-_aAGknKO.js → admin-menu-CL7S-xqR.js} +1 -1
  195. codex/static_root/assets/admin-menu-CL7S-xqR.js.br +0 -0
  196. codex/static_root/assets/admin-menu-CL7S-xqR.js.gz +0 -0
  197. codex/static_root/assets/{admin-settings-button-progress-BqRFyhjf.2bb1194b21e2.js → admin-settings-button-progress-BgBgdELw.52d052e38bc1.js} +1 -1
  198. codex/static_root/assets/admin-settings-button-progress-BgBgdELw.52d052e38bc1.js.br +0 -0
  199. codex/static_root/assets/admin-settings-button-progress-BgBgdELw.52d052e38bc1.js.gz +0 -0
  200. codex/static_root/assets/{admin-settings-button-progress-BqRFyhjf.js → admin-settings-button-progress-BgBgdELw.js} +1 -1
  201. codex/static_root/assets/admin-settings-button-progress-BgBgdELw.js.br +0 -0
  202. codex/static_root/assets/admin-settings-button-progress-BgBgdELw.js.gz +0 -0
  203. codex/static_root/assets/browser-Bi5ov5k8.a4af87c2a667.js +1 -0
  204. codex/static_root/assets/browser-Bi5ov5k8.a4af87c2a667.js.br +0 -0
  205. codex/static_root/assets/browser-Bi5ov5k8.a4af87c2a667.js.gz +0 -0
  206. codex/static_root/assets/browser-Bi5ov5k8.js +1 -0
  207. codex/static_root/assets/browser-Bi5ov5k8.js.br +0 -0
  208. codex/static_root/assets/browser-Bi5ov5k8.js.gz +0 -0
  209. codex/static_root/assets/{browser-chTZ1CM4.521193ab0710.css → browser-DNzQvgkY.aea8b7d7ca40.css} +1 -1
  210. codex/static_root/assets/browser-DNzQvgkY.aea8b7d7ca40.css.br +0 -0
  211. codex/static_root/assets/browser-DNzQvgkY.aea8b7d7ca40.css.gz +0 -0
  212. codex/static_root/assets/{browser-chTZ1CM4.css → browser-DNzQvgkY.css} +1 -1
  213. codex/static_root/assets/browser-DNzQvgkY.css.br +0 -0
  214. codex/static_root/assets/browser-DNzQvgkY.css.gz +0 -0
  215. codex/static_root/assets/{change-password-dialog-1ZVP_Q2w.ae0d9e5bd42b.js → change-password-dialog-BKar2Bhb.3dbc2feb3c5a.js} +1 -1
  216. codex/static_root/assets/change-password-dialog-BKar2Bhb.3dbc2feb3c5a.js.br +0 -0
  217. codex/static_root/assets/change-password-dialog-BKar2Bhb.3dbc2feb3c5a.js.gz +0 -0
  218. codex/static_root/assets/{change-password-dialog-1ZVP_Q2w.js → change-password-dialog-BKar2Bhb.js} +1 -1
  219. codex/static_root/assets/change-password-dialog-BKar2Bhb.js.br +0 -0
  220. codex/static_root/assets/change-password-dialog-BKar2Bhb.js.gz +0 -0
  221. codex/static_root/assets/{confirm-dialog-DqCey9Iq.e315d7f8f752.js → confirm-dialog-BoBL4OoS.abef9614fea9.js} +1 -1
  222. codex/static_root/assets/confirm-dialog-BoBL4OoS.abef9614fea9.js.br +0 -0
  223. codex/static_root/assets/confirm-dialog-BoBL4OoS.abef9614fea9.js.gz +0 -0
  224. codex/static_root/assets/{confirm-dialog-DqCey9Iq.js → confirm-dialog-BoBL4OoS.js} +1 -1
  225. codex/static_root/assets/confirm-dialog-BoBL4OoS.js.br +0 -0
  226. codex/static_root/assets/confirm-dialog-BoBL4OoS.js.gz +0 -0
  227. codex/static_root/assets/{datetime-column-CBA8bYeO.17a31f189d66.js → datetime-column-BsiYRUKO.cadd764c06f4.js} +1 -1
  228. codex/static_root/assets/datetime-column-BsiYRUKO.cadd764c06f4.js.br +0 -0
  229. codex/static_root/assets/datetime-column-BsiYRUKO.cadd764c06f4.js.gz +0 -0
  230. codex/static_root/assets/{datetime-column-CBA8bYeO.js → datetime-column-BsiYRUKO.js} +1 -1
  231. codex/static_root/assets/datetime-column-BsiYRUKO.js.br +0 -0
  232. codex/static_root/assets/datetime-column-BsiYRUKO.js.gz +0 -0
  233. codex/static_root/assets/{filter-mnO3lLPo.659442401b16.js → filter-HnY0knto.07f807227dcc.js} +1 -1
  234. codex/static_root/assets/filter-HnY0knto.07f807227dcc.js.br +0 -0
  235. codex/static_root/assets/filter-HnY0knto.07f807227dcc.js.gz +0 -0
  236. codex/static_root/assets/{filter-mnO3lLPo.js → filter-HnY0knto.js} +1 -1
  237. codex/static_root/assets/filter-HnY0knto.js.br +0 -0
  238. codex/static_root/assets/filter-HnY0knto.js.gz +0 -0
  239. codex/static_root/assets/{flag-tab-Bc677pNb.1b8a2f7c0dc3.js → flag-tab-CcS5pve2.a1df5d92e222.js} +1 -1
  240. codex/static_root/assets/flag-tab-CcS5pve2.a1df5d92e222.js.br +0 -0
  241. codex/static_root/assets/flag-tab-CcS5pve2.a1df5d92e222.js.gz +0 -0
  242. codex/static_root/assets/{flag-tab-Bc677pNb.js → flag-tab-CcS5pve2.js} +1 -1
  243. codex/static_root/assets/flag-tab-CcS5pve2.js.br +0 -0
  244. codex/static_root/assets/flag-tab-CcS5pve2.js.gz +0 -0
  245. codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css +1 -0
  246. codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css.br +0 -0
  247. codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css.gz +0 -0
  248. codex/static_root/assets/flag-tab-D2MYXCHk.css +1 -0
  249. codex/static_root/assets/flag-tab-D2MYXCHk.css.br +0 -0
  250. codex/static_root/assets/flag-tab-D2MYXCHk.css.gz +0 -0
  251. codex/static_root/assets/{forwardRefs-DPRKg5wq.6f09e9d22fa6.js → forwardRefs-i80xmxX3.db393aeef392.js} +1 -1
  252. codex/static_root/assets/forwardRefs-i80xmxX3.db393aeef392.js.br +0 -0
  253. codex/static_root/assets/forwardRefs-i80xmxX3.db393aeef392.js.gz +0 -0
  254. codex/static_root/assets/{forwardRefs-DPRKg5wq.js → forwardRefs-i80xmxX3.js} +1 -1
  255. codex/static_root/assets/forwardRefs-i80xmxX3.js.br +0 -0
  256. codex/static_root/assets/forwardRefs-i80xmxX3.js.gz +0 -0
  257. codex/static_root/assets/group-tab-SY0gxmHW.f72e944c0ff1.js +1 -0
  258. codex/static_root/assets/group-tab-SY0gxmHW.f72e944c0ff1.js.br +0 -0
  259. codex/static_root/assets/group-tab-SY0gxmHW.f72e944c0ff1.js.gz +0 -0
  260. codex/static_root/assets/group-tab-SY0gxmHW.js +1 -0
  261. codex/static_root/assets/group-tab-SY0gxmHW.js.br +0 -0
  262. codex/static_root/assets/group-tab-SY0gxmHW.js.gz +0 -0
  263. codex/static_root/assets/http-error-EE8gtq5A.07e291d9d955.js +1 -0
  264. codex/static_root/assets/http-error-EE8gtq5A.07e291d9d955.js.br +0 -0
  265. codex/static_root/assets/http-error-EE8gtq5A.07e291d9d955.js.gz +0 -0
  266. codex/static_root/assets/http-error-EE8gtq5A.js +1 -0
  267. codex/static_root/assets/http-error-EE8gtq5A.js.br +0 -0
  268. codex/static_root/assets/http-error-EE8gtq5A.js.gz +0 -0
  269. codex/static_root/assets/{index-9nBCksDQ.4561d2608773.js → index-gVdawuuE.a940fadbac00.js} +1 -1
  270. codex/static_root/assets/index-gVdawuuE.a940fadbac00.js.br +0 -0
  271. codex/static_root/assets/index-gVdawuuE.a940fadbac00.js.gz +0 -0
  272. codex/static_root/assets/{index-9nBCksDQ.js → index-gVdawuuE.js} +1 -1
  273. codex/static_root/assets/index-gVdawuuE.js.br +0 -0
  274. codex/static_root/assets/index-gVdawuuE.js.gz +0 -0
  275. codex/static_root/assets/library-tab-BkDIAvyS.4b4c606b77d6.js +1 -0
  276. codex/static_root/assets/library-tab-BkDIAvyS.4b4c606b77d6.js.br +0 -0
  277. codex/static_root/assets/library-tab-BkDIAvyS.4b4c606b77d6.js.gz +0 -0
  278. codex/static_root/assets/library-tab-BkDIAvyS.js +1 -0
  279. codex/static_root/assets/library-tab-BkDIAvyS.js.br +0 -0
  280. codex/static_root/assets/library-tab-BkDIAvyS.js.gz +0 -0
  281. codex/static_root/assets/main-B5uflU6E.77f3fcd6873f.js +35 -0
  282. codex/static_root/assets/main-B5uflU6E.77f3fcd6873f.js.br +0 -0
  283. codex/static_root/assets/main-B5uflU6E.77f3fcd6873f.js.gz +0 -0
  284. codex/static_root/assets/main-B5uflU6E.js +35 -0
  285. codex/static_root/assets/main-B5uflU6E.js.br +0 -0
  286. codex/static_root/assets/main-B5uflU6E.js.gz +0 -0
  287. codex/static_root/assets/pager-full-pdf-wuQbceLs.111d9b9d4133.js +1 -0
  288. codex/static_root/assets/pager-full-pdf-wuQbceLs.111d9b9d4133.js.br +0 -0
  289. codex/static_root/assets/pager-full-pdf-wuQbceLs.111d9b9d4133.js.gz +0 -0
  290. codex/static_root/assets/pager-full-pdf-wuQbceLs.js +1 -0
  291. codex/static_root/assets/pager-full-pdf-wuQbceLs.js.br +0 -0
  292. codex/static_root/assets/pager-full-pdf-wuQbceLs.js.gz +0 -0
  293. codex/static_root/assets/{pagination-toolbar-Dx5JwWG-.ba0e8b645dfa.js → pagination-toolbar-D3JQmDiD.8513a4db85f0.js} +1 -1
  294. codex/static_root/assets/pagination-toolbar-D3JQmDiD.8513a4db85f0.js.br +0 -0
  295. codex/static_root/assets/pagination-toolbar-D3JQmDiD.8513a4db85f0.js.gz +0 -0
  296. codex/static_root/assets/{pagination-toolbar-Dx5JwWG-.js → pagination-toolbar-D3JQmDiD.js} +1 -1
  297. codex/static_root/assets/pagination-toolbar-D3JQmDiD.js.br +0 -0
  298. codex/static_root/assets/pagination-toolbar-D3JQmDiD.js.gz +0 -0
  299. codex/static_root/assets/{pdf-doc-6ZE_HmLT.10d1e16abc78.js → pdf-doc-DRBtl9_2.225a6d89e842.js} +1 -1
  300. codex/static_root/assets/pdf-doc-DRBtl9_2.225a6d89e842.js.br +0 -0
  301. codex/static_root/assets/pdf-doc-DRBtl9_2.225a6d89e842.js.gz +0 -0
  302. codex/static_root/assets/{pdf-doc-6ZE_HmLT.js → pdf-doc-DRBtl9_2.js} +1 -1
  303. codex/static_root/assets/pdf-doc-DRBtl9_2.js.br +0 -0
  304. codex/static_root/assets/pdf-doc-DRBtl9_2.js.gz +0 -0
  305. codex/static_root/assets/reader-DycvjN42.3e2b4f43235e.js +2 -0
  306. codex/static_root/assets/reader-DycvjN42.3e2b4f43235e.js.br +0 -0
  307. codex/static_root/assets/reader-DycvjN42.3e2b4f43235e.js.gz +0 -0
  308. codex/static_root/assets/reader-DycvjN42.js +2 -0
  309. codex/static_root/assets/reader-DycvjN42.js.br +0 -0
  310. codex/static_root/assets/reader-DycvjN42.js.gz +0 -0
  311. codex/static_root/assets/{relation-chips-C96hi5jm.js → relation-chips-CeHIEjvZ.04d302f4fa89.js} +1 -1
  312. codex/static_root/assets/relation-chips-CeHIEjvZ.04d302f4fa89.js.br +0 -0
  313. codex/static_root/assets/relation-chips-CeHIEjvZ.04d302f4fa89.js.gz +0 -0
  314. codex/static_root/assets/{relation-chips-C96hi5jm.9f07c9eb533a.js → relation-chips-CeHIEjvZ.js} +1 -1
  315. codex/static_root/assets/relation-chips-CeHIEjvZ.js.br +0 -0
  316. codex/static_root/assets/relation-chips-CeHIEjvZ.js.gz +0 -0
  317. codex/static_root/assets/settings-drawer-DY8o-jF3.48dfaafaa00e.js +2 -0
  318. codex/static_root/assets/settings-drawer-DY8o-jF3.48dfaafaa00e.js.br +0 -0
  319. codex/static_root/assets/settings-drawer-DY8o-jF3.48dfaafaa00e.js.gz +0 -0
  320. codex/static_root/assets/settings-drawer-DY8o-jF3.js +2 -0
  321. codex/static_root/assets/settings-drawer-DY8o-jF3.js.br +0 -0
  322. codex/static_root/assets/settings-drawer-DY8o-jF3.js.gz +0 -0
  323. codex/static_root/assets/ssrBoot-DRKt_yWP.3b5868abdd61.js +1 -0
  324. codex/static_root/assets/ssrBoot-DRKt_yWP.3b5868abdd61.js.br +0 -0
  325. codex/static_root/assets/ssrBoot-DRKt_yWP.3b5868abdd61.js.gz +0 -0
  326. codex/static_root/assets/ssrBoot-DRKt_yWP.js +1 -0
  327. codex/static_root/assets/ssrBoot-DRKt_yWP.js.br +0 -0
  328. codex/static_root/assets/ssrBoot-DRKt_yWP.js.gz +0 -0
  329. codex/static_root/assets/{stats-tab-CkT2ZGUQ.b704fa46dc88.js → stats-tab-C1XYGBKj.812896e1d09c.js} +1 -1
  330. codex/static_root/assets/stats-tab-C1XYGBKj.812896e1d09c.js.br +0 -0
  331. codex/static_root/assets/stats-tab-C1XYGBKj.812896e1d09c.js.gz +0 -0
  332. codex/static_root/assets/{stats-tab-CkT2ZGUQ.js → stats-tab-C1XYGBKj.js} +1 -1
  333. codex/static_root/assets/stats-tab-C1XYGBKj.js.br +0 -0
  334. codex/static_root/assets/stats-tab-C1XYGBKj.js.gz +0 -0
  335. codex/static_root/assets/task-tab-CW4DQ3KN.81812f9208e5.css +1 -0
  336. codex/static_root/assets/{task-tab-DfdUY9Rc.478e74041f80.css.br → task-tab-CW4DQ3KN.81812f9208e5.css.br} +1 -1
  337. codex/static_root/assets/task-tab-CW4DQ3KN.81812f9208e5.css.gz +0 -0
  338. codex/static_root/assets/task-tab-CW4DQ3KN.css +1 -0
  339. codex/static_root/assets/{task-tab-DfdUY9Rc.css.br → task-tab-CW4DQ3KN.css.br} +1 -1
  340. codex/static_root/assets/task-tab-CW4DQ3KN.css.gz +0 -0
  341. codex/static_root/assets/task-tab-lFRZ0NMd.6b90f40a1a9f.js +1 -0
  342. codex/static_root/assets/task-tab-lFRZ0NMd.6b90f40a1a9f.js.br +0 -0
  343. codex/static_root/assets/task-tab-lFRZ0NMd.6b90f40a1a9f.js.gz +0 -0
  344. codex/static_root/assets/task-tab-lFRZ0NMd.js +1 -0
  345. codex/static_root/assets/task-tab-lFRZ0NMd.js.br +0 -0
  346. codex/static_root/assets/task-tab-lFRZ0NMd.js.gz +0 -0
  347. codex/static_root/assets/unauthorized-Dld9cV8d.4e675fd9991c.js +1 -0
  348. codex/static_root/assets/unauthorized-Dld9cV8d.4e675fd9991c.js.br +0 -0
  349. codex/static_root/assets/unauthorized-Dld9cV8d.4e675fd9991c.js.gz +0 -0
  350. codex/static_root/assets/unauthorized-Dld9cV8d.js +1 -0
  351. codex/static_root/assets/unauthorized-Dld9cV8d.js.br +0 -0
  352. codex/static_root/assets/unauthorized-Dld9cV8d.js.gz +0 -0
  353. codex/static_root/assets/user-tab-CN9nBOMS.f88d8b1c8afe.js +1 -0
  354. codex/static_root/assets/user-tab-CN9nBOMS.f88d8b1c8afe.js.br +0 -0
  355. codex/static_root/assets/user-tab-CN9nBOMS.f88d8b1c8afe.js.gz +0 -0
  356. codex/static_root/assets/user-tab-CN9nBOMS.js +1 -0
  357. codex/static_root/assets/user-tab-CN9nBOMS.js.br +0 -0
  358. codex/static_root/assets/user-tab-CN9nBOMS.js.gz +0 -0
  359. codex/static_root/{manifest.225989a17f49.json → manifest.66d7229aa07a.json} +297 -277
  360. codex/static_root/manifest.66d7229aa07a.json.br +0 -0
  361. codex/static_root/manifest.66d7229aa07a.json.gz +0 -0
  362. codex/static_root/manifest.json +297 -277
  363. codex/static_root/manifest.json.br +0 -0
  364. codex/static_root/manifest.json.gz +0 -0
  365. codex/static_root/staticfiles.json +1 -1
  366. codex/status_controller.py +10 -13
  367. codex/urls/root.py +4 -3
  368. codex/views/admin/api_key.py +1 -4
  369. codex/views/admin/flag.py +2 -2
  370. codex/views/admin/group.py +2 -2
  371. codex/views/admin/library.py +4 -4
  372. codex/views/admin/stats.py +10 -10
  373. codex/views/admin/tasks.py +32 -13
  374. codex/views/admin/user.py +36 -10
  375. codex/views/auth.py +3 -8
  376. codex/views/bookmark.py +3 -3
  377. codex/views/browser/annotate/card.py +2 -2
  378. codex/views/browser/annotate/order.py +6 -7
  379. codex/views/browser/bookmark.py +3 -1
  380. codex/views/browser/breadcrumbs.py +6 -5
  381. codex/views/browser/browser.py +2 -2
  382. codex/views/browser/choices.py +7 -8
  383. codex/views/browser/cover.py +6 -3
  384. codex/views/browser/download.py +2 -1
  385. codex/views/browser/filters/bookmark.py +1 -1
  386. codex/views/browser/filters/field.py +1 -1
  387. codex/views/browser/filters/filter.py +6 -8
  388. codex/views/browser/filters/group.py +8 -8
  389. codex/views/browser/filters/search/field/expression.py +1 -2
  390. codex/views/browser/filters/search/field/optimize.py +1 -1
  391. codex/views/browser/filters/search/field/parse.py +2 -2
  392. codex/views/browser/filters/search/parse.py +4 -19
  393. codex/views/browser/group_mtime.py +1 -1
  394. codex/views/browser/metadata/copy_intersections.py +1 -1
  395. codex/views/browser/metadata/metadata.py +1 -1
  396. codex/views/browser/mtime.py +1 -1
  397. codex/views/browser/order_by.py +3 -5
  398. codex/views/browser/params.py +1 -1
  399. codex/views/browser/settings.py +1 -1
  400. codex/views/browser/validate.py +9 -6
  401. codex/views/const.py +0 -3
  402. codex/views/frontend.py +1 -1
  403. codex/views/mixins.py +3 -2
  404. codex/views/opds/authentication_v1.py +1 -1
  405. codex/views/opds/const.py +4 -4
  406. codex/views/opds/urls.py +1 -1
  407. codex/views/opds/util.py +4 -4
  408. codex/views/opds/v1/entry/entry.py +4 -2
  409. codex/views/opds/v1/entry/links.py +4 -5
  410. codex/views/opds/v1/facets.py +8 -4
  411. codex/views/opds/v1/feed.py +5 -5
  412. codex/views/opds/v1/links.py +11 -6
  413. codex/views/opds/v2/const.py +5 -2
  414. codex/views/opds/v2/feed.py +3 -3
  415. codex/views/opds/v2/links.py +18 -11
  416. codex/views/opds/v2/progression.py +8 -9
  417. codex/views/opds/v2/publications.py +10 -20
  418. codex/views/public.py +2 -2
  419. codex/views/reader/books.py +3 -2
  420. codex/views/reader/page.py +3 -3
  421. codex/views/reader/params.py +2 -2
  422. codex/views/reader/reader.py +6 -6
  423. codex/views/reader/settings.py +1 -1
  424. codex/views/session.py +10 -3
  425. codex/views/settings.py +2 -2
  426. codex/views/timezone.py +2 -2
  427. codex/views/util.py +10 -9
  428. codex/views/version.py +1 -1
  429. {codex-1.7.3a2.dist-info → codex-1.7.5.dist-info}/METADATA +3 -1
  430. {codex-1.7.3a2.dist-info → codex-1.7.5.dist-info}/RECORD +433 -415
  431. {codex-1.7.3a2.dist-info → codex-1.7.5.dist-info}/WHEEL +1 -1
  432. codex/serializers/fields.py +0 -183
  433. codex/static_root/assets/VCheckbox-FaT6MGfu.f6732060f734.js.br +0 -0
  434. codex/static_root/assets/VCheckbox-FaT6MGfu.f6732060f734.js.gz +0 -0
  435. codex/static_root/assets/VCheckbox-FaT6MGfu.js.br +0 -0
  436. codex/static_root/assets/VCheckbox-FaT6MGfu.js.gz +0 -0
  437. codex/static_root/assets/VCheckboxBtn-CZ_P-qUM.847452d574cf.js.br +0 -0
  438. codex/static_root/assets/VCheckboxBtn-CZ_P-qUM.847452d574cf.js.gz +0 -0
  439. codex/static_root/assets/VCheckboxBtn-CZ_P-qUM.js.br +0 -0
  440. codex/static_root/assets/VCheckboxBtn-CZ_P-qUM.js.gz +0 -0
  441. codex/static_root/assets/VCombobox-C8QLNlSl.6f431e19a453.js.br +0 -0
  442. codex/static_root/assets/VCombobox-C8QLNlSl.6f431e19a453.js.gz +0 -0
  443. codex/static_root/assets/VCombobox-C8QLNlSl.js.br +0 -0
  444. codex/static_root/assets/VCombobox-C8QLNlSl.js.gz +0 -0
  445. codex/static_root/assets/VDialog-RVLeW7je.c0c7eef71eec.js.br +0 -0
  446. codex/static_root/assets/VDialog-RVLeW7je.c0c7eef71eec.js.gz +0 -0
  447. codex/static_root/assets/VDialog-RVLeW7je.js.br +0 -0
  448. codex/static_root/assets/VDialog-RVLeW7je.js.gz +0 -0
  449. codex/static_root/assets/VDivider-D1Ot4vR2.9dbee744fb3c.js.br +0 -0
  450. codex/static_root/assets/VDivider-D1Ot4vR2.9dbee744fb3c.js.gz +0 -0
  451. codex/static_root/assets/VDivider-D1Ot4vR2.js.br +0 -0
  452. codex/static_root/assets/VDivider-D1Ot4vR2.js.gz +0 -0
  453. codex/static_root/assets/VExpansionPanels-DQilGHZk.43f06d0a45e0.js.br +0 -0
  454. codex/static_root/assets/VExpansionPanels-DQilGHZk.43f06d0a45e0.js.gz +0 -0
  455. codex/static_root/assets/VExpansionPanels-DQilGHZk.js.br +0 -0
  456. codex/static_root/assets/VExpansionPanels-DQilGHZk.js.gz +0 -0
  457. codex/static_root/assets/VForm-DNmY-qFJ.81f3a5ff7ec3.js +0 -1
  458. codex/static_root/assets/VForm-DNmY-qFJ.81f3a5ff7ec3.js.br +0 -0
  459. codex/static_root/assets/VForm-DNmY-qFJ.81f3a5ff7ec3.js.gz +0 -0
  460. codex/static_root/assets/VForm-DNmY-qFJ.js +0 -1
  461. codex/static_root/assets/VForm-DNmY-qFJ.js.br +0 -0
  462. codex/static_root/assets/VForm-DNmY-qFJ.js.gz +0 -0
  463. codex/static_root/assets/VRadioGroup-DoayJpcS.fe5e0e74ffee.js.br +0 -0
  464. codex/static_root/assets/VRadioGroup-DoayJpcS.fe5e0e74ffee.js.gz +0 -0
  465. codex/static_root/assets/VRadioGroup-DoayJpcS.js.br +0 -0
  466. codex/static_root/assets/VRadioGroup-DoayJpcS.js.gz +0 -0
  467. codex/static_root/assets/VSelect-BSLmHX_P.9ab865ec0fad.js +0 -1
  468. codex/static_root/assets/VSelect-BSLmHX_P.9ab865ec0fad.js.br +0 -0
  469. codex/static_root/assets/VSelect-BSLmHX_P.9ab865ec0fad.js.gz +0 -0
  470. codex/static_root/assets/VSelect-BSLmHX_P.js +0 -1
  471. codex/static_root/assets/VSelect-BSLmHX_P.js.br +0 -0
  472. codex/static_root/assets/VSelect-BSLmHX_P.js.gz +0 -0
  473. codex/static_root/assets/VSelectionControl-TaKCeZgb.ad6c96efe57c.js.br +0 -0
  474. codex/static_root/assets/VSelectionControl-TaKCeZgb.ad6c96efe57c.js.gz +0 -0
  475. codex/static_root/assets/VSelectionControl-TaKCeZgb.js.br +0 -0
  476. codex/static_root/assets/VSelectionControl-TaKCeZgb.js.gz +0 -0
  477. codex/static_root/assets/VTable-BfcOiEpa.77ef3973bb54.js.br +0 -0
  478. codex/static_root/assets/VTable-BfcOiEpa.77ef3973bb54.js.gz +0 -0
  479. codex/static_root/assets/VTable-BfcOiEpa.js.br +0 -0
  480. codex/static_root/assets/VTable-BfcOiEpa.js.gz +0 -0
  481. codex/static_root/assets/VWindowItem-D8lWcbQY.e4c75ad78718.js +0 -1
  482. codex/static_root/assets/VWindowItem-D8lWcbQY.e4c75ad78718.js.br +0 -0
  483. codex/static_root/assets/VWindowItem-D8lWcbQY.e4c75ad78718.js.gz +0 -0
  484. codex/static_root/assets/VWindowItem-D8lWcbQY.js +0 -1
  485. codex/static_root/assets/VWindowItem-D8lWcbQY.js.br +0 -0
  486. codex/static_root/assets/VWindowItem-D8lWcbQY.js.gz +0 -0
  487. codex/static_root/assets/admin-80eqCqtz.d6deb9edb8cb.js.br +0 -0
  488. codex/static_root/assets/admin-80eqCqtz.d6deb9edb8cb.js.gz +0 -0
  489. codex/static_root/assets/admin-80eqCqtz.js.br +0 -0
  490. codex/static_root/assets/admin-80eqCqtz.js.gz +0 -0
  491. codex/static_root/assets/admin-CBLHOrM9.8c3c2268bc96.js +0 -1
  492. codex/static_root/assets/admin-CBLHOrM9.8c3c2268bc96.js.br +0 -0
  493. codex/static_root/assets/admin-CBLHOrM9.8c3c2268bc96.js.gz +0 -0
  494. codex/static_root/assets/admin-CBLHOrM9.js +0 -1
  495. codex/static_root/assets/admin-CBLHOrM9.js.br +0 -0
  496. codex/static_root/assets/admin-CBLHOrM9.js.gz +0 -0
  497. codex/static_root/assets/admin-menu-_aAGknKO.0c08c9bd2e7d.js.br +0 -0
  498. codex/static_root/assets/admin-menu-_aAGknKO.0c08c9bd2e7d.js.gz +0 -0
  499. codex/static_root/assets/admin-menu-_aAGknKO.js.br +0 -0
  500. codex/static_root/assets/admin-menu-_aAGknKO.js.gz +0 -0
  501. codex/static_root/assets/admin-settings-button-progress-BqRFyhjf.2bb1194b21e2.js.br +0 -0
  502. codex/static_root/assets/admin-settings-button-progress-BqRFyhjf.2bb1194b21e2.js.gz +0 -0
  503. codex/static_root/assets/admin-settings-button-progress-BqRFyhjf.js.br +0 -0
  504. codex/static_root/assets/admin-settings-button-progress-BqRFyhjf.js.gz +0 -0
  505. codex/static_root/assets/browser-DAprXYuP.8bb92965dd9d.js +0 -1
  506. codex/static_root/assets/browser-DAprXYuP.8bb92965dd9d.js.br +0 -0
  507. codex/static_root/assets/browser-DAprXYuP.8bb92965dd9d.js.gz +0 -0
  508. codex/static_root/assets/browser-DAprXYuP.js +0 -1
  509. codex/static_root/assets/browser-DAprXYuP.js.br +0 -0
  510. codex/static_root/assets/browser-DAprXYuP.js.gz +0 -0
  511. codex/static_root/assets/browser-chTZ1CM4.521193ab0710.css.br +0 -0
  512. codex/static_root/assets/browser-chTZ1CM4.521193ab0710.css.gz +0 -0
  513. codex/static_root/assets/browser-chTZ1CM4.css.br +0 -0
  514. codex/static_root/assets/browser-chTZ1CM4.css.gz +0 -0
  515. codex/static_root/assets/change-password-dialog-1ZVP_Q2w.ae0d9e5bd42b.js.br +0 -0
  516. codex/static_root/assets/change-password-dialog-1ZVP_Q2w.ae0d9e5bd42b.js.gz +0 -0
  517. codex/static_root/assets/change-password-dialog-1ZVP_Q2w.js.br +0 -0
  518. codex/static_root/assets/change-password-dialog-1ZVP_Q2w.js.gz +0 -0
  519. codex/static_root/assets/confirm-dialog-DqCey9Iq.e315d7f8f752.js.br +0 -0
  520. codex/static_root/assets/confirm-dialog-DqCey9Iq.e315d7f8f752.js.gz +0 -0
  521. codex/static_root/assets/confirm-dialog-DqCey9Iq.js.br +0 -0
  522. codex/static_root/assets/confirm-dialog-DqCey9Iq.js.gz +0 -0
  523. codex/static_root/assets/datetime-column-CBA8bYeO.17a31f189d66.js.br +0 -0
  524. codex/static_root/assets/datetime-column-CBA8bYeO.17a31f189d66.js.gz +0 -0
  525. codex/static_root/assets/datetime-column-CBA8bYeO.js.br +0 -0
  526. codex/static_root/assets/datetime-column-CBA8bYeO.js.gz +0 -0
  527. codex/static_root/assets/filter-mnO3lLPo.659442401b16.js.br +0 -0
  528. codex/static_root/assets/filter-mnO3lLPo.659442401b16.js.gz +0 -0
  529. codex/static_root/assets/filter-mnO3lLPo.js.br +0 -0
  530. codex/static_root/assets/filter-mnO3lLPo.js.gz +0 -0
  531. codex/static_root/assets/flag-tab-Bc677pNb.1b8a2f7c0dc3.js.br +0 -0
  532. codex/static_root/assets/flag-tab-Bc677pNb.1b8a2f7c0dc3.js.gz +0 -0
  533. codex/static_root/assets/flag-tab-Bc677pNb.js.br +0 -0
  534. codex/static_root/assets/flag-tab-Bc677pNb.js.gz +0 -0
  535. codex/static_root/assets/flag-tab-glFvEgEl.be8eed14384e.css +0 -1
  536. codex/static_root/assets/flag-tab-glFvEgEl.be8eed14384e.css.br +0 -0
  537. codex/static_root/assets/flag-tab-glFvEgEl.be8eed14384e.css.gz +0 -0
  538. codex/static_root/assets/flag-tab-glFvEgEl.css +0 -1
  539. codex/static_root/assets/flag-tab-glFvEgEl.css.br +0 -0
  540. codex/static_root/assets/flag-tab-glFvEgEl.css.gz +0 -0
  541. codex/static_root/assets/forwardRefs-DPRKg5wq.6f09e9d22fa6.js.br +0 -0
  542. codex/static_root/assets/forwardRefs-DPRKg5wq.6f09e9d22fa6.js.gz +0 -0
  543. codex/static_root/assets/forwardRefs-DPRKg5wq.js.br +0 -0
  544. codex/static_root/assets/forwardRefs-DPRKg5wq.js.gz +0 -0
  545. codex/static_root/assets/group-tab-BVlBrMwo.1127b51be6e7.js +0 -1
  546. codex/static_root/assets/group-tab-BVlBrMwo.1127b51be6e7.js.br +0 -0
  547. codex/static_root/assets/group-tab-BVlBrMwo.1127b51be6e7.js.gz +0 -0
  548. codex/static_root/assets/group-tab-BVlBrMwo.js +0 -1
  549. codex/static_root/assets/group-tab-BVlBrMwo.js.br +0 -0
  550. codex/static_root/assets/group-tab-BVlBrMwo.js.gz +0 -0
  551. codex/static_root/assets/http-error-C9-_aEBF.d29b164e80de.js +0 -1
  552. codex/static_root/assets/http-error-C9-_aEBF.d29b164e80de.js.br +0 -0
  553. codex/static_root/assets/http-error-C9-_aEBF.d29b164e80de.js.gz +0 -0
  554. codex/static_root/assets/http-error-C9-_aEBF.js +0 -1
  555. codex/static_root/assets/http-error-C9-_aEBF.js.br +0 -0
  556. codex/static_root/assets/http-error-C9-_aEBF.js.gz +0 -0
  557. codex/static_root/assets/index-9nBCksDQ.4561d2608773.js.br +0 -0
  558. codex/static_root/assets/index-9nBCksDQ.4561d2608773.js.gz +0 -0
  559. codex/static_root/assets/index-9nBCksDQ.js.br +0 -0
  560. codex/static_root/assets/index-9nBCksDQ.js.gz +0 -0
  561. codex/static_root/assets/library-tab-BMe3dKzy.22b6e123ecfb.js +0 -1
  562. codex/static_root/assets/library-tab-BMe3dKzy.22b6e123ecfb.js.br +0 -0
  563. codex/static_root/assets/library-tab-BMe3dKzy.22b6e123ecfb.js.gz +0 -0
  564. codex/static_root/assets/library-tab-BMe3dKzy.js +0 -1
  565. codex/static_root/assets/library-tab-BMe3dKzy.js.br +0 -0
  566. codex/static_root/assets/library-tab-BMe3dKzy.js.gz +0 -0
  567. codex/static_root/assets/main-BbNUiWEb.565b616eb122.js +0 -35
  568. codex/static_root/assets/main-BbNUiWEb.565b616eb122.js.br +0 -0
  569. codex/static_root/assets/main-BbNUiWEb.565b616eb122.js.gz +0 -0
  570. codex/static_root/assets/main-BbNUiWEb.js +0 -35
  571. codex/static_root/assets/main-BbNUiWEb.js.br +0 -0
  572. codex/static_root/assets/main-BbNUiWEb.js.gz +0 -0
  573. codex/static_root/assets/pager-full-pdf-JwAUlsNI.6d4ec47c14f7.js +0 -1
  574. codex/static_root/assets/pager-full-pdf-JwAUlsNI.6d4ec47c14f7.js.br +0 -0
  575. codex/static_root/assets/pager-full-pdf-JwAUlsNI.6d4ec47c14f7.js.gz +0 -0
  576. codex/static_root/assets/pager-full-pdf-JwAUlsNI.js +0 -1
  577. codex/static_root/assets/pager-full-pdf-JwAUlsNI.js.br +0 -0
  578. codex/static_root/assets/pager-full-pdf-JwAUlsNI.js.gz +0 -0
  579. codex/static_root/assets/pagination-toolbar-Dx5JwWG-.ba0e8b645dfa.js.br +0 -0
  580. codex/static_root/assets/pagination-toolbar-Dx5JwWG-.ba0e8b645dfa.js.gz +0 -0
  581. codex/static_root/assets/pagination-toolbar-Dx5JwWG-.js.br +0 -0
  582. codex/static_root/assets/pagination-toolbar-Dx5JwWG-.js.gz +0 -0
  583. codex/static_root/assets/pdf-doc-6ZE_HmLT.10d1e16abc78.js.br +0 -0
  584. codex/static_root/assets/pdf-doc-6ZE_HmLT.10d1e16abc78.js.gz +0 -0
  585. codex/static_root/assets/pdf-doc-6ZE_HmLT.js.br +0 -0
  586. codex/static_root/assets/pdf-doc-6ZE_HmLT.js.gz +0 -0
  587. codex/static_root/assets/reader-DdPKDuh5.0c55cef1e98b.js +0 -2
  588. codex/static_root/assets/reader-DdPKDuh5.0c55cef1e98b.js.br +0 -0
  589. codex/static_root/assets/reader-DdPKDuh5.0c55cef1e98b.js.gz +0 -0
  590. codex/static_root/assets/reader-DdPKDuh5.js +0 -2
  591. codex/static_root/assets/reader-DdPKDuh5.js.br +0 -0
  592. codex/static_root/assets/reader-DdPKDuh5.js.gz +0 -0
  593. codex/static_root/assets/relation-chips-C96hi5jm.9f07c9eb533a.js.br +0 -0
  594. codex/static_root/assets/relation-chips-C96hi5jm.9f07c9eb533a.js.gz +0 -0
  595. codex/static_root/assets/relation-chips-C96hi5jm.js.br +0 -0
  596. codex/static_root/assets/relation-chips-C96hi5jm.js.gz +0 -0
  597. codex/static_root/assets/settings-drawer-CqbT1rid.5639fa00b301.js +0 -2
  598. codex/static_root/assets/settings-drawer-CqbT1rid.5639fa00b301.js.br +0 -0
  599. codex/static_root/assets/settings-drawer-CqbT1rid.5639fa00b301.js.gz +0 -0
  600. codex/static_root/assets/settings-drawer-CqbT1rid.js +0 -2
  601. codex/static_root/assets/settings-drawer-CqbT1rid.js.br +0 -0
  602. codex/static_root/assets/settings-drawer-CqbT1rid.js.gz +0 -0
  603. codex/static_root/assets/stats-tab-CkT2ZGUQ.b704fa46dc88.js.br +0 -0
  604. codex/static_root/assets/stats-tab-CkT2ZGUQ.b704fa46dc88.js.gz +0 -0
  605. codex/static_root/assets/stats-tab-CkT2ZGUQ.js.br +0 -0
  606. codex/static_root/assets/stats-tab-CkT2ZGUQ.js.gz +0 -0
  607. codex/static_root/assets/task-tab-DfdUY9Rc.478e74041f80.css +0 -1
  608. codex/static_root/assets/task-tab-DfdUY9Rc.478e74041f80.css.gz +0 -0
  609. codex/static_root/assets/task-tab-DfdUY9Rc.css +0 -1
  610. codex/static_root/assets/task-tab-DfdUY9Rc.css.gz +0 -0
  611. codex/static_root/assets/task-tab-a-DcU3Tj.8c2f7bf3c4c9.js +0 -1
  612. codex/static_root/assets/task-tab-a-DcU3Tj.8c2f7bf3c4c9.js.br +0 -0
  613. codex/static_root/assets/task-tab-a-DcU3Tj.8c2f7bf3c4c9.js.gz +0 -0
  614. codex/static_root/assets/task-tab-a-DcU3Tj.js +0 -1
  615. codex/static_root/assets/task-tab-a-DcU3Tj.js.br +0 -0
  616. codex/static_root/assets/task-tab-a-DcU3Tj.js.gz +0 -0
  617. codex/static_root/assets/unauthorized-BOl5YpL3.f3c4b52718d5.js +0 -1
  618. codex/static_root/assets/unauthorized-BOl5YpL3.f3c4b52718d5.js.br +0 -0
  619. codex/static_root/assets/unauthorized-BOl5YpL3.f3c4b52718d5.js.gz +0 -0
  620. codex/static_root/assets/unauthorized-BOl5YpL3.js +0 -1
  621. codex/static_root/assets/unauthorized-BOl5YpL3.js.br +0 -0
  622. codex/static_root/assets/unauthorized-BOl5YpL3.js.gz +0 -0
  623. codex/static_root/assets/user-tab-BBDZvD8G.aa4263a68b22.js +0 -1
  624. codex/static_root/assets/user-tab-BBDZvD8G.aa4263a68b22.js.br +0 -0
  625. codex/static_root/assets/user-tab-BBDZvD8G.aa4263a68b22.js.gz +0 -0
  626. codex/static_root/assets/user-tab-BBDZvD8G.js +0 -1
  627. codex/static_root/assets/user-tab-BBDZvD8G.js.br +0 -0
  628. codex/static_root/assets/user-tab-BBDZvD8G.js.gz +0 -0
  629. codex/static_root/manifest.225989a17f49.json.br +0 -0
  630. codex/static_root/manifest.225989a17f49.json.gz +0 -0
  631. {codex-1.7.3a2.dist-info → codex-1.7.5.dist-info}/LICENSE +0 -0
  632. {codex-1.7.3a2.dist-info → codex-1.7.5.dist-info}/entry_points.txt +0 -0
Binary file
Binary file
@@ -1 +1 @@
1
- {"paths": {"rest_framework/docs/img/favicon.ico": "rest_framework/docs/img/favicon.5195b4d0f3eb.ico", "rest_framework/docs/img/grid.png": "rest_framework/docs/img/grid.a4b938cf382b.png", "rest_framework/docs/css/jquery.json-view.min.css": "rest_framework/docs/css/jquery.json-view.min.a2e6beeb6710.css", "rest_framework/docs/css/highlight.css": "rest_framework/docs/css/highlight.e0e4d973c6d7.css", "rest_framework/docs/css/base.css": "rest_framework/docs/css/base.e630f8f4990e.css", "rest_framework/docs/js/highlight.pack.js": "rest_framework/docs/js/highlight.pack.479b5f21dcba.js", "rest_framework/docs/js/api.js": "rest_framework/docs/js/api.18a5ba8a1bd8.js", "rest_framework/docs/js/jquery.json-view.min.js": "rest_framework/docs/js/jquery.json-view.min.b7c2d6981377.js", "rest_framework/fonts/glyphicons-halflings-regular.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/glyphicons-halflings-regular.woff": "rest_framework/fonts/glyphicons-halflings-regular.fa2772327f55.woff", "rest_framework/fonts/fontawesome-webfont.ttf": "rest_framework/fonts/fontawesome-webfont.dcb26c7239d8.ttf", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "rest_framework/fonts/fontawesome-webfont.svg": "rest_framework/fonts/fontawesome-webfont.83e37a11f9d7.svg", "rest_framework/fonts/glyphicons-halflings-regular.ttf": "rest_framework/fonts/glyphicons-halflings-regular.e18bbf611f2a.ttf", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "rest_framework/img/glyphicons-halflings.png": "rest_framework/img/glyphicons-halflings.90233c9067e9.png", "rest_framework/img/glyphicons-halflings-white.png": "rest_framework/img/glyphicons-halflings-white.9bbc6e960299.png", "rest_framework/img/grid.png": "rest_framework/img/grid.a4b938cf382b.png", "rest_framework/css/bootstrap.min.css": "rest_framework/css/bootstrap.min.f17d4516b026.css", "rest_framework/css/prettify.css": "rest_framework/css/prettify.a987f72342ee.css", "rest_framework/css/bootstrap-theme.min.css": "rest_framework/css/bootstrap-theme.min.1d4b05b397c3.css", "rest_framework/css/font-awesome-4.0.3.css": "rest_framework/css/font-awesome-4.0.3.c1e1ea213abf.css", "rest_framework/css/bootstrap-tweaks.css": "rest_framework/css/bootstrap-tweaks.ee4ee6acf9eb.css", "rest_framework/css/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/bootstrap-theme.min.css.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "rest_framework/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "rest_framework/js/ajax-form.js": "rest_framework/js/ajax-form.4e1cdcb7acab.js", "rest_framework/js/prettify-min.js": "rest_framework/js/prettify-min.709bfcc456c6.js", "rest_framework/js/default.js": "rest_framework/js/default.5b08897dbdc3.js", "rest_framework/js/load-ajax-form.js": "rest_framework/js/load-ajax-form.8cdb3a9f3466.js", "rest_framework/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "img/story-arc.svg": "img/story-arc.ca10014355ef.svg", "img/logo-maskable.svg": "img/logo-maskable.8f7de7f1c6a8.svg", "img/folder.svg": "img/folder.f28936a3701d.svg", "img/missing-cover-165.webp": "img/missing-cover-165.0743171f2148.webp", "img/missing-cover.svg": "img/missing-cover.ddb038cc2c56.svg", "img/publisher.svg": "img/publisher.82d378fcd601.svg", "img/logo-32.webp": "img/logo-32.5688944495bf.webp", "img/imprint.svg": "img/imprint.7c2adebb76d6.svg", "img/logo.svg": "img/logo.0f5344a028ca.svg", "img/volume.svg": "img/volume.814e4c79461a.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.c58d966aa64e.webp", "img/series.svg": "img/series.ec8a889b8f95.svg", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "assets/admin-C3iCIUnm.css": "assets/admin-C3iCIUnm.06cb213f624d.css", "assets/relation-chips-DpbzrZxT.css": "assets/relation-chips-DpbzrZxT.01269a188e01.css", "assets/VRadioGroup-DoayJpcS.js": "assets/VRadioGroup-DoayJpcS.fe5e0e74ffee.js", "assets/stats-tab-CkT2ZGUQ.js": "assets/stats-tab-CkT2ZGUQ.b704fa46dc88.js", "assets/datetime-column-BavtvLnf.css": "assets/datetime-column-BavtvLnf.1f3bf499e063.css", "assets/admin-settings-button-progress-BqRFyhjf.js": "assets/admin-settings-button-progress-BqRFyhjf.2bb1194b21e2.js", "assets/group-tab-BVlBrMwo.js": "assets/group-tab-BVlBrMwo.1127b51be6e7.js", "assets/pagination-toolbar-D5VQREy5.css": "assets/pagination-toolbar-D5VQREy5.dcb0eba65827.css", "assets/index-9nBCksDQ.js": "assets/index-9nBCksDQ.4561d2608773.js", "assets/VSelect-BSLmHX_P.js": "assets/VSelect-BSLmHX_P.9ab865ec0fad.js", "assets/confirm-dialog-DqCey9Iq.js": "assets/confirm-dialog-DqCey9Iq.e315d7f8f752.js", "assets/http-error-C9-_aEBF.js": "assets/http-error-C9-_aEBF.d29b164e80de.js", "assets/admin-menu-_aAGknKO.js": "assets/admin-menu-_aAGknKO.0c08c9bd2e7d.js", "assets/library-tab-CgsXOX_r.css": "assets/library-tab-CgsXOX_r.75baedb7e976.css", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/task-tab-a-DcU3Tj.js": "assets/task-tab-a-DcU3Tj.8c2f7bf3c4c9.js", "assets/confirm-dialog-B1ABbGMU.css": "assets/confirm-dialog-B1ABbGMU.9b5915b112c0.css", "assets/VWindowItem-CWBhiE_Y.css": "assets/VWindowItem-CWBhiE_Y.f7fb19752bf3.css", "assets/group-tab-_vKWzoyd.css": "assets/group-tab-_vKWzoyd.948e907b1e6b.css", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/change-password-dialog-D0ymWcl_.css": "assets/change-password-dialog-D0ymWcl_.a30e68c6e303.css", "assets/VTable-BfcOiEpa.js": "assets/VTable-BfcOiEpa.77ef3973bb54.js", "assets/settings-drawer-DMSsWF8c.css": "assets/settings-drawer-DMSsWF8c.75a6ea969e71.css", "assets/browser-chTZ1CM4.css": "assets/browser-chTZ1CM4.521193ab0710.css", "assets/VForm-DxBt30-N.css": "assets/VForm-DxBt30-N.138c0b89b6fc.css", "assets/change-password-dialog-1ZVP_Q2w.js": "assets/change-password-dialog-1ZVP_Q2w.ae0d9e5bd42b.js", "assets/pagination-toolbar-Dx5JwWG-.js": "assets/pagination-toolbar-Dx5JwWG-.ba0e8b645dfa.js", "assets/reader-D_3ruSqa.css": "assets/reader-D_3ruSqa.2ed32f08e906.css", "assets/VCombobox-BQHELb_o.css": "assets/VCombobox-BQHELb_o.9f25a34994e2.css", "assets/VDivider-D1Ot4vR2.js": "assets/VDivider-D1Ot4vR2.9dbee744fb3c.js", "assets/filter-mnO3lLPo.js": "assets/filter-mnO3lLPo.659442401b16.js", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/unauthorized-CsSak07X.css": "assets/unauthorized-CsSak07X.c5536d9dae75.css", "assets/VDialog-DWos4S54.css": "assets/VDialog-DWos4S54.b07aca713774.css", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/main-K8cER0IH.css": "assets/main-K8cER0IH.d529e8b3f52a.css", "assets/pdf-doc-6ZE_HmLT.js": "assets/pdf-doc-6ZE_HmLT.10d1e16abc78.js", "assets/VSelect-CP_CVb8s.css": "assets/VSelect-CP_CVb8s.6309f7bf17bb.css", "assets/VRadioGroup-Cp9mZ7cb.css": "assets/VRadioGroup-Cp9mZ7cb.8e3741381961.css", "assets/VDivider-DU47sRrT.css": "assets/VDivider-DU47sRrT.3d2e17799e5c.css", "assets/reader-DdPKDuh5.js": "assets/reader-DdPKDuh5.0c55cef1e98b.js", "assets/VSelectionControl-DPpfgCW2.css": "assets/VSelectionControl-DPpfgCW2.cc18de4e83f6.css", "assets/admin-menu-B3iXsOyy.css": "assets/admin-menu-B3iXsOyy.c13b7df2ff57.css", "assets/library-tab-BMe3dKzy.js": "assets/library-tab-BMe3dKzy.22b6e123ecfb.js", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/forwardRefs-CFNX6kJ2.css": "assets/forwardRefs-CFNX6kJ2.9b56b4459240.css", "assets/VCombobox-C8QLNlSl.js": "assets/VCombobox-C8QLNlSl.6f431e19a453.js", "assets/VExpansionPanels-RsCANmDP.css": "assets/VExpansionPanels-RsCANmDP.5b17872981df.css", "assets/VCheckbox-CvH8ekHL.css": "assets/VCheckbox-CvH8ekHL.016ed8d222c4.css", "assets/VTable-BnxSZ_W5.css": "assets/VTable-BnxSZ_W5.c36f0a6a30cf.css", "assets/main-BbNUiWEb.js": "assets/main-BbNUiWEb.565b616eb122.js", "assets/browser-DAprXYuP.js": "assets/browser-DAprXYuP.8bb92965dd9d.js", "assets/datetime-column-CBA8bYeO.js": "assets/datetime-column-CBA8bYeO.17a31f189d66.js", "assets/stats-tab-WvF2acoZ.css": "assets/stats-tab-WvF2acoZ.9fdb0106124d.css", "assets/VCheckboxBtn-CZ_P-qUM.js": "assets/VCheckboxBtn-CZ_P-qUM.847452d574cf.js", "assets/task-tab-DfdUY9Rc.css": "assets/task-tab-DfdUY9Rc.478e74041f80.css", "assets/admin-settings-button-progress-BGB22oTD.css": "assets/admin-settings-button-progress-BGB22oTD.2548c49a853e.css", "assets/pager-full-pdf-JwAUlsNI.js": "assets/pager-full-pdf-JwAUlsNI.6d4ec47c14f7.js", "assets/VSelectionControl-TaKCeZgb.js": "assets/VSelectionControl-TaKCeZgb.ad6c96efe57c.js", "assets/flag-tab-glFvEgEl.css": "assets/flag-tab-glFvEgEl.be8eed14384e.css", "assets/index-BHXJTQ4V.css": "assets/index-BHXJTQ4V.523d7b3d350f.css", "assets/admin-CBLHOrM9.js": "assets/admin-CBLHOrM9.8c3c2268bc96.js", "assets/VCheckbox-FaT6MGfu.js": "assets/VCheckbox-FaT6MGfu.f6732060f734.js", "assets/admin-80eqCqtz.js": "assets/admin-80eqCqtz.d6deb9edb8cb.js", "assets/http-error-CODU7jcH.css": "assets/http-error-CODU7jcH.8c13689ae574.css", "assets/relation-chips-C96hi5jm.js": "assets/relation-chips-C96hi5jm.9f07c9eb533a.js", "assets/unauthorized-BOl5YpL3.js": "assets/unauthorized-BOl5YpL3.f3c4b52718d5.js", "assets/user-tab-BBDZvD8G.js": "assets/user-tab-BBDZvD8G.aa4263a68b22.js", "assets/VDialog-RVLeW7je.js": "assets/VDialog-RVLeW7je.c0c7eef71eec.js", "assets/flag-tab-Bc677pNb.js": "assets/flag-tab-Bc677pNb.1b8a2f7c0dc3.js", "assets/settings-drawer-CqbT1rid.js": "assets/settings-drawer-CqbT1rid.5639fa00b301.js", "assets/forwardRefs-DPRKg5wq.js": "assets/forwardRefs-DPRKg5wq.6f09e9d22fa6.js", "assets/pdf-doc-B4cGW_Hl.css": "assets/pdf-doc-B4cGW_Hl.b94aac7e3313.css", "assets/VWindowItem-D8lWcbQY.js": "assets/VWindowItem-D8lWcbQY.e4c75ad78718.js", "assets/VExpansionPanels-DQilGHZk.js": "assets/VExpansionPanels-DQilGHZk.43f06d0a45e0.js", "assets/VForm-DNmY-qFJ.js": "assets/VForm-DNmY-qFJ.81f3a5ff7ec3.js", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.225989a17f49.json"}, "version": "1.1", "hash": "a035b4e91165"}
1
+ {"paths": {"rest_framework/docs/img/favicon.ico": "rest_framework/docs/img/favicon.5195b4d0f3eb.ico", "rest_framework/docs/img/grid.png": "rest_framework/docs/img/grid.a4b938cf382b.png", "rest_framework/docs/css/jquery.json-view.min.css": "rest_framework/docs/css/jquery.json-view.min.a2e6beeb6710.css", "rest_framework/docs/css/highlight.css": "rest_framework/docs/css/highlight.e0e4d973c6d7.css", "rest_framework/docs/css/base.css": "rest_framework/docs/css/base.e630f8f4990e.css", "rest_framework/docs/js/highlight.pack.js": "rest_framework/docs/js/highlight.pack.479b5f21dcba.js", "rest_framework/docs/js/api.js": "rest_framework/docs/js/api.18a5ba8a1bd8.js", "rest_framework/docs/js/jquery.json-view.min.js": "rest_framework/docs/js/jquery.json-view.min.b7c2d6981377.js", "rest_framework/fonts/glyphicons-halflings-regular.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/glyphicons-halflings-regular.woff": "rest_framework/fonts/glyphicons-halflings-regular.fa2772327f55.woff", "rest_framework/fonts/fontawesome-webfont.ttf": "rest_framework/fonts/fontawesome-webfont.dcb26c7239d8.ttf", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "rest_framework/fonts/fontawesome-webfont.svg": "rest_framework/fonts/fontawesome-webfont.83e37a11f9d7.svg", "rest_framework/fonts/glyphicons-halflings-regular.ttf": "rest_framework/fonts/glyphicons-halflings-regular.e18bbf611f2a.ttf", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "rest_framework/img/glyphicons-halflings.png": "rest_framework/img/glyphicons-halflings.90233c9067e9.png", "rest_framework/img/glyphicons-halflings-white.png": "rest_framework/img/glyphicons-halflings-white.9bbc6e960299.png", "rest_framework/img/grid.png": "rest_framework/img/grid.a4b938cf382b.png", "rest_framework/css/bootstrap.min.css": "rest_framework/css/bootstrap.min.f17d4516b026.css", "rest_framework/css/prettify.css": "rest_framework/css/prettify.a987f72342ee.css", "rest_framework/css/bootstrap-theme.min.css": "rest_framework/css/bootstrap-theme.min.1d4b05b397c3.css", "rest_framework/css/font-awesome-4.0.3.css": "rest_framework/css/font-awesome-4.0.3.c1e1ea213abf.css", "rest_framework/css/bootstrap-tweaks.css": "rest_framework/css/bootstrap-tweaks.ee4ee6acf9eb.css", "rest_framework/css/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/bootstrap-theme.min.css.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "rest_framework/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "rest_framework/js/ajax-form.js": "rest_framework/js/ajax-form.4e1cdcb7acab.js", "rest_framework/js/prettify-min.js": "rest_framework/js/prettify-min.709bfcc456c6.js", "rest_framework/js/default.js": "rest_framework/js/default.5b08897dbdc3.js", "rest_framework/js/load-ajax-form.js": "rest_framework/js/load-ajax-form.8cdb3a9f3466.js", "rest_framework/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "img/story-arc.svg": "img/story-arc.ca10014355ef.svg", "img/logo-maskable.svg": "img/logo-maskable.8f7de7f1c6a8.svg", "img/folder.svg": "img/folder.f28936a3701d.svg", "img/missing-cover-165.webp": "img/missing-cover-165.0743171f2148.webp", "img/missing-cover.svg": "img/missing-cover.ddb038cc2c56.svg", "img/publisher.svg": "img/publisher.82d378fcd601.svg", "img/logo-32.webp": "img/logo-32.5688944495bf.webp", "img/imprint.svg": "img/imprint.7c2adebb76d6.svg", "img/logo.svg": "img/logo.0f5344a028ca.svg", "img/volume.svg": "img/volume.814e4c79461a.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.c58d966aa64e.webp", "img/series.svg": "img/series.ec8a889b8f95.svg", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "assets/flag-tab-CcS5pve2.js": "assets/flag-tab-CcS5pve2.a1df5d92e222.js", "assets/VWindowItem-Dm2szrjK.js": "assets/VWindowItem-Dm2szrjK.e77444188aa3.js", "assets/user-tab-CN9nBOMS.js": "assets/user-tab-CN9nBOMS.f88d8b1c8afe.js", "assets/admin-C3iCIUnm.css": "assets/admin-C3iCIUnm.06cb213f624d.css", "assets/relation-chips-DpbzrZxT.css": "assets/relation-chips-DpbzrZxT.01269a188e01.css", "assets/VCombobox-DkOruNH0.js": "assets/VCombobox-DkOruNH0.f30f163ee632.js", "assets/settings-drawer-DY8o-jF3.js": "assets/settings-drawer-DY8o-jF3.48dfaafaa00e.js", "assets/reader-DycvjN42.js": "assets/reader-DycvjN42.3e2b4f43235e.js", "assets/pdf-doc-DRBtl9_2.js": "assets/pdf-doc-DRBtl9_2.225a6d89e842.js", "assets/http-error-EE8gtq5A.js": "assets/http-error-EE8gtq5A.07e291d9d955.js", "assets/datetime-column-BavtvLnf.css": "assets/datetime-column-BavtvLnf.1f3bf499e063.css", "assets/admin-settings-button-progress-BgBgdELw.js": "assets/admin-settings-button-progress-BgBgdELw.52d052e38bc1.js", "assets/pagination-toolbar-D5VQREy5.css": "assets/pagination-toolbar-D5VQREy5.dcb0eba65827.css", "assets/VRadioGroup-C1WCG0rO.js": "assets/VRadioGroup-C1WCG0rO.6ebc88e4f144.js", "assets/library-tab-BkDIAvyS.js": "assets/library-tab-BkDIAvyS.4b4c606b77d6.js", "assets/library-tab-CgsXOX_r.css": "assets/library-tab-CgsXOX_r.75baedb7e976.css", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/task-tab-lFRZ0NMd.js": "assets/task-tab-lFRZ0NMd.6b90f40a1a9f.js", "assets/confirm-dialog-B1ABbGMU.css": "assets/confirm-dialog-B1ABbGMU.9b5915b112c0.css", "assets/unauthorized-Dld9cV8d.js": "assets/unauthorized-Dld9cV8d.4e675fd9991c.js", "assets/VWindowItem-CWBhiE_Y.css": "assets/VWindowItem-CWBhiE_Y.f7fb19752bf3.css", "assets/group-tab-_vKWzoyd.css": "assets/group-tab-_vKWzoyd.948e907b1e6b.css", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/change-password-dialog-D0ymWcl_.css": "assets/change-password-dialog-D0ymWcl_.a30e68c6e303.css", "assets/relation-chips-CeHIEjvZ.js": "assets/relation-chips-CeHIEjvZ.04d302f4fa89.js", "assets/admin-menu-CL7S-xqR.js": "assets/admin-menu-CL7S-xqR.92b6d84c4b70.js", "assets/pager-full-pdf-wuQbceLs.js": "assets/pager-full-pdf-wuQbceLs.111d9b9d4133.js", "assets/VCheckbox-CWBDr4kF.js": "assets/VCheckbox-CWBDr4kF.6da5bf3a4d90.js", "assets/settings-drawer-DMSsWF8c.css": "assets/settings-drawer-DMSsWF8c.75a6ea969e71.css", "assets/VForm-DxBt30-N.css": "assets/VForm-DxBt30-N.138c0b89b6fc.css", "assets/VDivider-By4u2EsM.js": "assets/VDivider-By4u2EsM.fd5ee9cce906.js", "assets/group-tab-SY0gxmHW.js": "assets/group-tab-SY0gxmHW.f72e944c0ff1.js", "assets/reader-D_3ruSqa.css": "assets/reader-D_3ruSqa.2ed32f08e906.css", "assets/VCombobox-BQHELb_o.css": "assets/VCombobox-BQHELb_o.9f25a34994e2.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/admin-B4z2nA5P.js": "assets/admin-B4z2nA5P.da0c92500311.js", "assets/VExpansionPanels-BhO9oj0a.js": "assets/VExpansionPanels-BhO9oj0a.e99bea455c78.js", "assets/unauthorized-CsSak07X.css": "assets/unauthorized-CsSak07X.c5536d9dae75.css", "assets/VSelect-Bbt1vrBg.js": "assets/VSelect-Bbt1vrBg.ec45ee26818a.js", "assets/VDialog-DWos4S54.css": "assets/VDialog-DWos4S54.b07aca713774.css", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/pagination-toolbar-D3JQmDiD.js": "assets/pagination-toolbar-D3JQmDiD.8513a4db85f0.js", "assets/main-K8cER0IH.css": "assets/main-K8cER0IH.d529e8b3f52a.css", "assets/VDialog-Dr7SuC2S.js": "assets/VDialog-Dr7SuC2S.b6ec7df390f4.js", "assets/VSelect-CP_CVb8s.css": "assets/VSelect-CP_CVb8s.6309f7bf17bb.css", "assets/stats-tab-C1XYGBKj.js": "assets/stats-tab-C1XYGBKj.812896e1d09c.js", "assets/VRadioGroup-Cp9mZ7cb.css": "assets/VRadioGroup-Cp9mZ7cb.8e3741381961.css", "assets/admin-BhW3PNO0.js": "assets/admin-BhW3PNO0.e444048e548d.js", "assets/VDivider-DU47sRrT.css": "assets/VDivider-DU47sRrT.3d2e17799e5c.css", "assets/browser-Bi5ov5k8.js": "assets/browser-Bi5ov5k8.a4af87c2a667.js", "assets/VSelectionControl-DPpfgCW2.css": "assets/VSelectionControl-DPpfgCW2.cc18de4e83f6.css", "assets/filter-HnY0knto.js": "assets/filter-HnY0knto.07f807227dcc.js", "assets/datetime-column-BsiYRUKO.js": "assets/datetime-column-BsiYRUKO.cadd764c06f4.js", "assets/admin-menu-B3iXsOyy.css": "assets/admin-menu-B3iXsOyy.c13b7df2ff57.css", "assets/VForm-XhA6T0Lc.js": "assets/VForm-XhA6T0Lc.70c9c6fcb9e3.js", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/flag-tab-D2MYXCHk.css": "assets/flag-tab-D2MYXCHk.0f57e109c01b.css", "assets/forwardRefs-CFNX6kJ2.css": "assets/forwardRefs-CFNX6kJ2.9b56b4459240.css", "assets/VExpansionPanels-RsCANmDP.css": "assets/VExpansionPanels-RsCANmDP.5b17872981df.css", "assets/VCheckbox-CvH8ekHL.css": "assets/VCheckbox-CvH8ekHL.016ed8d222c4.css", "assets/VSelectionControl-BkZZAsWo.js": "assets/VSelectionControl-BkZZAsWo.ba6eca944e2e.js", "assets/VTable-BnxSZ_W5.css": "assets/VTable-BnxSZ_W5.c36f0a6a30cf.css", "assets/stats-tab-WvF2acoZ.css": "assets/stats-tab-WvF2acoZ.9fdb0106124d.css", "assets/main-B5uflU6E.js": "assets/main-B5uflU6E.77f3fcd6873f.js", "assets/admin-settings-button-progress-BGB22oTD.css": "assets/admin-settings-button-progress-BGB22oTD.2548c49a853e.css", "assets/task-tab-CW4DQ3KN.css": "assets/task-tab-CW4DQ3KN.81812f9208e5.css", "assets/index-BHXJTQ4V.css": "assets/index-BHXJTQ4V.523d7b3d350f.css", "assets/ssrBoot-DRKt_yWP.js": "assets/ssrBoot-DRKt_yWP.3b5868abdd61.js", "assets/VTable-D7P2eIc2.js": "assets/VTable-D7P2eIc2.5e94bf2a515b.js", "assets/forwardRefs-i80xmxX3.js": "assets/forwardRefs-i80xmxX3.db393aeef392.js", "assets/http-error-CODU7jcH.css": "assets/http-error-CODU7jcH.8c13689ae574.css", "assets/VCheckboxBtn-COaoh3uF.js": "assets/VCheckboxBtn-COaoh3uF.fc880a386827.js", "assets/index-gVdawuuE.js": "assets/index-gVdawuuE.a940fadbac00.js", "assets/browser-DNzQvgkY.css": "assets/browser-DNzQvgkY.aea8b7d7ca40.css", "assets/confirm-dialog-BoBL4OoS.js": "assets/confirm-dialog-BoBL4OoS.abef9614fea9.js", "assets/change-password-dialog-BKar2Bhb.js": "assets/change-password-dialog-BKar2Bhb.3dbc2feb3c5a.js", "assets/pdf-doc-B4cGW_Hl.css": "assets/pdf-doc-B4cGW_Hl.b94aac7e3313.css", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.66d7229aa07a.json"}, "version": "1.1", "hash": "89736070cb07"}
@@ -6,7 +6,7 @@ from time import time
6
6
 
7
7
  from django.db.models.functions.datetime import Now
8
8
 
9
- from codex.choices import ADMIN_STATUS_TITLES
9
+ from codex.choices.admin import ADMIN_STATUS_TITLES
10
10
  from codex.librarian.notifier.tasks import LIBRARIAN_STATUS_TASK
11
11
  from codex.librarian.tasks import DelayedTasks
12
12
  from codex.logger_base import LoggerBaseMixin
@@ -33,7 +33,7 @@ class StatusController(LoggerBaseMixin):
33
33
  self.init_logger(log_queue)
34
34
  self.librarian_queue = librarian_queue
35
35
 
36
- def _enqueue_notifier_task(self, notify=True, until=0.0):
36
+ def _enqueue_notifier_task(self, notify: bool, until=0.0):
37
37
  """Notify the status has changed."""
38
38
  if not notify:
39
39
  return
@@ -46,7 +46,7 @@ class StatusController(LoggerBaseMixin):
46
46
  def _loggit(self, level, status):
47
47
  """Log with a ? in place of none."""
48
48
  type_title = ADMIN_STATUS_TITLES[status.status_type]
49
- msg = " ".join((type_title, status.subtitle)).strip()
49
+ msg = f"{type_title} {status.subtitle}".strip()
50
50
  msg += ": "
51
51
  if status.complete is None and status.total is None:
52
52
  msg += "In progress"
@@ -69,9 +69,9 @@ class StatusController(LoggerBaseMixin):
69
69
  def start(
70
70
  self,
71
71
  status,
72
- notify=True,
72
+ notify: bool = True, # noqa: FBT002
73
+ preactive: bool = False, # noqa: FBT002
73
74
  now_pad=0.0,
74
- preactive=False,
75
75
  ):
76
76
  """Start a librarian status."""
77
77
  try:
@@ -102,9 +102,9 @@ class StatusController(LoggerBaseMixin):
102
102
  for status in status_iterable:
103
103
  self.start(status, notify=False, now_pad=now_pad, preactive=True)
104
104
  now_pad += 0.1
105
- self._enqueue_notifier_task()
105
+ self._enqueue_notifier_task(notify=True)
106
106
 
107
- def update(self, status, notify=True):
107
+ def update(self, status, notify: bool = True): # noqa: FBT002
108
108
  """Update a librarian status."""
109
109
  if time() - status.since < self._UPDATE_DELTA:
110
110
  # noop unless time has expired.
@@ -127,7 +127,7 @@ class StatusController(LoggerBaseMixin):
127
127
  title = ADMIN_STATUS_TITLES[status.status_type]
128
128
  self.log.warning(f"Update status {title}: {exc}")
129
129
 
130
- def finish_many(self, statii, notify=True, until=0.0):
130
+ def finish_many(self, statii, notify: bool = True, until=0.0): # noqa: FBT002
131
131
  """Finish all librarian statuses."""
132
132
  try:
133
133
  types = []
@@ -143,15 +143,12 @@ class StatusController(LoggerBaseMixin):
143
143
  update_ls.append(ls)
144
144
  LibrarianStatus.objects.bulk_update(update_ls, tuple(updates.keys()))
145
145
  self._enqueue_notifier_task(notify, until)
146
- if ls_filter:
147
- # self.log.debug(f"Cleared {types} librarian statuses")
148
- pass
149
- else:
146
+ if not ls_filter:
150
147
  self.log.info("Cleared all librarian statuses")
151
148
  except Exception as exc:
152
149
  self.log.warning(f"Finish status {statii}: {exc}")
153
150
 
154
- def finish(self, status, notify=True, until=0.0):
151
+ def finish(self, status, notify: bool = True, until=0.0): # noqa: FBT002
155
152
  """Finish a librarian status."""
156
153
  try:
157
154
  self.finish_many((status,), notify=notify, until=until)
codex/urls/root.py CHANGED
@@ -1,4 +1,5 @@
1
- """Codex URL Configuration.
1
+ """
2
+ Codex URL Configuration.
2
3
 
3
4
  https://docs.djangoproject.com/en/dev/topics/http/urls/
4
5
  """
@@ -17,10 +18,10 @@ register_converter(IntListConverter, "int_list")
17
18
  urlpatterns = []
18
19
  if DEBUG:
19
20
  # Pyright doesn't follow logic so will try to find these types.
20
- from schema_graph.views import Schema # type: ignore
21
+ from schema_graph.views import Schema # type: ignore[reportMissingImports]
21
22
 
22
23
  urlpatterns += [
23
- path("schema/", Schema.as_view()), # type: ignore
24
+ path("schema/", Schema.as_view()), # type: ignore[reportPossiblyUnboundVariable]
24
25
  ]
25
26
 
26
27
  urlpatterns += [
@@ -14,10 +14,7 @@ class AdminAPIKey(AdminGenericAPIView):
14
14
  serializer_class = APIKeySerializer
15
15
  input_serializer_class = None
16
16
 
17
- @extend_schema(
18
- # parameters=[input_serializer_class],
19
- request=input_serializer_class
20
- )
17
+ @extend_schema(request=input_serializer_class)
21
18
  def put(self, *_args, **_kwargs):
22
19
  """Regenerate the API Key."""
23
20
  ts = Timestamp.objects.get(key=Timestamp.TimestampChoices.API_KEY.value)
codex/views/admin/flag.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """Admin Flag View."""
2
2
 
3
3
  from codex.librarian.mp_queue import LIBRARIAN_QUEUE
4
- from codex.librarian.notifier.tasks import LIBRARY_CHANGED_TASK
4
+ from codex.librarian.notifier.tasks import ADMIN_FLAGS_CHANGED_TASK
5
5
  from codex.librarian.tasks import WakeCronTask
6
6
  from codex.logger.logging import get_logger
7
7
  from codex.models import AdminFlag
@@ -39,7 +39,7 @@ class AdminFlagViewSet(AdminModelViewSet):
39
39
  # Folder View could only change the group view and let the ui decide
40
40
  # Registration only needs to change the enable flag
41
41
  if key in _REFRESH_LIBRARY_FLAGS:
42
- LIBRARIAN_QUEUE.put(LIBRARY_CHANGED_TASK)
42
+ LIBRARIAN_QUEUE.put(ADMIN_FLAGS_CHANGED_TASK)
43
43
 
44
44
  def perform_update(self, serializer):
45
45
  """Perform update and hook for change."""
@@ -4,7 +4,7 @@ from django.contrib.auth.models import Group
4
4
  from django.core.cache import cache
5
5
 
6
6
  from codex.librarian.mp_queue import LIBRARIAN_QUEUE
7
- from codex.librarian.notifier.tasks import LIBRARY_CHANGED_TASK
7
+ from codex.librarian.notifier.tasks import GROUPS_CHANGED_TASK
8
8
  from codex.logger.logging import get_logger
9
9
  from codex.serializers.admin.groups import GroupSerializer
10
10
  from codex.views.admin.auth import AdminModelViewSet
@@ -28,7 +28,7 @@ class AdminGroupViewSet(AdminModelViewSet):
28
28
  self._CHANGE_FIELDS
29
29
  ):
30
30
  cache.clear()
31
- LIBRARIAN_QUEUE.put(LIBRARY_CHANGED_TASK)
31
+ LIBRARIAN_QUEUE.put(GROUPS_CHANGED_TASK)
32
32
 
33
33
  def get_serializer(self, *args, **kwargs):
34
34
  """Allow creation with the model serializer without users & libraries."""
@@ -74,7 +74,7 @@ class AdminLibraryViewSet(AdminModelViewSet):
74
74
  )
75
75
  self._create_library_folder(library)
76
76
  self._sync_watchdog()
77
- self._poll(library.pk, False)
77
+ self._poll(library.pk, force=False)
78
78
 
79
79
  def perform_update(self, serializer):
80
80
  """Perform update an run hooks."""
@@ -87,7 +87,7 @@ class AdminLibraryViewSet(AdminModelViewSet):
87
87
  if "groupSet" in validated_keys:
88
88
  self._on_change()
89
89
  self._sync_watchdog(validated_keys)
90
- self._poll(pk, False)
90
+ self._poll(pk, force=False)
91
91
 
92
92
  def perform_destroy(self, instance):
93
93
  """Perform destroy and run hooks."""
@@ -132,8 +132,8 @@ class AdminFolderListView(AdminGenericAPIView):
132
132
  try:
133
133
  serializer = self.input_serializer_class(data=self.request.GET)
134
134
  serializer.is_valid(raise_exception=True)
135
- root_path = Path(serializer.validated_data.get("path", ".")).resolve() # type: ignore
136
- show_hidden = serializer.validated_data.get("show_hidden", False) # type: ignore
135
+ root_path = Path(serializer.validated_data.get("path", ".")).resolve()
136
+ show_hidden = serializer.validated_data.get("show_hidden", False)
137
137
 
138
138
  dirs = self._get_dirs(root_path, show_hidden)
139
139
 
@@ -23,7 +23,7 @@ LOG = get_logger(__name__)
23
23
  class AdminStatsView(AdminGenericAPIView):
24
24
  """Admin Flag Viewset."""
25
25
 
26
- permission_classes: ClassVar[list] = [HasAPIKeyOrIsAdminUser] # type: ignore
26
+ permission_classes: ClassVar[list] = [HasAPIKeyOrIsAdminUser]
27
27
  serializer_class = StatsSerializer
28
28
  input_serializer_class = AdminStatsRequestSerializer
29
29
 
@@ -40,14 +40,14 @@ class AdminStatsView(AdminGenericAPIView):
40
40
 
41
41
  input_serializer = self.input_serializer_class(data=data)
42
42
  input_serializer.is_valid(raise_exception=True)
43
- params = {}
44
- if input_serializer.validated_data and not isinstance(
45
- input_serializer.validated_data, empty
46
- ):
47
- for key, value in input_serializer.validated_data.items():
48
- if value:
49
- params[key] = value
50
- self._params = MappingProxyType(params)
43
+ self._params = MappingProxyType(
44
+ {
45
+ key: value
46
+ for key, value in input_serializer.validated_data.items()
47
+ if input_serializer.validated_data
48
+ and not isinstance(input_serializer.validated_data, empty)
49
+ }
50
+ )
51
51
  return self._params
52
52
 
53
53
  def _add_api_key(self, obj):
@@ -62,7 +62,7 @@ class AdminStatsView(AdminGenericAPIView):
62
62
  obj["config"] = {}
63
63
  obj["config"]["api_key"] = api_key
64
64
 
65
- def get_object(self): # type: ignore
65
+ def get_object(self):
66
66
  """Get the stats object with an api key."""
67
67
  getter = CodexStats(self.params)
68
68
  obj = getter.get()
@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING
6
6
  from drf_spectacular.utils import extend_schema
7
7
  from rest_framework.response import Response
8
8
 
9
+ from codex.choices.notifications import Notifications
9
10
  from codex.librarian.covers.tasks import (
10
11
  CoverCreateAllTask,
11
12
  CoverRemoveAllTask,
@@ -35,7 +36,16 @@ from codex.librarian.janitor.tasks import (
35
36
  JanitorVacuumTask,
36
37
  )
37
38
  from codex.librarian.mp_queue import LIBRARIAN_QUEUE
38
- from codex.librarian.notifier.tasks import LIBRARIAN_STATUS_TASK, LIBRARY_CHANGED_TASK
39
+ from codex.librarian.notifier.tasks import (
40
+ ADMIN_FLAGS_CHANGED_TASK,
41
+ COVERS_CHANGED_TASK,
42
+ FAILED_IMPORTS_CHANGED_TASK,
43
+ GROUPS_CHANGED_TASK,
44
+ LIBRARIAN_STATUS_TASK,
45
+ LIBRARY_CHANGED_TASK,
46
+ USERS_CHANGED_TASK,
47
+ NotifierTask,
48
+ )
39
49
  from codex.librarian.search.tasks import (
40
50
  SearchIndexAbortTask,
41
51
  SearchIndexClearTask,
@@ -64,11 +74,11 @@ _TASK_MAP = MappingProxyType(
64
74
  {
65
75
  "purge_comic_covers": CoverRemoveAllTask(),
66
76
  "create_all_comic_covers": CoverCreateAllTask(),
67
- "search_index_update": SearchIndexUpdateTask(False),
68
- "search_index_rebuild": SearchIndexUpdateTask(True),
77
+ "search_index_update": SearchIndexUpdateTask(rebuild=False),
78
+ "search_index_rebuild": SearchIndexUpdateTask(rebuild=True),
69
79
  "search_index_remove_stale": SearchIndexRemoveStaleTask(),
70
80
  "search_index_abort": SearchIndexAbortTask(),
71
- "search_index_optimize": SearchIndexOptimizeTask(True),
81
+ "search_index_optimize": SearchIndexOptimizeTask(janitor=False),
72
82
  "search_index_clear": SearchIndexClearTask(),
73
83
  "db_vacuum": JanitorVacuumTask(),
74
84
  "db_backup": JanitorBackupTask(),
@@ -77,12 +87,17 @@ _TASK_MAP = MappingProxyType(
77
87
  "db_fts_integrity_check": JanitorFTSIntegrityCheck(),
78
88
  "db_fts_rebuild": JanitorFTSRebuildTask(),
79
89
  "watchdog_sync": WatchdogSyncTask(),
80
- "codex_latest_version": JanitorLatestVersionTask(True),
81
- "codex_update": JanitorUpdateTask(False),
90
+ "codex_latest_version": JanitorLatestVersionTask(force=True),
91
+ "codex_update": JanitorUpdateTask(force=False),
82
92
  "codex_shutdown": JanitorShutdownTask(),
83
93
  "codex_restart": JanitorRestartTask(),
94
+ "notify_admin_flags_changed": ADMIN_FLAGS_CHANGED_TASK,
95
+ "notify_covers_changed": COVERS_CHANGED_TASK,
96
+ "notify_failed_imports_changed": FAILED_IMPORTS_CHANGED_TASK,
97
+ "notify_groups_changed": GROUPS_CHANGED_TASK,
84
98
  "notify_library_changed": LIBRARY_CHANGED_TASK,
85
99
  "notify_librarian_status": LIBRARIAN_STATUS_TASK,
100
+ "notify_users_changed": USERS_CHANGED_TASK,
86
101
  "cleanup_fks": JanitorCleanFKsTask(),
87
102
  "cleanup_db_custom_covers": JanitorCleanCoversTask(),
88
103
  "cleanup_sessions": JanitorCleanupSessionsTask(),
@@ -90,8 +105,8 @@ _TASK_MAP = MappingProxyType(
90
105
  "cleanup_covers": CoverRemoveOrphansTask(),
91
106
  "librarian_clear_status": JanitorClearStatusTask(),
92
107
  "force_update_all_failed_imports": ForceUpdateAllFailedImportsTask(),
93
- "poll": WatchdogPollLibrariesTask(frozenset(), False),
94
- "poll_force": WatchdogPollLibrariesTask(frozenset(), True),
108
+ "poll": WatchdogPollLibrariesTask(frozenset(), force=False),
109
+ "poll_force": WatchdogPollLibrariesTask(frozenset(), force=True),
95
110
  "janitor_nightly": JanitorNightlyTask(),
96
111
  "force_update_groups": UpdateGroupsTask(start_time=EPOCH_START),
97
112
  "adopt_folders": AdoptOrphanFoldersTask(),
@@ -114,10 +129,14 @@ class AdminLibrarianTaskView(AdminAPIView):
114
129
  input_serializer_class = AdminLibrarianTaskSerializer
115
130
  serializer_class = OKSerializer
116
131
 
117
- @classmethod
118
- def _get_task(cls, name, pk):
132
+ def _get_task(self, name, pk):
119
133
  """Stuff library ids into tasks."""
120
- task = _TASK_MAP.get(name)
134
+ if name == "notify_bookmark_changed":
135
+ uid = self.request.user.pk
136
+ group = f"user_{uid}"
137
+ task = NotifierTask(Notifications.BOOKMARK.value, group)
138
+ else:
139
+ task = _TASK_MAP.get(name)
121
140
  if pk and isinstance(
122
141
  task, WatchdogPollLibrariesTask | WatchdogPollLibrariesTask
123
142
  ):
@@ -128,10 +147,10 @@ class AdminLibrarianTaskView(AdminAPIView):
128
147
  def post(self, *_args, **_kwargs):
129
148
  """Download a comic archive."""
130
149
  # DRF does not populate POST correctly, only data
131
- data = self.request.data # type:ignore
150
+ data = self.request.data
132
151
  serializer = self.input_serializer_class(data=data)
133
152
  serializer.is_valid(raise_exception=True)
134
- validated_data: Mapping = serializer.validated_data # type: ignore
153
+ validated_data: Mapping = serializer.validated_data
135
154
  task_name = validated_data.get("task")
136
155
  pk = validated_data.get("library_id")
137
156
  task = self._get_task(task_name, pk)
codex/views/admin/user.py CHANGED
@@ -2,19 +2,25 @@
2
2
 
3
3
  from django.contrib.auth.models import User
4
4
  from django.contrib.auth.password_validation import validate_password
5
- from django.core.cache import cache
6
5
  from django.core.exceptions import ValidationError
7
6
  from rest_framework.response import Response
8
7
  from rest_framework.status import HTTP_202_ACCEPTED, HTTP_400_BAD_REQUEST
9
8
 
9
+ from codex.choices.notifications import Notifications
10
10
  from codex.librarian.mp_queue import LIBRARIAN_QUEUE
11
- from codex.librarian.notifier.tasks import LIBRARY_CHANGED_TASK
11
+ from codex.librarian.notifier.tasks import (
12
+ ADMIN_USERS_CHANGED_TASK,
13
+ USERS_CHANGED_TASK,
14
+ NotifierTask,
15
+ )
12
16
  from codex.logger.logging import get_logger
13
17
  from codex.serializers.admin.users import UserChangePasswordSerializer, UserSerializer
14
18
  from codex.views.admin.auth import AdminGenericAPIView, AdminModelViewSet
15
19
 
16
20
  LOG = get_logger(__name__)
17
21
 
22
+ _BAD_CURRENT_USER_FALSE_KEYS = ("is_active", "is_staff", "is_superuser")
23
+
18
24
 
19
25
  class AdminUserViewSet(AdminModelViewSet):
20
26
  """User ViewSet."""
@@ -28,9 +34,17 @@ class AdminUserViewSet(AdminModelViewSet):
28
34
  INPUT_METHODS = ("POST", "PUT")
29
35
 
30
36
  @staticmethod
31
- def _on_change():
32
- cache.clear()
33
- LIBRARIAN_QUEUE.put(LIBRARY_CHANGED_TASK)
37
+ def _on_change(uid: int):
38
+ if uid:
39
+ group = f"user_{uid}"
40
+ tasks = (
41
+ ADMIN_USERS_CHANGED_TASK,
42
+ NotifierTask(Notifications.USERS.value, group),
43
+ )
44
+ else:
45
+ tasks = (USERS_CHANGED_TASK,)
46
+ for task in tasks:
47
+ LIBRARIAN_QUEUE.put(task)
34
48
 
35
49
  def get_serializer(self, *args, **kwargs):
36
50
  """Allow partial data for update methods."""
@@ -38,18 +52,30 @@ class AdminUserViewSet(AdminModelViewSet):
38
52
  kwargs["partial"] = True
39
53
  return super().get_serializer(*args, **kwargs)
40
54
 
55
+ def _is_change_to_current_user(self):
56
+ instance = self.get_object()
57
+ return instance == self.request.user
58
+
41
59
  def destroy(self, request, *args, **kwargs):
42
60
  """Destroy with guard for logged in user."""
43
- instance = self.get_object()
44
- if instance == request.user:
61
+ if self._is_change_to_current_user():
45
62
  reason = "Cannot delete logged in user."
46
- raise ValueError(reason)
47
- return super().destroy(request, *args, **kwargs)
63
+ raise ValidationError(reason)
64
+ res = super().destroy(request, *args, **kwargs)
65
+ self._on_change(0)
66
+ return res
48
67
 
49
68
  def perform_update(self, serializer):
50
69
  """Add hook after update."""
70
+ data = serializer.validated_data
71
+ if self._is_change_to_current_user() and False in {
72
+ data.get(key) for key in _BAD_CURRENT_USER_FALSE_KEYS
73
+ }:
74
+ reason = "Cannot deactivate logged in user."
75
+ raise ValidationError(reason)
76
+ uid = self.kwargs.get("pk", 0)
51
77
  super().perform_update(serializer)
52
- self._on_change()
78
+ self._on_change(uid)
53
79
 
54
80
  def perform_create(self, serializer):
55
81
  """Create user."""
codex/views/auth.py CHANGED
@@ -1,7 +1,5 @@
1
1
  """Views authorization bases."""
2
2
 
3
- from typing import TYPE_CHECKING
4
-
5
3
  from django.contrib.auth.models import AnonymousUser
6
4
  from django.db.models import Q
7
5
  from rest_framework.generics import GenericAPIView
@@ -11,9 +9,6 @@ from rest_framework.views import APIView
11
9
  from codex.logger.logging import get_logger
12
10
  from codex.models import AdminFlag, Comic, Folder, StoryArc
13
11
 
14
- if TYPE_CHECKING:
15
- from django.contrib.auth.models import User
16
-
17
12
  LOG = get_logger(__name__)
18
13
 
19
14
 
@@ -46,15 +41,15 @@ class AuthGenericAPIView(AuthMixin, GenericAPIView):
46
41
  """Auth Policy GenericAPIView."""
47
42
 
48
43
 
49
- class GroupACLMixin:
44
+ class GroupACLMixin(APIView):
50
45
  """Filter group ACLS for views."""
51
46
 
52
47
  @property
53
48
  def is_admin(self):
54
49
  """Is the current user an admin."""
55
50
  if self._is_admin is None:
56
- user: User = self.request.user # type: ignore
57
- self._is_admin = user and user.is_staff
51
+ user = self.request.user
52
+ self._is_admin = user and getattr(user, "is_staff", False)
58
53
  return self._is_admin
59
54
 
60
55
  @staticmethod
codex/views/bookmark.py CHANGED
@@ -10,7 +10,7 @@ from rest_framework.views import APIView
10
10
  from codex.librarian.bookmark.tasks import BookmarkUpdateTask
11
11
  from codex.librarian.mp_queue import LIBRARIAN_QUEUE
12
12
  from codex.logger.logging import get_logger
13
- from codex.views.auth import AuthAPIView
13
+ from codex.views.auth import AuthAPIView, GroupACLMixin
14
14
 
15
15
  if TYPE_CHECKING:
16
16
  from codex.models import BrowserGroupModel
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
18
18
  LOG = get_logger(__name__)
19
19
 
20
20
 
21
- class BookmarkFilterMixin(APIView, ABC):
21
+ class BookmarkFilterMixin(GroupACLMixin, ABC):
22
22
  """Bookmark filter methods."""
23
23
 
24
24
  def __init__(self, *args, **kwargs):
@@ -30,7 +30,7 @@ class BookmarkFilterMixin(APIView, ABC):
30
30
  def get_bm_rel(self, model):
31
31
  """Create bookmark relation."""
32
32
  if model not in self._bm_rels:
33
- rel_prefix = self.get_rel_prefix(model) # type: ignore
33
+ rel_prefix = self.get_rel_prefix(model)
34
34
  self._bm_rels[model] = rel_prefix + "bookmark"
35
35
  return self._bm_rels[model]
36
36
 
@@ -25,13 +25,13 @@ class BrowserAnnotateCardView(BrowserAnnotateBookmarkView):
25
25
 
26
26
  def add_group_by(self, qs):
27
27
  """Get the group by for the model."""
28
- if group_by := _GROUP_BY.get(qs.model): # type: ignore
28
+ if group_by := _GROUP_BY.get(qs.model):
29
29
  qs = qs.group_by(group_by)
30
30
  return qs
31
31
 
32
32
  def _annotate_group(self, qs):
33
33
  """Annotate Group."""
34
- value = "c" if qs.model is Comic else self.model_group # type: ignore
34
+ value = "c" if qs.model is Comic else self.model_group
35
35
  return qs.annotate(group=Value(value, CharField(max_length=1)))
36
36
 
37
37
  def _annotate_file_name(self, qs):
@@ -115,9 +115,6 @@ class BrowserAnnotateOrderView(BrowserOrderByView, SharedAnnotationsMixin):
115
115
  group = self.kwargs.get("group")
116
116
  pks = self.kwargs.get("pks")
117
117
  show = MappingProxyType(self.params["show"])
118
- # TODO too many annotations for order?
119
- # Move other annotations to card.
120
- # eager publisher for imprint of course
121
118
  sort_name_annotations = self.get_sort_name_annotations(
122
119
  qs.model, group, pks, show
123
120
  )
@@ -134,7 +131,11 @@ class BrowserAnnotateOrderView(BrowserOrderByView, SharedAnnotationsMixin):
134
131
 
135
132
  return Right(
136
133
  path_rel,
137
- StrIndex(Reverse(F(path_rel)), Value(sep)) - 1, # type: ignore
134
+ StrIndex(
135
+ Reverse(F(path_rel)), # type: ignore[reportArgumentType]
136
+ Value(sep),
137
+ )
138
+ - 1,
138
139
  output_field=CharField(),
139
140
  )
140
141
 
@@ -159,9 +160,7 @@ class BrowserAnnotateOrderView(BrowserOrderByView, SharedAnnotationsMixin):
159
160
  if group == STORY_ARC_GROUP and pks:
160
161
  story_arc_pks = pks
161
162
  else:
162
- story_arc_pks = self.params.get("filters", {}).get( # type: ignore
163
- "story_arcs", ()
164
- )
163
+ story_arc_pks = self.params.get("filters", {}).get("story_arcs", ())
165
164
 
166
165
  # If we have one annotate it.
167
166
  if story_arc_pks:
@@ -21,13 +21,15 @@ class BookmarkView(BookmarkUpdate, BookmarkAuthMixin, BrowserFilterView):
21
21
 
22
22
  serializer_class = BookmarkSerializer
23
23
 
24
+ TARGET = "bookmark"
25
+
24
26
  def _parse_params(self):
25
27
  """Validate and translate the submitted data."""
26
28
  group = self.kwargs.get("group")
27
29
  # If the target is recursive, strip everything but finished state data.
28
30
  serializer_class = None if group == "c" else BookmarkFinishedSerializer
29
31
 
30
- data = self.request.data # type: ignore
32
+ data = self.request.data
31
33
  if serializer_class:
32
34
  serializer = serializer_class(data=data, partial=True)
33
35
  else:
@@ -87,8 +87,9 @@ class BrowserBreadcrumbsView(BrowserPaginateView):
87
87
  if not model:
88
88
  model = Publisher
89
89
  group_query = model.objects.none()
90
- self._group_instance = group_query.first()
91
- return self._group_instance # type: ignore
90
+ group_instance: BrowserGroupModel | None = group_query.first()
91
+ self._group_instance = group_instance
92
+ return self._group_instance # type: ignore[reportReturnType]
92
93
 
93
94
  def _init_breadcrumbs(self, valid_groups):
94
95
  """Load breadcrumbs and determine if they should be searched for a graft."""
@@ -103,7 +104,7 @@ class BrowserBreadcrumbsView(BrowserPaginateView):
103
104
  """Save the breadcrumbs to params."""
104
105
  params = dict(self.params)
105
106
  params["breadcrumbs"] = tuple(crumb.dict() for crumb in breadcrumbs)
106
- # HACK rewriting params
107
+ # The only place I rewrite params
107
108
  self._params = MappingProxyType(params)
108
109
 
109
110
  def _breadcrumbs_graft_or_create_story_arc(self) -> tuple[tuple[Route, ...], bool]:
@@ -146,7 +147,7 @@ class BrowserBreadcrumbsView(BrowserPaginateView):
146
147
 
147
148
  pks = self.kwargs["pks"]
148
149
  page = self.kwargs["page"]
149
- folder: Folder | None = self.group_instance # type: ignore
150
+ folder: Folder | None = self.group_instance # type: ignore[reportAssignmentType]
150
151
  name = folder.name if folder and pks else ""
151
152
  group_crumb = Route(FOLDER_GROUP, pks, page, name)
152
153
  new_breadcrumbs = []
@@ -230,7 +231,7 @@ class BrowserBreadcrumbsView(BrowserPaginateView):
230
231
  """Graft or create browse group breadcrumbs."""
231
232
  old_breadcrumbs, changed = self._init_breadcrumbs(GROUP_ORDER)
232
233
 
233
- vng = self.valid_nav_groups # type: ignore
234
+ vng = self.valid_nav_groups
234
235
  test_groups = tuple(reversed(vng[:-1]))
235
236
  new_breadcrumbs = []
236
237
  level = done = False