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
@@ -17,10 +17,10 @@ from codex.views.opds.v2.top_links import OPDS2TopLinksView
17
17
  _MD_CONTRIBUTOR_MAP = MappingProxyType(
18
18
  {
19
19
  "author": AUTHOR_ROLES,
20
- # "translator": {},
20
+ # "translator": {}, unused
21
21
  "editor": {"Editor"},
22
22
  "artist": {"CoverArtist"},
23
- # "illustrator": {},
23
+ # "illustrator": {}, unused, could use penciller
24
24
  "letterer": {"Letterer"},
25
25
  "penciller": {"Penciller"},
26
26
  "colorist": {"Colorist"},
@@ -42,7 +42,9 @@ class OPDS2PublicationView(OPDS2TopLinksView):
42
42
  "dynamicCovers": False,
43
43
  "ts": ts,
44
44
  }
45
- href_data = HrefData(kwargs, query_params, True, "opds:bin:cover")
45
+ href_data = HrefData(
46
+ kwargs, query_params, absolute_query_params=True, url_name="opds:bin:cover"
47
+ )
46
48
  link_data = LinkData(
47
49
  Rel.THUMBNAIL,
48
50
  href_data,
@@ -65,15 +67,13 @@ class OPDS2PublicationView(OPDS2TopLinksView):
65
67
  @staticmethod
66
68
  def _add_contributors(md, pks, key, roles):
67
69
  """Add contributors to metadata."""
68
- if contributors := get_contributors(pks, roles):
70
+ if contributors := get_contributors(pks, roles, exclude=False):
69
71
  md[key] = contributors
70
72
 
71
73
  def _publication_optional_metadata(self, md, obj):
72
74
  """Add optional Publication Metadtata."""
73
75
  if subtitle := obj.name:
74
76
  md["subtitle"] = subtitle
75
- # if identifier := obj.get("guid")
76
- # md["identifier"] = identifier
77
77
  if desc := obj.summary:
78
78
  md["description"] = desc
79
79
  if lang := obj.language:
@@ -89,25 +89,21 @@ class OPDS2PublicationView(OPDS2TopLinksView):
89
89
  """Publication m2m metadata only on the metadata alternate link."""
90
90
  for key, roles in _MD_CONTRIBUTOR_MAP.items():
91
91
  self._add_contributors(md, obj.ids, key, roles)
92
- if contributors := get_contributors(obj.ids, _CONTRIBUTOR_ROLES, True):
92
+ if contributors := get_contributors(obj.ids, _CONTRIBUTOR_ROLES, exclude=True):
93
93
  md["contributor"] = contributors
94
94
 
95
95
  if m2m_objs := get_m2m_objects(obj.ids):
96
- # XXX Subjects can also have links
96
+ # Subjects can also have links
97
97
  # https://readium.org/webpub-manifest/schema/subject-object.schema.json
98
- subjects = []
99
- for subjs in m2m_objs.values():
100
- for subj in subjs:
101
- subjects.append(subj.name)
102
- md["subject"] = subjects
98
+ md["subject"] = [subj.name for subjs in m2m_objs.values() for subj in subjs]
103
99
 
104
100
  def _publication_metadata(self, obj, zero_pad):
105
101
  title = Comic.get_title(
106
102
  obj,
107
103
  volume=False,
108
104
  name=False,
109
- zero_pad=zero_pad,
110
105
  filename_fallback=self.title_filename_fallback,
106
+ zero_pad=zero_pad,
111
107
  )
112
108
  md = {
113
109
  "type": MimeType.BOOK,
@@ -129,10 +125,6 @@ class OPDS2PublicationView(OPDS2TopLinksView):
129
125
  download_mime_type = MimeType.FILE_TYPE_MAP.get(obj.file_type, MimeType.OCTET)
130
126
  self_kwargs = {"pk": obj.pk, "page": 1}
131
127
 
132
- # This would be for comic streaming which is not supported by OPDS 2 yet?
133
- # self_href_data = HrefData(self_kwargs, absolute_query_params=True)
134
- # self_link_data = LinkData(Rel.SELF, self_href_data, mime_type=MimeType.OPDS_PUB)
135
-
136
128
  alt_kwargs = self_kwargs
137
129
  alt_href_data = HrefData(
138
130
  alt_kwargs,
@@ -174,8 +166,6 @@ class OPDS2PublicationView(OPDS2TopLinksView):
174
166
  authenticate=auth_link,
175
167
  )
176
168
  links = [
177
- # Comic streaming link (unsupported)
178
- # self.link(self_link_data),
179
169
  self.link(alt_link_data),
180
170
  self.link(acq_link_data),
181
171
  self.link(prog_link_data),
codex/views/public.py CHANGED
@@ -29,7 +29,7 @@ class AdminFlagsView(GenericAPIView, RetrieveModelMixin):
29
29
  def get_object(self):
30
30
  """Get admin flags."""
31
31
  flags = {}
32
- for obj in self.get_queryset(): # type: ignore
32
+ for obj in self.get_queryset():
33
33
  name = ADMIN_FLAG_CHOICES[obj.key].lower().replace(" ", "_")
34
34
  if obj.key == AdminFlag.FlagChoices.BANNER_TEXT.value:
35
35
  val = obj.value
@@ -95,7 +95,7 @@ class ReaderBooksView(SharedAnnotationsMixin, BookmarkAuthMixin, ReaderParamsVie
95
95
 
96
96
  def _get_comics_list(self):
97
97
  """Get the reader naviation group filter."""
98
- arc: Mapping = self.params.get("arc", {}) # type: ignore
98
+ arc: Mapping = self.params.get("arc", {})
99
99
 
100
100
  arc_group = arc.get("group", "")
101
101
  if not GROUP_MODEL_MAP.get(arc_group):
@@ -170,7 +170,8 @@ class ReaderBooksView(SharedAnnotationsMixin, BookmarkAuthMixin, ReaderParamsVie
170
170
  return book
171
171
 
172
172
  def get_book_collection(self):
173
- """Get the -1, +1 window around the current issue.
173
+ """
174
+ Get the -1, +1 window around the current issue.
174
175
 
175
176
  Uses iteration in python. There are some complicated ways of
176
177
  doing this with __gt[0] & __lt[0] in the db, but I think they
@@ -32,11 +32,11 @@ class IgnoreClientContentNegotiation(BaseContentNegotiation):
32
32
  """Select the first parser in the `.parser_classes` list."""
33
33
  return next(iter(parsers))
34
34
 
35
- def select_renderer( # type: ignore
35
+ def select_renderer(
36
36
  self,
37
37
  request, # noqa: ARG002
38
38
  renderers,
39
- _format_suffix="",
39
+ format_suffix="", # noqa: ARG002, F841, RUF100
40
40
  ):
41
41
  """Select the first renderer in the `.renderer_classes` list."""
42
42
  renderer = next(iter(renderers))
@@ -48,7 +48,7 @@ class ReaderPageView(BookmarkAuthMixin, AuthFilterAPIView):
48
48
 
49
49
  X_MOZ_PRE_HEADERS = frozenset({"prefetch", "preload", "prerender", "subresource"})
50
50
  content_type = "image/jpeg"
51
- content_negotiation_class = IgnoreClientContentNegotiation # type: ignore
51
+ content_negotiation_class = IgnoreClientContentNegotiation # type: ignore[reportAssignmentType]
52
52
 
53
53
  def _update_bookmark(self):
54
54
  """Update the bookmark if the bookmark param was passed."""
@@ -121,9 +121,9 @@ class ReaderParamsView(SessionView):
121
121
  serializer = self.input_serializer_class(data=data)
122
122
  serializer.is_valid(raise_exception=True)
123
123
 
124
- params: dict = mapping_to_dict(_DEFAULT_PARAMS) # type: ignore
124
+ params: dict[str, Any] = mapping_to_dict(_DEFAULT_PARAMS) # type: ignore[reportAssignmentType]
125
125
  if serializer.validated_data:
126
- params.update(serializer.validated_data) # type: ignore
126
+ params.update(serializer.validated_data)
127
127
  self._ensure_arc_contains_comic(params)
128
128
  self._ensure_arc(params)
129
129
 
@@ -58,7 +58,7 @@ class ReaderView(ReaderArcsView):
58
58
  task = LazyImportComicsTask(frozenset(import_pks))
59
59
  LIBRARIAN_QUEUE.put(task)
60
60
 
61
- def get_object(self): # type: ignore
61
+ def get_object(self):
62
62
  """Get the previous and next comics in a group or story arc."""
63
63
  # Books
64
64
  books = self.get_book_collection()
@@ -82,13 +82,13 @@ class ReaderView(ReaderArcsView):
82
82
 
83
83
  arc = self.params.get("arc", {})
84
84
  if not arc.get("group"):
85
- arc["group"] = current.arc_group # type: ignore
85
+ arc["group"] = current.arc_group
86
86
  if not arc.get("pks"):
87
- arc["pks"] = (current.arc_pk,) # type: ignore
88
- arc["index"] = current.arc_index # type:ignore
89
- arc["count"] = current.arc_count # type: ignore
87
+ arc["pks"] = (current.arc_pk,)
88
+ arc["index"] = current.arc_index
89
+ arc["count"] = current.arc_count
90
90
 
91
- close_route = self.get_last_route()
91
+ close_route = self.get_last_route(name=True)
92
92
 
93
93
  return {
94
94
  "books": books,
@@ -7,6 +7,6 @@ from codex.views.settings import SettingsView
7
7
  class ReaderSettingsView(SettingsView):
8
8
  """Get Reader Settings."""
9
9
 
10
- serializer_class = ReaderSettingsSerializer # type: ignore
10
+ serializer_class = ReaderSettingsSerializer
11
11
 
12
12
  SESSION_KEY = "reader"
codex/views/session.py CHANGED
@@ -3,6 +3,7 @@
3
3
  from abc import ABC
4
4
  from copy import deepcopy
5
5
  from types import MappingProxyType
6
+ from typing import TYPE_CHECKING
6
7
 
7
8
  from codex.choices import BROWSER_DEFAULTS, READER_DEFAULTS
8
9
  from codex.logger.logging import get_logger
@@ -10,6 +11,9 @@ from codex.util import mapping_to_dict
10
11
  from codex.views.auth import AuthFilterGenericAPIView
11
12
  from codex.views.util import pop_name
12
13
 
14
+ if TYPE_CHECKING:
15
+ from collections.abc import Mapping
16
+
13
17
  LOG = get_logger(__name__)
14
18
 
15
19
  CONTRIBUTOR_PERSON_UI_FIELD = "contributors"
@@ -78,13 +82,15 @@ class SessionView(AuthFilterGenericAPIView, ABC):
78
82
  default = self.SESSION_DEFAULTS[session_key][key]
79
83
  return session.get(key, default)
80
84
 
81
- def get_last_route(self, name=True):
85
+ def get_last_route(self, name: bool):
82
86
  """Get the last route from the breadcrumbs."""
83
87
  breadcrumbs = self.get_from_session(
84
88
  "breadcrumbs", session_key=self.BROWSER_SESSION_KEY
85
89
  )
86
90
  if not breadcrumbs:
87
- default_breadcrumbs: tuple[dict] = BROWSER_DEFAULTS["breadcrumbs"] # type: ignore
91
+ default_breadcrumbs: tuple[
92
+ Mapping[str, str | tuple[int, ...] | int], ...
93
+ ] = BROWSER_DEFAULTS["breadcrumbs"] # type: ignore[reportAssignmentType]
88
94
  breadcrumbs = default_breadcrumbs
89
95
  last_route = breadcrumbs[-1]
90
96
  if not name:
codex/views/settings.py CHANGED
@@ -29,7 +29,7 @@ class SettingsView(SessionView, ABC):
29
29
  serializer = self.input_serializer_class(data=data)
30
30
  serializer.is_valid(raise_exception=True)
31
31
  validated_data = serializer.validated_data
32
- only = validated_data.get("only") if validated_data else None # type: ignore
32
+ only = validated_data.get("only") if validated_data else None
33
33
  params = self.load_params_from_session(only=only)
34
34
  params = self.validate_settings_get(validated_data, params)
35
35
  serializer = self.get_serializer(params)
@@ -38,7 +38,7 @@ class SettingsView(SessionView, ABC):
38
38
  @extend_schema(responses=None)
39
39
  def patch(self, *args, **kwargs):
40
40
  """Update session settings."""
41
- data = self.request.data # type: ignore
41
+ data = self.request.data
42
42
  serializer = self.get_serializer(data=data)
43
43
  serializer.is_valid(raise_exception=True)
44
44
  params = self.load_params_from_session()
codex/views/timezone.py CHANGED
@@ -28,11 +28,11 @@ class TimezoneView(AuthGenericAPIView):
28
28
  @extend_schema(request=input_serializer_class)
29
29
  def put(self, *args, **kwargs):
30
30
  """Get the user info for the current user."""
31
- data = self.request.data # type: ignore
31
+ data = self.request.data
32
32
  serializer = self.input_serializer_class(data=data)
33
33
  serializer.is_valid(raise_exception=True)
34
34
  try:
35
- timezone = serializer.validated_data.get("timezone") # type: ignore
35
+ timezone = serializer.validated_data.get("timezone")
36
36
  self._save_timezone(timezone)
37
37
  except Exception as exc:
38
38
  reason = f"update user timezone {exc}"
codex/views/util.py CHANGED
@@ -5,6 +5,7 @@ from collections.abc import Mapping
5
5
  from contextlib import suppress
6
6
  from dataclasses import asdict, dataclass
7
7
  from json.decoder import JSONDecodeError
8
+ from typing import Any
8
9
  from urllib.parse import unquote_plus
9
10
 
10
11
  from djangorestframework_camel_case.settings import api_settings
@@ -43,7 +44,7 @@ class Route(dict):
43
44
  dict = asdict
44
45
 
45
46
 
46
- def reparse_json_query_params(query_params, keys) -> dict:
47
+ def reparse_json_query_params(query_params, keys) -> dict[str, Any]:
47
48
  """Reparse JSON encoded query_params."""
48
49
  # It is an unbelievable amount of trouble to try to parse axios native bracket
49
50
  # encoded complex objects in python
@@ -57,7 +58,7 @@ def reparse_json_query_params(query_params, keys) -> dict:
57
58
  parsed_value = value
58
59
 
59
60
  parsed_dict[key] = parsed_value
60
- return dict(underscoreize(parsed_dict, **api_settings.JSON_UNDERSCOREIZE)) # type:ignore
61
+ return dict(underscoreize(parsed_dict, **api_settings.JSON_UNDERSCOREIZE)) # type:ignore[reportReturnType]
61
62
 
62
63
 
63
64
  def pop_name(kwargs: Mapping):
@@ -67,11 +68,11 @@ def pop_name(kwargs: Mapping):
67
68
  return kwargs
68
69
 
69
70
 
70
- async def chunker(open_file, chunk_size=DEFAULT_CHUNK_SIZE):
71
+ def chunker(open_file, chunk_size=DEFAULT_CHUNK_SIZE):
71
72
  """Asynchronous iterator for serving files."""
72
- while True:
73
- chunk = open_file.read(chunk_size)
74
- if not chunk:
75
- open_file.close()
76
- break
77
- yield chunk
73
+ with open_file:
74
+ while True:
75
+ if chunk := open_file.read(chunk_size):
76
+ yield chunk
77
+ else:
78
+ break
codex/views/version.py CHANGED
@@ -15,7 +15,7 @@ class VersionView(AuthGenericAPIView):
15
15
 
16
16
  serializer_class = VersionsSerializer
17
17
 
18
- def get_object(self) -> dict[str, str]: # type: ignore
18
+ def get_object(self) -> dict[str, str]:
19
19
  """Get the versions."""
20
20
  ts = Timestamp.objects.get(key=Timestamp.TimestampChoices.CODEX_VERSION.value)
21
21
  if ts.version:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codex
3
- Version: 1.7.3a2
3
+ Version: 1.7.4
4
4
  Summary: A comic archive web server.
5
5
  Home-page: https://github.com/ajslater/codex
6
6
  License: GPL-3.0-only
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3
20
20
  Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Programming Language :: Python :: 3.11
22
22
  Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
23
24
  Classifier: Programming Language :: Python :: 3 :: Only
24
25
  Classifier: Topic :: Internet :: WWW/HTTP
25
26
  Classifier: Topic :: Multimedia :: Graphics :: Viewers
@@ -43,6 +44,7 @@ Requires-Dist: fnvhash (>=0.1,<0.2)
43
44
  Requires-Dist: humanfriendly (>=10.0,<11.0)
44
45
  Requires-Dist: humanize (>=4.0.0,<5.0.0)
45
46
  Requires-Dist: hypercorn[h3] (>=0.17.3,<0.18.0)
47
+ Requires-Dist: nh3 (>=0.2.18,<0.3.0)
46
48
  Requires-Dist: psutil (>=6.0.0,<7.0.0)
47
49
  Requires-Dist: pyparsing (>=3.1.2,<4.0.0)
48
50
  Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)