codex 1.7.3a2__py3-none-any.whl → 1.7.4__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 (578) hide show
  1. codex/asgi.py +2 -1
  2. codex/choices.py +12 -12
  3. codex/choices_to_json.py +8 -8
  4. codex/db.py +2 -2
  5. codex/exceptions.py +6 -7
  6. codex/librarian/bookmark/bookmarkd.py +8 -4
  7. codex/librarian/bookmark/update.py +82 -48
  8. codex/librarian/covers/create.py +10 -8
  9. codex/librarian/covers/path.py +6 -5
  10. codex/librarian/covers/purge.py +2 -2
  11. codex/librarian/importer/aggregate.py +2 -2
  12. codex/librarian/importer/cache.py +1 -4
  13. codex/librarian/importer/create_comics.py +2 -2
  14. codex/librarian/importer/create_covers.py +1 -1
  15. codex/librarian/importer/create_fks.py +4 -3
  16. codex/librarian/importer/deleted.py +3 -3
  17. codex/librarian/importer/extract.py +56 -37
  18. codex/librarian/importer/failed_imports.py +1 -1
  19. codex/librarian/importer/importer.py +3 -1
  20. codex/librarian/importer/importerd.py +3 -3
  21. codex/librarian/importer/link_comics.py +2 -1
  22. codex/librarian/importer/moved.py +2 -7
  23. codex/librarian/importer/query_fks.py +1 -4
  24. codex/librarian/importer/tasks.py +1 -1
  25. codex/librarian/janitor/integrity.py +27 -20
  26. codex/librarian/janitor/janitor.py +1 -1
  27. codex/librarian/janitor/latest_version.py +1 -1
  28. codex/librarian/janitor/update.py +2 -2
  29. codex/librarian/janitor/vacuum.py +1 -1
  30. codex/librarian/librariand.py +3 -2
  31. codex/librarian/notifier/notifierd.py +2 -1
  32. codex/librarian/search/optimize.py +1 -1
  33. codex/librarian/search/remove.py +1 -1
  34. codex/librarian/search/update.py +4 -4
  35. codex/librarian/telemeter/stats.py +7 -6
  36. codex/librarian/telemeter/telemeter.py +0 -1
  37. codex/librarian/watchdog/db_snapshot.py +3 -3
  38. codex/librarian/watchdog/dir_snapshot_diff.py +3 -4
  39. codex/librarian/watchdog/emitter.py +4 -4
  40. codex/librarian/watchdog/event_batcherd.py +2 -1
  41. codex/librarian/watchdog/events.py +1 -2
  42. codex/librarian/watchdog/observers.py +15 -10
  43. codex/logger/logging.py +1 -1
  44. codex/memory.py +3 -2
  45. codex/migrations/0001_init.py +1 -2
  46. codex/migrations/0014_pdf_issue_suffix_remove_cover_image_sort_name.py +1 -2
  47. codex/migrations/0018_rename_userbookmark_bookmark.py +1 -2
  48. codex/migrations/0028_telemeter.py +1 -5
  49. codex/models/base.py +3 -1
  50. codex/models/bookmark.py +4 -7
  51. codex/models/comic.py +2 -2
  52. codex/models/functions.py +12 -5
  53. codex/models/groups.py +1 -1
  54. codex/models/library.py +1 -1
  55. codex/models/paths.py +4 -4
  56. codex/models/query.py +8 -4
  57. codex/models/util.py +1 -1
  58. codex/permissions.py +1 -1
  59. codex/run.py +1 -1
  60. codex/serializers/admin/libraries.py +1 -3
  61. codex/serializers/admin/stats.py +4 -4
  62. codex/serializers/auth.py +4 -2
  63. codex/serializers/browser/choices.py +87 -9
  64. codex/serializers/browser/filters.py +9 -37
  65. codex/serializers/browser/metadata.py +2 -1
  66. codex/serializers/browser/mixins.py +7 -3
  67. codex/serializers/browser/mtime.py +3 -5
  68. codex/serializers/browser/page.py +5 -4
  69. codex/serializers/browser/settings.py +7 -5
  70. codex/serializers/fields/__init__.py +37 -0
  71. codex/serializers/fields/auth.py +45 -0
  72. codex/serializers/fields/browser.py +85 -0
  73. codex/serializers/fields/group.py +13 -0
  74. codex/serializers/fields/reader.py +22 -0
  75. codex/serializers/fields/sanitized.py +13 -0
  76. codex/serializers/fields/session.py +15 -0
  77. codex/serializers/fields/stats.py +36 -0
  78. codex/serializers/fields/vuetify.py +62 -0
  79. codex/serializers/models/base.py +1 -1
  80. codex/serializers/models/comic.py +2 -2
  81. codex/serializers/models/groups.py +0 -2
  82. codex/serializers/models/named.py +1 -1
  83. codex/serializers/models/pycountry.py +1 -1
  84. codex/serializers/opds/authentication.py +4 -2
  85. codex/serializers/opds/urls.py +2 -1
  86. codex/serializers/opds/v1.py +4 -3
  87. codex/serializers/opds/v2/feed.py +2 -1
  88. codex/serializers/opds/v2/links.py +23 -21
  89. codex/serializers/opds/v2/metadata.py +4 -8
  90. codex/serializers/opds/v2/progression.py +5 -3
  91. codex/serializers/opds/v2/publication.py +16 -18
  92. codex/serializers/opds/v2/unused.py +15 -8
  93. codex/serializers/reader.py +16 -14
  94. codex/serializers/redirect.py +2 -1
  95. codex/serializers/route.py +6 -4
  96. codex/serializers/settings.py +5 -3
  97. codex/serializers/versions.py +2 -1
  98. codex/settings/settings.py +4 -3
  99. codex/signals/django_signals.py +1 -1
  100. codex/static_root/assets/{VCheckbox-FaT6MGfu.f6732060f734.js → VCheckbox-CtTi6T7d.87331fa7e77f.js} +1 -1
  101. codex/static_root/assets/VCheckbox-CtTi6T7d.87331fa7e77f.js.br +0 -0
  102. codex/static_root/assets/VCheckbox-CtTi6T7d.87331fa7e77f.js.gz +0 -0
  103. codex/static_root/assets/{VCheckbox-FaT6MGfu.js → VCheckbox-CtTi6T7d.js} +1 -1
  104. codex/static_root/assets/VCheckbox-CtTi6T7d.js.br +0 -0
  105. codex/static_root/assets/VCheckbox-CtTi6T7d.js.gz +0 -0
  106. codex/static_root/assets/{VCheckboxBtn-CZ_P-qUM.847452d574cf.js → VCheckboxBtn-DQafuWTH.dada5e0634ef.js} +1 -1
  107. codex/static_root/assets/VCheckboxBtn-DQafuWTH.dada5e0634ef.js.br +0 -0
  108. codex/static_root/assets/VCheckboxBtn-DQafuWTH.dada5e0634ef.js.gz +0 -0
  109. codex/static_root/assets/{VCheckboxBtn-CZ_P-qUM.js → VCheckboxBtn-DQafuWTH.js} +1 -1
  110. codex/static_root/assets/VCheckboxBtn-DQafuWTH.js.br +0 -0
  111. codex/static_root/assets/VCheckboxBtn-DQafuWTH.js.gz +0 -0
  112. codex/static_root/assets/{VCombobox-C8QLNlSl.6f431e19a453.js → VCombobox-C6TX3Dhp.e619423a6463.js} +1 -1
  113. codex/static_root/assets/VCombobox-C6TX3Dhp.e619423a6463.js.br +0 -0
  114. codex/static_root/assets/VCombobox-C6TX3Dhp.e619423a6463.js.gz +0 -0
  115. codex/static_root/assets/{VCombobox-C8QLNlSl.js → VCombobox-C6TX3Dhp.js} +1 -1
  116. codex/static_root/assets/VCombobox-C6TX3Dhp.js.br +0 -0
  117. codex/static_root/assets/VCombobox-C6TX3Dhp.js.gz +0 -0
  118. codex/static_root/assets/{VDialog-RVLeW7je.c0c7eef71eec.js → VDialog-CknWq2kd.b2d301ec6ac5.js} +1 -1
  119. codex/static_root/assets/VDialog-CknWq2kd.b2d301ec6ac5.js.br +0 -0
  120. codex/static_root/assets/VDialog-CknWq2kd.b2d301ec6ac5.js.gz +0 -0
  121. codex/static_root/assets/{VDialog-RVLeW7je.js → VDialog-CknWq2kd.js} +1 -1
  122. codex/static_root/assets/VDialog-CknWq2kd.js.br +0 -0
  123. codex/static_root/assets/VDialog-CknWq2kd.js.gz +0 -0
  124. codex/static_root/assets/{VDivider-D1Ot4vR2.9dbee744fb3c.js → VDivider-F4DUgr74.62bc92cab97d.js} +1 -1
  125. codex/static_root/assets/VDivider-F4DUgr74.62bc92cab97d.js.br +0 -0
  126. codex/static_root/assets/VDivider-F4DUgr74.62bc92cab97d.js.gz +0 -0
  127. codex/static_root/assets/{VDivider-D1Ot4vR2.js → VDivider-F4DUgr74.js} +1 -1
  128. codex/static_root/assets/VDivider-F4DUgr74.js.br +0 -0
  129. codex/static_root/assets/VDivider-F4DUgr74.js.gz +0 -0
  130. codex/static_root/assets/{VExpansionPanels-DQilGHZk.43f06d0a45e0.js → VExpansionPanels-CprYUTGT.39b8a50cde43.js} +1 -1
  131. codex/static_root/assets/VExpansionPanels-CprYUTGT.39b8a50cde43.js.br +0 -0
  132. codex/static_root/assets/VExpansionPanels-CprYUTGT.39b8a50cde43.js.gz +0 -0
  133. codex/static_root/assets/{VExpansionPanels-DQilGHZk.js → VExpansionPanels-CprYUTGT.js} +1 -1
  134. codex/static_root/assets/VExpansionPanels-CprYUTGT.js.br +0 -0
  135. codex/static_root/assets/VExpansionPanels-CprYUTGT.js.gz +0 -0
  136. codex/static_root/assets/{VForm-DNmY-qFJ.81f3a5ff7ec3.js → VForm-DnWAUsrl.4ab0786d658e.js} +1 -1
  137. codex/static_root/assets/VForm-DnWAUsrl.4ab0786d658e.js.br +0 -0
  138. codex/static_root/assets/VForm-DnWAUsrl.4ab0786d658e.js.gz +0 -0
  139. codex/static_root/assets/{VForm-DNmY-qFJ.js → VForm-DnWAUsrl.js} +1 -1
  140. codex/static_root/assets/VForm-DnWAUsrl.js.br +0 -0
  141. codex/static_root/assets/VForm-DnWAUsrl.js.gz +0 -0
  142. codex/static_root/assets/{VRadioGroup-DoayJpcS.fe5e0e74ffee.js → VRadioGroup-D71Rszum.befc87b0c476.js} +1 -1
  143. codex/static_root/assets/VRadioGroup-D71Rszum.befc87b0c476.js.br +0 -0
  144. codex/static_root/assets/VRadioGroup-D71Rszum.befc87b0c476.js.gz +0 -0
  145. codex/static_root/assets/{VRadioGroup-DoayJpcS.js → VRadioGroup-D71Rszum.js} +1 -1
  146. codex/static_root/assets/VRadioGroup-D71Rszum.js.br +0 -0
  147. codex/static_root/assets/VRadioGroup-D71Rszum.js.gz +0 -0
  148. codex/static_root/assets/{VSelect-BSLmHX_P.9ab865ec0fad.js → VSelect-CbPDrHNj.4809fbbf00f0.js} +1 -1
  149. codex/static_root/assets/VSelect-CbPDrHNj.4809fbbf00f0.js.br +0 -0
  150. codex/static_root/assets/VSelect-CbPDrHNj.4809fbbf00f0.js.gz +0 -0
  151. codex/static_root/assets/{VSelect-BSLmHX_P.js → VSelect-CbPDrHNj.js} +1 -1
  152. codex/static_root/assets/VSelect-CbPDrHNj.js.br +0 -0
  153. codex/static_root/assets/VSelect-CbPDrHNj.js.gz +0 -0
  154. codex/static_root/assets/{VSelectionControl-TaKCeZgb.ad6c96efe57c.js → VSelectionControl-It389cbo.ac75aee480a0.js} +1 -1
  155. codex/static_root/assets/VSelectionControl-It389cbo.ac75aee480a0.js.br +0 -0
  156. codex/static_root/assets/VSelectionControl-It389cbo.ac75aee480a0.js.gz +0 -0
  157. codex/static_root/assets/{VSelectionControl-TaKCeZgb.js → VSelectionControl-It389cbo.js} +1 -1
  158. codex/static_root/assets/VSelectionControl-It389cbo.js.br +0 -0
  159. codex/static_root/assets/VSelectionControl-It389cbo.js.gz +0 -0
  160. codex/static_root/assets/{VTable-BfcOiEpa.77ef3973bb54.js → VTable-D9e3lKk6.7cd0760008c7.js} +1 -1
  161. codex/static_root/assets/VTable-D9e3lKk6.7cd0760008c7.js.br +0 -0
  162. codex/static_root/assets/VTable-D9e3lKk6.7cd0760008c7.js.gz +0 -0
  163. codex/static_root/assets/{VTable-BfcOiEpa.js → VTable-D9e3lKk6.js} +1 -1
  164. codex/static_root/assets/VTable-D9e3lKk6.js.br +0 -0
  165. codex/static_root/assets/VTable-D9e3lKk6.js.gz +0 -0
  166. codex/static_root/assets/{VWindowItem-D8lWcbQY.e4c75ad78718.js → VWindowItem-B4VZ37cq.e45c5018cc73.js} +1 -1
  167. codex/static_root/assets/VWindowItem-B4VZ37cq.e45c5018cc73.js.br +0 -0
  168. codex/static_root/assets/VWindowItem-B4VZ37cq.e45c5018cc73.js.gz +0 -0
  169. codex/static_root/assets/{VWindowItem-D8lWcbQY.js → VWindowItem-B4VZ37cq.js} +1 -1
  170. codex/static_root/assets/VWindowItem-B4VZ37cq.js.br +0 -0
  171. codex/static_root/assets/VWindowItem-B4VZ37cq.js.gz +0 -0
  172. codex/static_root/assets/{admin-CBLHOrM9.8c3c2268bc96.js → admin-Bkd8zuSF.2a29386f3488.js} +1 -1
  173. codex/static_root/assets/admin-Bkd8zuSF.2a29386f3488.js.br +0 -0
  174. codex/static_root/assets/admin-Bkd8zuSF.2a29386f3488.js.gz +0 -0
  175. codex/static_root/assets/{admin-CBLHOrM9.js → admin-Bkd8zuSF.js} +1 -1
  176. codex/static_root/assets/admin-Bkd8zuSF.js.br +0 -0
  177. codex/static_root/assets/admin-Bkd8zuSF.js.gz +0 -0
  178. codex/static_root/assets/{admin-80eqCqtz.d6deb9edb8cb.js → admin-CFTKGwmx.18915c5df4d3.js} +1 -1
  179. codex/static_root/assets/admin-CFTKGwmx.18915c5df4d3.js.br +0 -0
  180. codex/static_root/assets/admin-CFTKGwmx.18915c5df4d3.js.gz +0 -0
  181. codex/static_root/assets/{admin-80eqCqtz.js → admin-CFTKGwmx.js} +1 -1
  182. codex/static_root/assets/admin-CFTKGwmx.js.br +0 -0
  183. codex/static_root/assets/admin-CFTKGwmx.js.gz +0 -0
  184. codex/static_root/assets/{admin-menu-_aAGknKO.0c08c9bd2e7d.js → admin-menu-CxZqtPES.7b3a06ce4b92.js} +1 -1
  185. codex/static_root/assets/admin-menu-CxZqtPES.7b3a06ce4b92.js.br +0 -0
  186. codex/static_root/assets/admin-menu-CxZqtPES.7b3a06ce4b92.js.gz +0 -0
  187. codex/static_root/assets/{admin-menu-_aAGknKO.js → admin-menu-CxZqtPES.js} +1 -1
  188. codex/static_root/assets/admin-menu-CxZqtPES.js.br +0 -0
  189. codex/static_root/assets/admin-menu-CxZqtPES.js.gz +0 -0
  190. codex/static_root/assets/{admin-settings-button-progress-BqRFyhjf.2bb1194b21e2.js → admin-settings-button-progress-D2TfW_5T.8a9d411ee79d.js} +1 -1
  191. codex/static_root/assets/admin-settings-button-progress-D2TfW_5T.8a9d411ee79d.js.br +0 -0
  192. codex/static_root/assets/admin-settings-button-progress-D2TfW_5T.8a9d411ee79d.js.gz +0 -0
  193. codex/static_root/assets/{admin-settings-button-progress-BqRFyhjf.js → admin-settings-button-progress-D2TfW_5T.js} +1 -1
  194. codex/static_root/assets/admin-settings-button-progress-D2TfW_5T.js.br +0 -0
  195. codex/static_root/assets/admin-settings-button-progress-D2TfW_5T.js.gz +0 -0
  196. codex/static_root/assets/browser-Br2DgAdi.433cca495d61.js +1 -0
  197. codex/static_root/assets/browser-Br2DgAdi.433cca495d61.js.br +0 -0
  198. codex/static_root/assets/browser-Br2DgAdi.433cca495d61.js.gz +0 -0
  199. codex/static_root/assets/browser-Br2DgAdi.js +1 -0
  200. codex/static_root/assets/browser-Br2DgAdi.js.br +0 -0
  201. codex/static_root/assets/browser-Br2DgAdi.js.gz +0 -0
  202. codex/static_root/assets/{browser-chTZ1CM4.521193ab0710.css → browser-DNzQvgkY.aea8b7d7ca40.css} +1 -1
  203. codex/static_root/assets/browser-DNzQvgkY.aea8b7d7ca40.css.br +0 -0
  204. codex/static_root/assets/browser-DNzQvgkY.aea8b7d7ca40.css.gz +0 -0
  205. codex/static_root/assets/{browser-chTZ1CM4.css → browser-DNzQvgkY.css} +1 -1
  206. codex/static_root/assets/browser-DNzQvgkY.css.br +0 -0
  207. codex/static_root/assets/browser-DNzQvgkY.css.gz +0 -0
  208. codex/static_root/assets/{change-password-dialog-1ZVP_Q2w.ae0d9e5bd42b.js → change-password-dialog-CSylx5Qb.319466c891c9.js} +1 -1
  209. codex/static_root/assets/change-password-dialog-CSylx5Qb.319466c891c9.js.br +0 -0
  210. codex/static_root/assets/change-password-dialog-CSylx5Qb.319466c891c9.js.gz +0 -0
  211. codex/static_root/assets/{change-password-dialog-1ZVP_Q2w.js → change-password-dialog-CSylx5Qb.js} +1 -1
  212. codex/static_root/assets/change-password-dialog-CSylx5Qb.js.br +0 -0
  213. codex/static_root/assets/change-password-dialog-CSylx5Qb.js.gz +0 -0
  214. codex/static_root/assets/{confirm-dialog-DqCey9Iq.e315d7f8f752.js → confirm-dialog-Bx2R2vgR.d42b6449c495.js} +1 -1
  215. codex/static_root/assets/confirm-dialog-Bx2R2vgR.d42b6449c495.js.br +0 -0
  216. codex/static_root/assets/confirm-dialog-Bx2R2vgR.d42b6449c495.js.gz +0 -0
  217. codex/static_root/assets/{confirm-dialog-DqCey9Iq.js → confirm-dialog-Bx2R2vgR.js} +1 -1
  218. codex/static_root/assets/confirm-dialog-Bx2R2vgR.js.br +0 -0
  219. codex/static_root/assets/confirm-dialog-Bx2R2vgR.js.gz +0 -0
  220. codex/static_root/assets/{datetime-column-CBA8bYeO.17a31f189d66.js → datetime-column-sOrWMDcU.9ad225af18db.js} +1 -1
  221. codex/static_root/assets/datetime-column-sOrWMDcU.9ad225af18db.js.br +2 -0
  222. codex/static_root/assets/datetime-column-sOrWMDcU.9ad225af18db.js.gz +0 -0
  223. codex/static_root/assets/{datetime-column-CBA8bYeO.js → datetime-column-sOrWMDcU.js} +1 -1
  224. codex/static_root/assets/datetime-column-sOrWMDcU.js.br +2 -0
  225. codex/static_root/assets/datetime-column-sOrWMDcU.js.gz +0 -0
  226. codex/static_root/assets/{filter-mnO3lLPo.659442401b16.js → filter-SgjvoAvL.094069d6978d.js} +1 -1
  227. codex/static_root/assets/filter-SgjvoAvL.094069d6978d.js.br +0 -0
  228. codex/static_root/assets/filter-SgjvoAvL.094069d6978d.js.gz +0 -0
  229. codex/static_root/assets/{filter-mnO3lLPo.js → filter-SgjvoAvL.js} +1 -1
  230. codex/static_root/assets/filter-SgjvoAvL.js.br +0 -0
  231. codex/static_root/assets/filter-SgjvoAvL.js.gz +0 -0
  232. codex/static_root/assets/{flag-tab-Bc677pNb.1b8a2f7c0dc3.js → flag-tab-B_0tGWPg.e46d1782b327.js} +1 -1
  233. codex/static_root/assets/flag-tab-B_0tGWPg.e46d1782b327.js.br +0 -0
  234. codex/static_root/assets/flag-tab-B_0tGWPg.e46d1782b327.js.gz +0 -0
  235. codex/static_root/assets/{flag-tab-Bc677pNb.js → flag-tab-B_0tGWPg.js} +1 -1
  236. codex/static_root/assets/flag-tab-B_0tGWPg.js.br +0 -0
  237. codex/static_root/assets/flag-tab-B_0tGWPg.js.gz +0 -0
  238. codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css +1 -0
  239. codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css.br +0 -0
  240. codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css.gz +0 -0
  241. codex/static_root/assets/flag-tab-D2MYXCHk.css +1 -0
  242. codex/static_root/assets/flag-tab-D2MYXCHk.css.br +0 -0
  243. codex/static_root/assets/flag-tab-D2MYXCHk.css.gz +0 -0
  244. codex/static_root/assets/{forwardRefs-DPRKg5wq.6f09e9d22fa6.js → forwardRefs-DqbPK1-k.bb9d6863ac16.js} +1 -1
  245. codex/static_root/assets/forwardRefs-DqbPK1-k.bb9d6863ac16.js.br +0 -0
  246. codex/static_root/assets/forwardRefs-DqbPK1-k.bb9d6863ac16.js.gz +0 -0
  247. codex/static_root/assets/{forwardRefs-DPRKg5wq.js → forwardRefs-DqbPK1-k.js} +1 -1
  248. codex/static_root/assets/forwardRefs-DqbPK1-k.js.br +0 -0
  249. codex/static_root/assets/forwardRefs-DqbPK1-k.js.gz +0 -0
  250. codex/static_root/assets/{group-tab-BVlBrMwo.1127b51be6e7.js → group-tab-DXxQUa6C.f1f12f39b167.js} +1 -1
  251. codex/static_root/assets/group-tab-DXxQUa6C.f1f12f39b167.js.br +0 -0
  252. codex/static_root/assets/group-tab-DXxQUa6C.f1f12f39b167.js.gz +0 -0
  253. codex/static_root/assets/{group-tab-BVlBrMwo.js → group-tab-DXxQUa6C.js} +1 -1
  254. codex/static_root/assets/group-tab-DXxQUa6C.js.br +0 -0
  255. codex/static_root/assets/group-tab-DXxQUa6C.js.gz +0 -0
  256. codex/static_root/assets/{http-error-C9-_aEBF.d29b164e80de.js → http-error-BVMwwrFo.a7be6a26c9eb.js} +1 -1
  257. codex/static_root/assets/http-error-BVMwwrFo.a7be6a26c9eb.js.br +0 -0
  258. codex/static_root/assets/http-error-BVMwwrFo.a7be6a26c9eb.js.gz +0 -0
  259. codex/static_root/assets/{http-error-C9-_aEBF.js → http-error-BVMwwrFo.js} +1 -1
  260. codex/static_root/assets/http-error-BVMwwrFo.js.br +0 -0
  261. codex/static_root/assets/http-error-BVMwwrFo.js.gz +0 -0
  262. codex/static_root/assets/{index-9nBCksDQ.4561d2608773.js → index-DK0lSHDP.86f18c078fa9.js} +1 -1
  263. codex/static_root/assets/index-DK0lSHDP.86f18c078fa9.js.br +0 -0
  264. codex/static_root/assets/index-DK0lSHDP.86f18c078fa9.js.gz +0 -0
  265. codex/static_root/assets/{index-9nBCksDQ.js → index-DK0lSHDP.js} +1 -1
  266. codex/static_root/assets/index-DK0lSHDP.js.br +0 -0
  267. codex/static_root/assets/index-DK0lSHDP.js.gz +0 -0
  268. codex/static_root/assets/{library-tab-BMe3dKzy.22b6e123ecfb.js → library-tab-NhXuvZ4F.1e8ac3b7c168.js} +1 -1
  269. codex/static_root/assets/library-tab-NhXuvZ4F.1e8ac3b7c168.js.br +0 -0
  270. codex/static_root/assets/library-tab-NhXuvZ4F.1e8ac3b7c168.js.gz +0 -0
  271. codex/static_root/assets/{library-tab-BMe3dKzy.js → library-tab-NhXuvZ4F.js} +1 -1
  272. codex/static_root/assets/library-tab-NhXuvZ4F.js.br +0 -0
  273. codex/static_root/assets/library-tab-NhXuvZ4F.js.gz +0 -0
  274. codex/static_root/assets/{main-BbNUiWEb.565b616eb122.js → main-CYgubU7H.50aa39cf9565.js} +3 -3
  275. codex/static_root/assets/main-CYgubU7H.50aa39cf9565.js.br +0 -0
  276. codex/static_root/assets/main-CYgubU7H.50aa39cf9565.js.gz +0 -0
  277. codex/static_root/assets/{main-BbNUiWEb.js → main-CYgubU7H.js} +3 -3
  278. codex/static_root/assets/main-CYgubU7H.js.br +0 -0
  279. codex/static_root/assets/main-CYgubU7H.js.gz +0 -0
  280. codex/static_root/assets/pager-full-pdf---TZiAf5.a6269ab85085.js +1 -0
  281. codex/static_root/assets/pager-full-pdf---TZiAf5.a6269ab85085.js.br +0 -0
  282. codex/static_root/assets/pager-full-pdf---TZiAf5.a6269ab85085.js.gz +0 -0
  283. codex/static_root/assets/pager-full-pdf---TZiAf5.js +1 -0
  284. codex/static_root/assets/pager-full-pdf---TZiAf5.js.br +0 -0
  285. codex/static_root/assets/pager-full-pdf---TZiAf5.js.gz +0 -0
  286. codex/static_root/assets/{pagination-toolbar-Dx5JwWG-.ba0e8b645dfa.js → pagination-toolbar-CeWXU_qA.abe0805da1cc.js} +1 -1
  287. codex/static_root/assets/pagination-toolbar-CeWXU_qA.abe0805da1cc.js.br +0 -0
  288. codex/static_root/assets/pagination-toolbar-CeWXU_qA.abe0805da1cc.js.gz +0 -0
  289. codex/static_root/assets/{pagination-toolbar-Dx5JwWG-.js → pagination-toolbar-CeWXU_qA.js} +1 -1
  290. codex/static_root/assets/pagination-toolbar-CeWXU_qA.js.br +0 -0
  291. codex/static_root/assets/pagination-toolbar-CeWXU_qA.js.gz +0 -0
  292. codex/static_root/assets/{pdf-doc-6ZE_HmLT.10d1e16abc78.js → pdf-doc-Dws_otkd.d215eca27da5.js} +1 -1
  293. codex/static_root/assets/pdf-doc-Dws_otkd.d215eca27da5.js.br +0 -0
  294. codex/static_root/assets/pdf-doc-Dws_otkd.d215eca27da5.js.gz +0 -0
  295. codex/static_root/assets/{pdf-doc-6ZE_HmLT.js → pdf-doc-Dws_otkd.js} +1 -1
  296. codex/static_root/assets/pdf-doc-Dws_otkd.js.br +0 -0
  297. codex/static_root/assets/pdf-doc-Dws_otkd.js.gz +0 -0
  298. codex/static_root/assets/{reader-DdPKDuh5.0c55cef1e98b.js → reader-BCxYgZHF.dde3c4ac39a5.js} +2 -2
  299. codex/static_root/assets/reader-BCxYgZHF.dde3c4ac39a5.js.br +0 -0
  300. codex/static_root/assets/reader-BCxYgZHF.dde3c4ac39a5.js.gz +0 -0
  301. codex/static_root/assets/{reader-DdPKDuh5.js → reader-BCxYgZHF.js} +2 -2
  302. codex/static_root/assets/reader-BCxYgZHF.js.br +0 -0
  303. codex/static_root/assets/reader-BCxYgZHF.js.gz +0 -0
  304. codex/static_root/assets/{relation-chips-C96hi5jm.js → relation-chips-DNRRCvrw.b1bc75fb9349.js} +1 -1
  305. codex/static_root/assets/relation-chips-DNRRCvrw.b1bc75fb9349.js.br +0 -0
  306. codex/static_root/assets/relation-chips-DNRRCvrw.b1bc75fb9349.js.gz +0 -0
  307. codex/static_root/assets/{relation-chips-C96hi5jm.9f07c9eb533a.js → relation-chips-DNRRCvrw.js} +1 -1
  308. codex/static_root/assets/relation-chips-DNRRCvrw.js.br +0 -0
  309. codex/static_root/assets/relation-chips-DNRRCvrw.js.gz +0 -0
  310. codex/static_root/assets/{settings-drawer-CqbT1rid.js → settings-drawer-BuB29L5p.fe2eeea0058f.js} +2 -2
  311. codex/static_root/assets/settings-drawer-BuB29L5p.fe2eeea0058f.js.br +0 -0
  312. codex/static_root/assets/settings-drawer-BuB29L5p.fe2eeea0058f.js.gz +0 -0
  313. codex/static_root/assets/{settings-drawer-CqbT1rid.5639fa00b301.js → settings-drawer-BuB29L5p.js} +2 -2
  314. codex/static_root/assets/settings-drawer-BuB29L5p.js.br +0 -0
  315. codex/static_root/assets/settings-drawer-BuB29L5p.js.gz +0 -0
  316. codex/static_root/assets/{stats-tab-CkT2ZGUQ.b704fa46dc88.js → stats-tab-D0zymxU6.d5267113b51e.js} +1 -1
  317. codex/static_root/assets/stats-tab-D0zymxU6.d5267113b51e.js.br +0 -0
  318. codex/static_root/assets/stats-tab-D0zymxU6.d5267113b51e.js.gz +0 -0
  319. codex/static_root/assets/{stats-tab-CkT2ZGUQ.js → stats-tab-D0zymxU6.js} +1 -1
  320. codex/static_root/assets/stats-tab-D0zymxU6.js.br +0 -0
  321. codex/static_root/assets/stats-tab-D0zymxU6.js.gz +0 -0
  322. codex/static_root/assets/{task-tab-a-DcU3Tj.8c2f7bf3c4c9.js → task-tab-CI9RLdMS.120f395dc9c6.js} +1 -1
  323. codex/static_root/assets/task-tab-CI9RLdMS.120f395dc9c6.js.br +0 -0
  324. codex/static_root/assets/task-tab-CI9RLdMS.120f395dc9c6.js.gz +0 -0
  325. codex/static_root/assets/{task-tab-a-DcU3Tj.js → task-tab-CI9RLdMS.js} +1 -1
  326. codex/static_root/assets/task-tab-CI9RLdMS.js.br +0 -0
  327. codex/static_root/assets/task-tab-CI9RLdMS.js.gz +0 -0
  328. codex/static_root/assets/{unauthorized-BOl5YpL3.f3c4b52718d5.js → unauthorized-BNwg_Xvu.a894b96156e0.js} +1 -1
  329. codex/static_root/assets/unauthorized-BNwg_Xvu.a894b96156e0.js.br +0 -0
  330. codex/static_root/assets/unauthorized-BNwg_Xvu.a894b96156e0.js.gz +0 -0
  331. codex/static_root/assets/{unauthorized-BOl5YpL3.js → unauthorized-BNwg_Xvu.js} +1 -1
  332. codex/static_root/assets/unauthorized-BNwg_Xvu.js.br +0 -0
  333. codex/static_root/assets/unauthorized-BNwg_Xvu.js.gz +0 -0
  334. codex/static_root/assets/{user-tab-BBDZvD8G.aa4263a68b22.js → user-tab-w9LgIMMi.4a89c7b37486.js} +1 -1
  335. codex/static_root/assets/user-tab-w9LgIMMi.4a89c7b37486.js.br +0 -0
  336. codex/static_root/assets/user-tab-w9LgIMMi.4a89c7b37486.js.gz +0 -0
  337. codex/static_root/assets/{user-tab-BBDZvD8G.js → user-tab-w9LgIMMi.js} +1 -1
  338. codex/static_root/assets/user-tab-w9LgIMMi.js.br +0 -0
  339. codex/static_root/assets/user-tab-w9LgIMMi.js.gz +0 -0
  340. codex/static_root/{manifest.225989a17f49.json → manifest.514e63b9f805.json} +253 -253
  341. codex/static_root/manifest.514e63b9f805.json.br +0 -0
  342. codex/static_root/manifest.514e63b9f805.json.gz +0 -0
  343. codex/static_root/manifest.json +253 -253
  344. codex/static_root/manifest.json.br +0 -0
  345. codex/static_root/manifest.json.gz +0 -0
  346. codex/static_root/staticfiles.json +1 -1
  347. codex/status_controller.py +9 -12
  348. codex/urls/root.py +4 -3
  349. codex/views/admin/api_key.py +1 -4
  350. codex/views/admin/library.py +4 -4
  351. codex/views/admin/stats.py +10 -10
  352. codex/views/admin/tasks.py +9 -9
  353. codex/views/auth.py +3 -8
  354. codex/views/bookmark.py +3 -3
  355. codex/views/browser/annotate/card.py +2 -2
  356. codex/views/browser/annotate/order.py +6 -7
  357. codex/views/browser/bookmark.py +3 -1
  358. codex/views/browser/breadcrumbs.py +6 -5
  359. codex/views/browser/browser.py +2 -2
  360. codex/views/browser/choices.py +6 -7
  361. codex/views/browser/cover.py +6 -3
  362. codex/views/browser/download.py +2 -1
  363. codex/views/browser/filters/bookmark.py +1 -1
  364. codex/views/browser/filters/field.py +1 -1
  365. codex/views/browser/filters/filter.py +6 -8
  366. codex/views/browser/filters/group.py +8 -8
  367. codex/views/browser/filters/search/field/expression.py +1 -2
  368. codex/views/browser/filters/search/field/optimize.py +1 -1
  369. codex/views/browser/filters/search/field/parse.py +2 -2
  370. codex/views/browser/filters/search/parse.py +4 -19
  371. codex/views/browser/group_mtime.py +1 -1
  372. codex/views/browser/metadata/copy_intersections.py +1 -1
  373. codex/views/browser/metadata/metadata.py +1 -1
  374. codex/views/browser/mtime.py +1 -1
  375. codex/views/browser/order_by.py +3 -5
  376. codex/views/browser/params.py +1 -1
  377. codex/views/browser/settings.py +1 -1
  378. codex/views/browser/validate.py +8 -5
  379. codex/views/const.py +0 -3
  380. codex/views/frontend.py +1 -1
  381. codex/views/mixins.py +3 -2
  382. codex/views/opds/authentication_v1.py +1 -1
  383. codex/views/opds/const.py +4 -4
  384. codex/views/opds/util.py +3 -3
  385. codex/views/opds/v1/entry/entry.py +4 -2
  386. codex/views/opds/v1/entry/links.py +4 -5
  387. codex/views/opds/v1/facets.py +8 -4
  388. codex/views/opds/v1/feed.py +5 -5
  389. codex/views/opds/v1/links.py +11 -6
  390. codex/views/opds/v2/const.py +5 -2
  391. codex/views/opds/v2/feed.py +3 -3
  392. codex/views/opds/v2/progression.py +8 -9
  393. codex/views/opds/v2/publications.py +10 -20
  394. codex/views/public.py +1 -1
  395. codex/views/reader/books.py +3 -2
  396. codex/views/reader/page.py +3 -3
  397. codex/views/reader/params.py +2 -2
  398. codex/views/reader/reader.py +6 -6
  399. codex/views/reader/settings.py +1 -1
  400. codex/views/session.py +8 -2
  401. codex/views/settings.py +2 -2
  402. codex/views/timezone.py +2 -2
  403. codex/views/util.py +10 -9
  404. codex/views/version.py +1 -1
  405. {codex-1.7.3a2.dist-info → codex-1.7.4.dist-info}/METADATA +3 -1
  406. {codex-1.7.3a2.dist-info → codex-1.7.4.dist-info}/RECORD +409 -401
  407. {codex-1.7.3a2.dist-info → codex-1.7.4.dist-info}/WHEEL +1 -1
  408. codex/serializers/fields.py +0 -183
  409. codex/static_root/assets/VCheckbox-FaT6MGfu.f6732060f734.js.br +0 -0
  410. codex/static_root/assets/VCheckbox-FaT6MGfu.f6732060f734.js.gz +0 -0
  411. codex/static_root/assets/VCheckbox-FaT6MGfu.js.br +0 -0
  412. codex/static_root/assets/VCheckbox-FaT6MGfu.js.gz +0 -0
  413. codex/static_root/assets/VCheckboxBtn-CZ_P-qUM.847452d574cf.js.br +0 -0
  414. codex/static_root/assets/VCheckboxBtn-CZ_P-qUM.847452d574cf.js.gz +0 -0
  415. codex/static_root/assets/VCheckboxBtn-CZ_P-qUM.js.br +0 -0
  416. codex/static_root/assets/VCheckboxBtn-CZ_P-qUM.js.gz +0 -0
  417. codex/static_root/assets/VCombobox-C8QLNlSl.6f431e19a453.js.br +0 -0
  418. codex/static_root/assets/VCombobox-C8QLNlSl.6f431e19a453.js.gz +0 -0
  419. codex/static_root/assets/VCombobox-C8QLNlSl.js.br +0 -0
  420. codex/static_root/assets/VCombobox-C8QLNlSl.js.gz +0 -0
  421. codex/static_root/assets/VDialog-RVLeW7je.c0c7eef71eec.js.br +0 -0
  422. codex/static_root/assets/VDialog-RVLeW7je.c0c7eef71eec.js.gz +0 -0
  423. codex/static_root/assets/VDialog-RVLeW7je.js.br +0 -0
  424. codex/static_root/assets/VDialog-RVLeW7je.js.gz +0 -0
  425. codex/static_root/assets/VDivider-D1Ot4vR2.9dbee744fb3c.js.br +0 -0
  426. codex/static_root/assets/VDivider-D1Ot4vR2.9dbee744fb3c.js.gz +0 -0
  427. codex/static_root/assets/VDivider-D1Ot4vR2.js.br +0 -0
  428. codex/static_root/assets/VDivider-D1Ot4vR2.js.gz +0 -0
  429. codex/static_root/assets/VExpansionPanels-DQilGHZk.43f06d0a45e0.js.br +0 -0
  430. codex/static_root/assets/VExpansionPanels-DQilGHZk.43f06d0a45e0.js.gz +0 -0
  431. codex/static_root/assets/VExpansionPanels-DQilGHZk.js.br +0 -0
  432. codex/static_root/assets/VExpansionPanels-DQilGHZk.js.gz +0 -0
  433. codex/static_root/assets/VForm-DNmY-qFJ.81f3a5ff7ec3.js.br +0 -0
  434. codex/static_root/assets/VForm-DNmY-qFJ.81f3a5ff7ec3.js.gz +0 -0
  435. codex/static_root/assets/VForm-DNmY-qFJ.js.br +0 -0
  436. codex/static_root/assets/VForm-DNmY-qFJ.js.gz +0 -0
  437. codex/static_root/assets/VRadioGroup-DoayJpcS.fe5e0e74ffee.js.br +0 -0
  438. codex/static_root/assets/VRadioGroup-DoayJpcS.fe5e0e74ffee.js.gz +0 -0
  439. codex/static_root/assets/VRadioGroup-DoayJpcS.js.br +0 -0
  440. codex/static_root/assets/VRadioGroup-DoayJpcS.js.gz +0 -0
  441. codex/static_root/assets/VSelect-BSLmHX_P.9ab865ec0fad.js.br +0 -0
  442. codex/static_root/assets/VSelect-BSLmHX_P.9ab865ec0fad.js.gz +0 -0
  443. codex/static_root/assets/VSelect-BSLmHX_P.js.br +0 -0
  444. codex/static_root/assets/VSelect-BSLmHX_P.js.gz +0 -0
  445. codex/static_root/assets/VSelectionControl-TaKCeZgb.ad6c96efe57c.js.br +0 -0
  446. codex/static_root/assets/VSelectionControl-TaKCeZgb.ad6c96efe57c.js.gz +0 -0
  447. codex/static_root/assets/VSelectionControl-TaKCeZgb.js.br +0 -0
  448. codex/static_root/assets/VSelectionControl-TaKCeZgb.js.gz +0 -0
  449. codex/static_root/assets/VTable-BfcOiEpa.77ef3973bb54.js.br +0 -0
  450. codex/static_root/assets/VTable-BfcOiEpa.77ef3973bb54.js.gz +0 -0
  451. codex/static_root/assets/VTable-BfcOiEpa.js.br +0 -0
  452. codex/static_root/assets/VTable-BfcOiEpa.js.gz +0 -0
  453. codex/static_root/assets/VWindowItem-D8lWcbQY.e4c75ad78718.js.br +0 -0
  454. codex/static_root/assets/VWindowItem-D8lWcbQY.e4c75ad78718.js.gz +0 -0
  455. codex/static_root/assets/VWindowItem-D8lWcbQY.js.br +0 -0
  456. codex/static_root/assets/VWindowItem-D8lWcbQY.js.gz +0 -0
  457. codex/static_root/assets/admin-80eqCqtz.d6deb9edb8cb.js.br +0 -0
  458. codex/static_root/assets/admin-80eqCqtz.d6deb9edb8cb.js.gz +0 -0
  459. codex/static_root/assets/admin-80eqCqtz.js.br +0 -0
  460. codex/static_root/assets/admin-80eqCqtz.js.gz +0 -0
  461. codex/static_root/assets/admin-CBLHOrM9.8c3c2268bc96.js.br +0 -0
  462. codex/static_root/assets/admin-CBLHOrM9.8c3c2268bc96.js.gz +0 -0
  463. codex/static_root/assets/admin-CBLHOrM9.js.br +0 -0
  464. codex/static_root/assets/admin-CBLHOrM9.js.gz +0 -0
  465. codex/static_root/assets/admin-menu-_aAGknKO.0c08c9bd2e7d.js.br +0 -0
  466. codex/static_root/assets/admin-menu-_aAGknKO.0c08c9bd2e7d.js.gz +0 -0
  467. codex/static_root/assets/admin-menu-_aAGknKO.js.br +0 -0
  468. codex/static_root/assets/admin-menu-_aAGknKO.js.gz +0 -0
  469. codex/static_root/assets/admin-settings-button-progress-BqRFyhjf.2bb1194b21e2.js.br +0 -0
  470. codex/static_root/assets/admin-settings-button-progress-BqRFyhjf.2bb1194b21e2.js.gz +0 -0
  471. codex/static_root/assets/admin-settings-button-progress-BqRFyhjf.js.br +0 -0
  472. codex/static_root/assets/admin-settings-button-progress-BqRFyhjf.js.gz +0 -0
  473. codex/static_root/assets/browser-DAprXYuP.8bb92965dd9d.js +0 -1
  474. codex/static_root/assets/browser-DAprXYuP.8bb92965dd9d.js.br +0 -0
  475. codex/static_root/assets/browser-DAprXYuP.8bb92965dd9d.js.gz +0 -0
  476. codex/static_root/assets/browser-DAprXYuP.js +0 -1
  477. codex/static_root/assets/browser-DAprXYuP.js.br +0 -0
  478. codex/static_root/assets/browser-DAprXYuP.js.gz +0 -0
  479. codex/static_root/assets/browser-chTZ1CM4.521193ab0710.css.br +0 -0
  480. codex/static_root/assets/browser-chTZ1CM4.521193ab0710.css.gz +0 -0
  481. codex/static_root/assets/browser-chTZ1CM4.css.br +0 -0
  482. codex/static_root/assets/browser-chTZ1CM4.css.gz +0 -0
  483. codex/static_root/assets/change-password-dialog-1ZVP_Q2w.ae0d9e5bd42b.js.br +0 -0
  484. codex/static_root/assets/change-password-dialog-1ZVP_Q2w.ae0d9e5bd42b.js.gz +0 -0
  485. codex/static_root/assets/change-password-dialog-1ZVP_Q2w.js.br +0 -0
  486. codex/static_root/assets/change-password-dialog-1ZVP_Q2w.js.gz +0 -0
  487. codex/static_root/assets/confirm-dialog-DqCey9Iq.e315d7f8f752.js.br +0 -0
  488. codex/static_root/assets/confirm-dialog-DqCey9Iq.e315d7f8f752.js.gz +0 -0
  489. codex/static_root/assets/confirm-dialog-DqCey9Iq.js.br +0 -0
  490. codex/static_root/assets/confirm-dialog-DqCey9Iq.js.gz +0 -0
  491. codex/static_root/assets/datetime-column-CBA8bYeO.17a31f189d66.js.br +0 -0
  492. codex/static_root/assets/datetime-column-CBA8bYeO.17a31f189d66.js.gz +0 -0
  493. codex/static_root/assets/datetime-column-CBA8bYeO.js.br +0 -0
  494. codex/static_root/assets/datetime-column-CBA8bYeO.js.gz +0 -0
  495. codex/static_root/assets/filter-mnO3lLPo.659442401b16.js.br +0 -0
  496. codex/static_root/assets/filter-mnO3lLPo.659442401b16.js.gz +0 -0
  497. codex/static_root/assets/filter-mnO3lLPo.js.br +0 -0
  498. codex/static_root/assets/filter-mnO3lLPo.js.gz +0 -0
  499. codex/static_root/assets/flag-tab-Bc677pNb.1b8a2f7c0dc3.js.br +0 -0
  500. codex/static_root/assets/flag-tab-Bc677pNb.1b8a2f7c0dc3.js.gz +0 -0
  501. codex/static_root/assets/flag-tab-Bc677pNb.js.br +0 -0
  502. codex/static_root/assets/flag-tab-Bc677pNb.js.gz +0 -0
  503. codex/static_root/assets/flag-tab-glFvEgEl.be8eed14384e.css +0 -1
  504. codex/static_root/assets/flag-tab-glFvEgEl.be8eed14384e.css.br +0 -0
  505. codex/static_root/assets/flag-tab-glFvEgEl.be8eed14384e.css.gz +0 -0
  506. codex/static_root/assets/flag-tab-glFvEgEl.css +0 -1
  507. codex/static_root/assets/flag-tab-glFvEgEl.css.br +0 -0
  508. codex/static_root/assets/flag-tab-glFvEgEl.css.gz +0 -0
  509. codex/static_root/assets/forwardRefs-DPRKg5wq.6f09e9d22fa6.js.br +0 -0
  510. codex/static_root/assets/forwardRefs-DPRKg5wq.6f09e9d22fa6.js.gz +0 -0
  511. codex/static_root/assets/forwardRefs-DPRKg5wq.js.br +0 -0
  512. codex/static_root/assets/forwardRefs-DPRKg5wq.js.gz +0 -0
  513. codex/static_root/assets/group-tab-BVlBrMwo.1127b51be6e7.js.br +0 -0
  514. codex/static_root/assets/group-tab-BVlBrMwo.1127b51be6e7.js.gz +0 -0
  515. codex/static_root/assets/group-tab-BVlBrMwo.js.br +0 -0
  516. codex/static_root/assets/group-tab-BVlBrMwo.js.gz +0 -0
  517. codex/static_root/assets/http-error-C9-_aEBF.d29b164e80de.js.br +0 -0
  518. codex/static_root/assets/http-error-C9-_aEBF.d29b164e80de.js.gz +0 -0
  519. codex/static_root/assets/http-error-C9-_aEBF.js.br +0 -0
  520. codex/static_root/assets/http-error-C9-_aEBF.js.gz +0 -0
  521. codex/static_root/assets/index-9nBCksDQ.4561d2608773.js.br +0 -0
  522. codex/static_root/assets/index-9nBCksDQ.4561d2608773.js.gz +0 -0
  523. codex/static_root/assets/index-9nBCksDQ.js.br +0 -0
  524. codex/static_root/assets/index-9nBCksDQ.js.gz +0 -0
  525. codex/static_root/assets/library-tab-BMe3dKzy.22b6e123ecfb.js.br +0 -0
  526. codex/static_root/assets/library-tab-BMe3dKzy.22b6e123ecfb.js.gz +0 -0
  527. codex/static_root/assets/library-tab-BMe3dKzy.js.br +0 -0
  528. codex/static_root/assets/library-tab-BMe3dKzy.js.gz +0 -0
  529. codex/static_root/assets/main-BbNUiWEb.565b616eb122.js.br +0 -0
  530. codex/static_root/assets/main-BbNUiWEb.565b616eb122.js.gz +0 -0
  531. codex/static_root/assets/main-BbNUiWEb.js.br +0 -0
  532. codex/static_root/assets/main-BbNUiWEb.js.gz +0 -0
  533. codex/static_root/assets/pager-full-pdf-JwAUlsNI.6d4ec47c14f7.js +0 -1
  534. codex/static_root/assets/pager-full-pdf-JwAUlsNI.6d4ec47c14f7.js.br +0 -0
  535. codex/static_root/assets/pager-full-pdf-JwAUlsNI.6d4ec47c14f7.js.gz +0 -0
  536. codex/static_root/assets/pager-full-pdf-JwAUlsNI.js +0 -1
  537. codex/static_root/assets/pager-full-pdf-JwAUlsNI.js.br +0 -0
  538. codex/static_root/assets/pager-full-pdf-JwAUlsNI.js.gz +0 -0
  539. codex/static_root/assets/pagination-toolbar-Dx5JwWG-.ba0e8b645dfa.js.br +0 -0
  540. codex/static_root/assets/pagination-toolbar-Dx5JwWG-.ba0e8b645dfa.js.gz +0 -0
  541. codex/static_root/assets/pagination-toolbar-Dx5JwWG-.js.br +0 -0
  542. codex/static_root/assets/pagination-toolbar-Dx5JwWG-.js.gz +0 -0
  543. codex/static_root/assets/pdf-doc-6ZE_HmLT.10d1e16abc78.js.br +0 -0
  544. codex/static_root/assets/pdf-doc-6ZE_HmLT.10d1e16abc78.js.gz +0 -0
  545. codex/static_root/assets/pdf-doc-6ZE_HmLT.js.br +0 -0
  546. codex/static_root/assets/pdf-doc-6ZE_HmLT.js.gz +0 -0
  547. codex/static_root/assets/reader-DdPKDuh5.0c55cef1e98b.js.br +0 -0
  548. codex/static_root/assets/reader-DdPKDuh5.0c55cef1e98b.js.gz +0 -0
  549. codex/static_root/assets/reader-DdPKDuh5.js.br +0 -0
  550. codex/static_root/assets/reader-DdPKDuh5.js.gz +0 -0
  551. codex/static_root/assets/relation-chips-C96hi5jm.9f07c9eb533a.js.br +0 -0
  552. codex/static_root/assets/relation-chips-C96hi5jm.9f07c9eb533a.js.gz +0 -0
  553. codex/static_root/assets/relation-chips-C96hi5jm.js.br +0 -0
  554. codex/static_root/assets/relation-chips-C96hi5jm.js.gz +0 -0
  555. codex/static_root/assets/settings-drawer-CqbT1rid.5639fa00b301.js.br +0 -0
  556. codex/static_root/assets/settings-drawer-CqbT1rid.5639fa00b301.js.gz +0 -0
  557. codex/static_root/assets/settings-drawer-CqbT1rid.js.br +0 -0
  558. codex/static_root/assets/settings-drawer-CqbT1rid.js.gz +0 -0
  559. codex/static_root/assets/stats-tab-CkT2ZGUQ.b704fa46dc88.js.br +0 -0
  560. codex/static_root/assets/stats-tab-CkT2ZGUQ.b704fa46dc88.js.gz +0 -0
  561. codex/static_root/assets/stats-tab-CkT2ZGUQ.js.br +0 -0
  562. codex/static_root/assets/stats-tab-CkT2ZGUQ.js.gz +0 -0
  563. codex/static_root/assets/task-tab-a-DcU3Tj.8c2f7bf3c4c9.js.br +0 -0
  564. codex/static_root/assets/task-tab-a-DcU3Tj.8c2f7bf3c4c9.js.gz +0 -0
  565. codex/static_root/assets/task-tab-a-DcU3Tj.js.br +0 -0
  566. codex/static_root/assets/task-tab-a-DcU3Tj.js.gz +0 -0
  567. codex/static_root/assets/unauthorized-BOl5YpL3.f3c4b52718d5.js.br +0 -0
  568. codex/static_root/assets/unauthorized-BOl5YpL3.f3c4b52718d5.js.gz +0 -0
  569. codex/static_root/assets/unauthorized-BOl5YpL3.js.br +0 -0
  570. codex/static_root/assets/unauthorized-BOl5YpL3.js.gz +0 -0
  571. codex/static_root/assets/user-tab-BBDZvD8G.aa4263a68b22.js.br +0 -0
  572. codex/static_root/assets/user-tab-BBDZvD8G.aa4263a68b22.js.gz +0 -0
  573. codex/static_root/assets/user-tab-BBDZvD8G.js.br +0 -0
  574. codex/static_root/assets/user-tab-BBDZvD8G.js.gz +0 -0
  575. codex/static_root/manifest.225989a17f49.json.br +0 -0
  576. codex/static_root/manifest.225989a17f49.json.gz +0 -0
  577. {codex-1.7.3a2.dist-info → codex-1.7.4.dist-info}/LICENSE +0 -0
  578. {codex-1.7.3a2.dist-info → codex-1.7.4.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/admin-C3iCIUnm.css": "assets/admin-C3iCIUnm.06cb213f624d.css", "assets/relation-chips-DpbzrZxT.css": "assets/relation-chips-DpbzrZxT.01269a188e01.css", "assets/library-tab-NhXuvZ4F.js": "assets/library-tab-NhXuvZ4F.1e8ac3b7c168.js", "assets/VTable-D9e3lKk6.js": "assets/VTable-D9e3lKk6.7cd0760008c7.js", "assets/datetime-column-BavtvLnf.css": "assets/datetime-column-BavtvLnf.1f3bf499e063.css", "assets/reader-BCxYgZHF.js": "assets/reader-BCxYgZHF.dde3c4ac39a5.js", "assets/group-tab-DXxQUa6C.js": "assets/group-tab-DXxQUa6C.f1f12f39b167.js", "assets/VSelect-CbPDrHNj.js": "assets/VSelect-CbPDrHNj.4809fbbf00f0.js", "assets/stats-tab-D0zymxU6.js": "assets/stats-tab-D0zymxU6.d5267113b51e.js", "assets/change-password-dialog-CSylx5Qb.js": "assets/change-password-dialog-CSylx5Qb.319466c891c9.js", "assets/pagination-toolbar-D5VQREy5.css": "assets/pagination-toolbar-D5VQREy5.dcb0eba65827.css", "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/confirm-dialog-B1ABbGMU.css": "assets/confirm-dialog-B1ABbGMU.9b5915b112c0.css", "assets/VDialog-CknWq2kd.js": "assets/VDialog-CknWq2kd.b2d301ec6ac5.js", "assets/VCombobox-C6TX3Dhp.js": "assets/VCombobox-C6TX3Dhp.e619423a6463.js", "assets/VWindowItem-CWBhiE_Y.css": "assets/VWindowItem-CWBhiE_Y.f7fb19752bf3.css", "assets/pager-full-pdf---TZiAf5.js": "assets/pager-full-pdf---TZiAf5.a6269ab85085.js", "assets/main-CYgubU7H.js": "assets/main-CYgubU7H.50aa39cf9565.js", "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/task-tab-CI9RLdMS.js": "assets/task-tab-CI9RLdMS.120f395dc9c6.js", "assets/filter-SgjvoAvL.js": "assets/filter-SgjvoAvL.094069d6978d.js", "assets/forwardRefs-DqbPK1-k.js": "assets/forwardRefs-DqbPK1-k.bb9d6863ac16.js", "assets/settings-drawer-DMSsWF8c.css": "assets/settings-drawer-DMSsWF8c.75a6ea969e71.css", "assets/VForm-DxBt30-N.css": "assets/VForm-DxBt30-N.138c0b89b6fc.css", "assets/reader-D_3ruSqa.css": "assets/reader-D_3ruSqa.2ed32f08e906.css", "assets/flag-tab-B_0tGWPg.js": "assets/flag-tab-B_0tGWPg.e46d1782b327.js", "assets/VCombobox-BQHELb_o.css": "assets/VCombobox-BQHELb_o.9f25a34994e2.css", "assets/VWindowItem-B4VZ37cq.js": "assets/VWindowItem-B4VZ37cq.e45c5018cc73.js", "assets/VRadioGroup-D71Rszum.js": "assets/VRadioGroup-D71Rszum.befc87b0c476.js", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/datetime-column-sOrWMDcU.js": "assets/datetime-column-sOrWMDcU.9ad225af18db.js", "assets/unauthorized-CsSak07X.css": "assets/unauthorized-CsSak07X.c5536d9dae75.css", "assets/VDialog-DWos4S54.css": "assets/VDialog-DWos4S54.b07aca713774.css", "assets/admin-CFTKGwmx.js": "assets/admin-CFTKGwmx.18915c5df4d3.js", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/admin-settings-button-progress-D2TfW_5T.js": "assets/admin-settings-button-progress-D2TfW_5T.8a9d411ee79d.js", "assets/main-K8cER0IH.css": "assets/main-K8cER0IH.d529e8b3f52a.css", "assets/VSelectionControl-It389cbo.js": "assets/VSelectionControl-It389cbo.ac75aee480a0.js", "assets/VCheckboxBtn-DQafuWTH.js": "assets/VCheckboxBtn-DQafuWTH.dada5e0634ef.js", "assets/browser-Br2DgAdi.js": "assets/browser-Br2DgAdi.433cca495d61.js", "assets/VSelect-CP_CVb8s.css": "assets/VSelect-CP_CVb8s.6309f7bf17bb.css", "assets/admin-Bkd8zuSF.js": "assets/admin-Bkd8zuSF.2a29386f3488.js", "assets/relation-chips-DNRRCvrw.js": "assets/relation-chips-DNRRCvrw.b1bc75fb9349.js", "assets/VRadioGroup-Cp9mZ7cb.css": "assets/VRadioGroup-Cp9mZ7cb.8e3741381961.css", "assets/unauthorized-BNwg_Xvu.js": "assets/unauthorized-BNwg_Xvu.a894b96156e0.js", "assets/VDivider-DU47sRrT.css": "assets/VDivider-DU47sRrT.3d2e17799e5c.css", "assets/admin-menu-CxZqtPES.js": "assets/admin-menu-CxZqtPES.7b3a06ce4b92.js", "assets/VSelectionControl-DPpfgCW2.css": "assets/VSelectionControl-DPpfgCW2.cc18de4e83f6.css", "assets/admin-menu-B3iXsOyy.css": "assets/admin-menu-B3iXsOyy.c13b7df2ff57.css", "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/pagination-toolbar-CeWXU_qA.js": "assets/pagination-toolbar-CeWXU_qA.abe0805da1cc.js", "assets/forwardRefs-CFNX6kJ2.css": "assets/forwardRefs-CFNX6kJ2.9b56b4459240.css", "assets/user-tab-w9LgIMMi.js": "assets/user-tab-w9LgIMMi.4a89c7b37486.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/VCheckbox-CtTi6T7d.js": "assets/VCheckbox-CtTi6T7d.87331fa7e77f.js", "assets/stats-tab-WvF2acoZ.css": "assets/stats-tab-WvF2acoZ.9fdb0106124d.css", "assets/VExpansionPanels-CprYUTGT.js": "assets/VExpansionPanels-CprYUTGT.39b8a50cde43.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/http-error-BVMwwrFo.js": "assets/http-error-BVMwwrFo.a7be6a26c9eb.js", "assets/index-BHXJTQ4V.css": "assets/index-BHXJTQ4V.523d7b3d350f.css", "assets/settings-drawer-BuB29L5p.js": "assets/settings-drawer-BuB29L5p.fe2eeea0058f.js", "assets/VDivider-F4DUgr74.js": "assets/VDivider-F4DUgr74.62bc92cab97d.js", "assets/VForm-DnWAUsrl.js": "assets/VForm-DnWAUsrl.4ab0786d658e.js", "assets/http-error-CODU7jcH.css": "assets/http-error-CODU7jcH.8c13689ae574.css", "assets/browser-DNzQvgkY.css": "assets/browser-DNzQvgkY.aea8b7d7ca40.css", "assets/pdf-doc-Dws_otkd.js": "assets/pdf-doc-Dws_otkd.d215eca27da5.js", "assets/pdf-doc-B4cGW_Hl.css": "assets/pdf-doc-B4cGW_Hl.b94aac7e3313.css", "assets/confirm-dialog-Bx2R2vgR.js": "assets/confirm-dialog-Bx2R2vgR.d42b6449c495.js", "assets/index-DK0lSHDP.js": "assets/index-DK0lSHDP.86f18c078fa9.js", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.514e63b9f805.json"}, "version": "1.1", "hash": "3a3f7f3ebcd9"}
@@ -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)
@@ -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()
@@ -64,11 +64,11 @@ _TASK_MAP = MappingProxyType(
64
64
  {
65
65
  "purge_comic_covers": CoverRemoveAllTask(),
66
66
  "create_all_comic_covers": CoverCreateAllTask(),
67
- "search_index_update": SearchIndexUpdateTask(False),
68
- "search_index_rebuild": SearchIndexUpdateTask(True),
67
+ "search_index_update": SearchIndexUpdateTask(rebuild=False),
68
+ "search_index_rebuild": SearchIndexUpdateTask(rebuild=True),
69
69
  "search_index_remove_stale": SearchIndexRemoveStaleTask(),
70
70
  "search_index_abort": SearchIndexAbortTask(),
71
- "search_index_optimize": SearchIndexOptimizeTask(True),
71
+ "search_index_optimize": SearchIndexOptimizeTask(janitor=False),
72
72
  "search_index_clear": SearchIndexClearTask(),
73
73
  "db_vacuum": JanitorVacuumTask(),
74
74
  "db_backup": JanitorBackupTask(),
@@ -77,8 +77,8 @@ _TASK_MAP = MappingProxyType(
77
77
  "db_fts_integrity_check": JanitorFTSIntegrityCheck(),
78
78
  "db_fts_rebuild": JanitorFTSRebuildTask(),
79
79
  "watchdog_sync": WatchdogSyncTask(),
80
- "codex_latest_version": JanitorLatestVersionTask(True),
81
- "codex_update": JanitorUpdateTask(False),
80
+ "codex_latest_version": JanitorLatestVersionTask(force=True),
81
+ "codex_update": JanitorUpdateTask(force=False),
82
82
  "codex_shutdown": JanitorShutdownTask(),
83
83
  "codex_restart": JanitorRestartTask(),
84
84
  "notify_library_changed": LIBRARY_CHANGED_TASK,
@@ -90,8 +90,8 @@ _TASK_MAP = MappingProxyType(
90
90
  "cleanup_covers": CoverRemoveOrphansTask(),
91
91
  "librarian_clear_status": JanitorClearStatusTask(),
92
92
  "force_update_all_failed_imports": ForceUpdateAllFailedImportsTask(),
93
- "poll": WatchdogPollLibrariesTask(frozenset(), False),
94
- "poll_force": WatchdogPollLibrariesTask(frozenset(), True),
93
+ "poll": WatchdogPollLibrariesTask(frozenset(), force=False),
94
+ "poll_force": WatchdogPollLibrariesTask(frozenset(), force=True),
95
95
  "janitor_nightly": JanitorNightlyTask(),
96
96
  "force_update_groups": UpdateGroupsTask(start_time=EPOCH_START),
97
97
  "adopt_folders": AdoptOrphanFoldersTask(),
@@ -128,10 +128,10 @@ class AdminLibrarianTaskView(AdminAPIView):
128
128
  def post(self, *_args, **_kwargs):
129
129
  """Download a comic archive."""
130
130
  # DRF does not populate POST correctly, only data
131
- data = self.request.data # type:ignore
131
+ data = self.request.data
132
132
  serializer = self.input_serializer_class(data=data)
133
133
  serializer.is_valid(raise_exception=True)
134
- validated_data: Mapping = serializer.validated_data # type: ignore
134
+ validated_data: Mapping = serializer.validated_data
135
135
  task_name = validated_data.get("task")
136
136
  pk = validated_data.get("library_id")
137
137
  task = self._get_task(task_name, pk)
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
@@ -173,13 +173,13 @@ class BrowserView(BrowserTitleView):
173
173
  else:
174
174
  zero_pad = 1
175
175
 
176
- # self._debug_queries(page_group_count, page_book_count, group_qs, book_qs)
176
+ # self._debug_queries(page_group_count, page_book_count, group_qs, book_qs) # noqa: ERA001
177
177
 
178
178
  total_page_count = page_group_count + page_book_count
179
179
  mtime = self._get_page_mtime()
180
180
  return group_qs, book_qs, num_pages, total_page_count, zero_pad, mtime
181
181
 
182
- def get_object(self): # type: ignore
182
+ def get_object(self):
183
183
  """Validate settings and get the querysets."""
184
184
  group_qs, book_qs, num_pages, total_count, zero_pad, mtime = (
185
185
  self._get_group_and_books()
@@ -18,8 +18,6 @@ from codex.models import (
18
18
  from codex.models.named import IdentifierType
19
19
  from codex.serializers.browser.choices import (
20
20
  BrowserChoicesFilterSerializer,
21
- )
22
- from codex.serializers.browser.filters import (
23
21
  BrowserFilterChoicesSerializer,
24
22
  )
25
23
  from codex.serializers.browser.settings import BrowserFilterChoicesInputSerilalizer
@@ -98,7 +96,7 @@ class BrowserChoicesViewBase(BrowserFilterView):
98
96
 
99
97
  return rel, model
100
98
 
101
- def get_object(self) -> QuerySet: # type: ignore
99
+ def get_object(self) -> QuerySet:
102
100
  """Get the comic subquery use for the choices."""
103
101
  return self.get_filtered_queryset(Comic)
104
102
 
@@ -136,12 +134,13 @@ class BrowserChoicesAvailableView(BrowserChoicesViewBase):
136
134
 
137
135
  return count
138
136
 
139
- def get_object(self) -> dict[str, Any]: # type: ignore
137
+ def get_object(self) -> dict[str, Any]: # type: ignore[reportIncompatibleMethodOverride]
140
138
  """Get choice counts."""
141
139
  qs = super().get_object()
142
140
  filters = self.params.get("filters", {})
143
141
  data = {}
144
- for field_name in self.serializer_class().get_fields(): # type: ignore
142
+ serializer: BrowserFilterChoicesSerializer = self.serializer_class() # type: ignore[reportOptionalCall, reportAssignmentType]
143
+ for field_name in serializer.get_fields():
145
144
  if field_name == "story_arcs" and qs.model is StoryArc:
146
145
  # don't allow filtering on story arc in story arc view.
147
146
  continue
@@ -154,7 +153,7 @@ class BrowserChoicesAvailableView(BrowserChoicesViewBase):
154
153
 
155
154
  try:
156
155
  is_filter_set = bool(filters.get(field_name))
157
- flag = is_filter_set or count > 1 # type: ignore
156
+ flag = is_filter_set or count > 1
158
157
  except TypeError:
159
158
  flag = False
160
159
  data[field_name] = flag
@@ -185,7 +184,7 @@ class BrowserChoicesView(BrowserChoicesViewBase):
185
184
  field_name = self.kwargs.get("field_name", "")
186
185
  return snakecase(field_name)
187
186
 
188
- def get_object(self) -> dict[str, Any]: # type: ignore
187
+ def get_object(self) -> dict[str, Any]: # type: ignore[reportIncompatibleMethodOverride]
189
188
  """Return choices with more than one choice."""
190
189
  qs = super().get_object()
191
190
  field_name = self._get_field_name()
@@ -52,7 +52,7 @@ class CoverView(BrowserAnnotateOrderView):
52
52
  BrowserAnnotateOrderView.REPARSE_JSON_FIELDS | {"parent"}
53
53
  )
54
54
 
55
- def get_group_filter(self, group=None, pks=None, page_mtime=False):
55
+ def get_group_filter(self, group=None, pks=None, page_mtime=False): # noqa: FBT002
56
56
  """Get group filter for First Cover View."""
57
57
  if self.params.get("dynamic_covers") or self.model in (Volume, Folder):
58
58
  return super().get_group_filter(group=group, pks=pks, page_mtime=page_mtime)
@@ -60,7 +60,10 @@ class CoverView(BrowserAnnotateOrderView):
60
60
  # First cover group filter relies on sort names to look outside the browser supplied pks
61
61
  # For multi_groups not in the browser query.
62
62
  pks = self.kwargs["pks"]
63
- qs = self.model.objects.filter(pk__in=pks) # type: ignore
63
+ if not self.model:
64
+ qs = Comic.objects.none()
65
+ else:
66
+ qs = self.model.objects.filter(pk__in=pks)
64
67
  sort_names = qs.values_list("sort_name", flat=True).distinct()
65
68
  model_rel = GROUP_RELATION[self.model_group]
66
69
  group_filter = {f"{model_rel}__sort_name__in": sort_names}
@@ -142,7 +145,7 @@ class CoverView(BrowserAnnotateOrderView):
142
145
  parameters=[BrowserAnnotateOrderView.input_serializer_class],
143
146
  responses={(200, content_type): OpenApiTypes.BINARY},
144
147
  )
145
- def get(self, *args, **kwargs): # type: ignore
148
+ def get(self, *args, **kwargs):
146
149
  """Get comic cover."""
147
150
  try:
148
151
  try:
@@ -54,7 +54,8 @@ class GroupDownloadView(BrowserFilterView):
54
54
  filename = kwargs.get("filename")
55
55
  if not filename:
56
56
  pks = self.kwargs.get("pks")
57
- filename = f"{self.model.__name__} {pks} Comics.zip" # type: ignore
57
+ name = self.model.__name__ if self.model else "No Model"
58
+ filename = f"{name} {pks} Comics.zip"
58
59
 
59
60
  headers = {"Content-Length": len(zs), "Last-Modified": zs.last_modified}
60
61
  return FileResponse(
@@ -11,7 +11,7 @@ class BrowserFilterBookmarkView(BookmarkFilterMixin, BrowserValidateView):
11
11
 
12
12
  def get_bookmark_filter(self, model):
13
13
  """Build bookmark query."""
14
- choice: str = self.params.get("filters", {}).get("bookmark", "") # type: ignore
14
+ choice: str = self.params.get("filters", {}).get("bookmark", "")
15
15
  if choice:
16
16
  bm_rel = self.get_bm_rel(model)
17
17
  my_bookmark_filter = self.get_my_bookmark_filter(bm_rel)
@@ -55,5 +55,5 @@ class ComicFieldFilterView(GroupFilterView):
55
55
  def get_comic_field_filter(self, model):
56
56
  """Filter the comics based on the form filters."""
57
57
  rel_prefix = self.get_rel_prefix(model)
58
- filters = self.params["filters"] # type: ignore
58
+ filters = self.params["filters"]
59
59
  return self.get_all_comic_field_filters(rel_prefix, filters)
@@ -13,8 +13,6 @@ LOG = get_logger(__name__)
13
13
  class BrowserFilterView(BrowserFilterBookmarkView):
14
14
  """Browser Filters."""
15
15
 
16
- TARGET = ""
17
-
18
16
  def force_inner_joins(self, qs):
19
17
  """Force INNER JOINS to filter empty groups."""
20
18
  demote_tables = {"codex_library"}
@@ -28,10 +26,10 @@ class BrowserFilterView(BrowserFilterBookmarkView):
28
26
  def _get_query_filters(
29
27
  self,
30
28
  model,
29
+ page_mtime,
30
+ bookmark_filter,
31
31
  group=None,
32
32
  pks=None,
33
- page_mtime=False,
34
- bookmark_filter=True,
35
33
  ) -> Q:
36
34
  """Return all the filters except the group filter."""
37
35
  big_include_filter = Q()
@@ -54,16 +52,16 @@ class BrowserFilterView(BrowserFilterBookmarkView):
54
52
  model,
55
53
  group=None,
56
54
  pks=None,
57
- page_mtime=False,
58
- bookmark_filter=True,
55
+ page_mtime=False, # noqa: FBT002
56
+ bookmark_filter=True, # noqa: FBT002
59
57
  ) -> QuerySet:
60
58
  """Get a filtered queryset for the model."""
61
59
  query_filters = self._get_query_filters(
62
60
  model,
63
- group=group,
64
- pks=pks,
65
61
  page_mtime=page_mtime,
66
62
  bookmark_filter=bookmark_filter,
63
+ group=group,
64
+ pks=pks,
67
65
  )
68
66
  # Distinct necissary for folder view with search
69
67
  return model.objects.filter(query_filters).distinct()