codex 1.7.2__py3-none-any.whl → 1.7.3__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 (894) hide show
  1. codex/asgi.py +2 -1
  2. codex/choices.py +10 -11
  3. codex/choices_to_json.py +8 -8
  4. codex/db.py +2 -2
  5. codex/exceptions.py +5 -6
  6. codex/librarian/bookmark/bookmarkd.py +9 -6
  7. codex/librarian/bookmark/tasks.py +1 -1
  8. codex/librarian/bookmark/update.py +17 -31
  9. codex/librarian/covers/create.py +10 -8
  10. codex/librarian/covers/path.py +6 -5
  11. codex/librarian/covers/purge.py +2 -2
  12. codex/librarian/cron/crond.py +1 -1
  13. codex/librarian/importer/aggregate.py +2 -2
  14. codex/librarian/importer/cache.py +1 -4
  15. codex/librarian/importer/create_comics.py +2 -2
  16. codex/librarian/importer/create_covers.py +1 -1
  17. codex/librarian/importer/create_fks.py +4 -3
  18. codex/librarian/importer/deleted.py +3 -3
  19. codex/librarian/importer/extract.py +2 -2
  20. codex/librarian/importer/failed_imports.py +1 -1
  21. codex/librarian/importer/importer.py +3 -1
  22. codex/librarian/importer/importerd.py +3 -3
  23. codex/librarian/importer/link_comics.py +2 -1
  24. codex/librarian/importer/moved.py +2 -7
  25. codex/librarian/importer/query_fks.py +3 -6
  26. codex/librarian/importer/tasks.py +1 -1
  27. codex/librarian/janitor/integrity.py +27 -20
  28. codex/librarian/janitor/janitor.py +5 -2
  29. codex/librarian/janitor/latest_version.py +1 -1
  30. codex/librarian/janitor/update.py +2 -2
  31. codex/librarian/janitor/vacuum.py +1 -1
  32. codex/librarian/librariand.py +16 -15
  33. codex/librarian/notifier/notifierd.py +2 -1
  34. codex/librarian/search/optimize.py +1 -1
  35. codex/librarian/search/remove.py +1 -1
  36. codex/librarian/search/update.py +11 -7
  37. codex/librarian/telemeter/stats.py +7 -6
  38. codex/librarian/telemeter/telemeter.py +0 -1
  39. codex/librarian/watchdog/db_snapshot.py +3 -3
  40. codex/librarian/watchdog/dir_snapshot_diff.py +3 -4
  41. codex/librarian/watchdog/emitter.py +4 -4
  42. codex/librarian/watchdog/event_batcherd.py +2 -1
  43. codex/librarian/watchdog/events.py +1 -2
  44. codex/librarian/watchdog/observers.py +15 -10
  45. codex/logger/loggerd.py +40 -17
  46. codex/logger/logging.py +1 -1
  47. codex/memory.py +3 -2
  48. codex/migrations/0001_init.py +1 -2
  49. codex/migrations/0014_pdf_issue_suffix_remove_cover_image_sort_name.py +1 -2
  50. codex/migrations/0018_rename_userbookmark_bookmark.py +1 -2
  51. codex/migrations/0028_telemeter.py +1 -5
  52. codex/migrations/0031_adminflag_banner.py +50 -0
  53. codex/models/admin.py +4 -3
  54. codex/models/base.py +3 -1
  55. codex/models/bookmark.py +4 -7
  56. codex/models/comic.py +2 -2
  57. codex/models/functions.py +12 -5
  58. codex/models/groups.py +1 -1
  59. codex/models/library.py +1 -1
  60. codex/models/paths.py +4 -4
  61. codex/models/query.py +8 -4
  62. codex/models/util.py +1 -1
  63. codex/permissions.py +1 -1
  64. codex/run.py +1 -1
  65. codex/serializers/admin/flags.py +1 -1
  66. codex/serializers/admin/libraries.py +1 -3
  67. codex/serializers/auth.py +1 -0
  68. codex/serializers/browser/choices.py +2 -2
  69. codex/serializers/browser/mixins.py +5 -1
  70. codex/serializers/browser/settings.py +2 -2
  71. codex/serializers/fields.py +7 -7
  72. codex/serializers/models/base.py +1 -1
  73. codex/serializers/models/comic.py +2 -2
  74. codex/serializers/models/groups.py +0 -2
  75. codex/serializers/opds/authentication.py +2 -1
  76. codex/serializers/opds/v2/__init__.py +1 -0
  77. codex/serializers/opds/v2/facet.py +13 -0
  78. codex/serializers/opds/v2/feed.py +36 -0
  79. codex/serializers/opds/v2/links.py +75 -0
  80. codex/serializers/opds/v2/metadata.py +23 -0
  81. codex/serializers/opds/v2/progression.py +65 -0
  82. codex/serializers/opds/v2/publication.py +81 -0
  83. codex/serializers/opds/{v2_unused.py → v2/unused.py} +16 -9
  84. codex/serializers/route.py +2 -2
  85. codex/settings/settings.py +4 -3
  86. codex/signals/django_signals.py +1 -1
  87. codex/static_root/assets/VCheckbox-Dv6fwaDb.56abbfb00c8a.js +1 -0
  88. codex/static_root/assets/VCheckbox-Dv6fwaDb.56abbfb00c8a.js.br +0 -0
  89. codex/static_root/assets/VCheckbox-Dv6fwaDb.56abbfb00c8a.js.gz +0 -0
  90. codex/static_root/assets/VCheckbox-Dv6fwaDb.js +1 -0
  91. codex/static_root/assets/VCheckbox-Dv6fwaDb.js.br +0 -0
  92. codex/static_root/assets/VCheckbox-Dv6fwaDb.js.gz +0 -0
  93. codex/static_root/assets/VCheckboxBtn-CNMFahfF.4ee9778a562e.js +1 -0
  94. codex/static_root/assets/VCheckboxBtn-CNMFahfF.4ee9778a562e.js.br +0 -0
  95. codex/static_root/assets/VCheckboxBtn-CNMFahfF.4ee9778a562e.js.gz +0 -0
  96. codex/static_root/assets/VCheckboxBtn-CNMFahfF.js +1 -0
  97. codex/static_root/assets/VCheckboxBtn-CNMFahfF.js.br +0 -0
  98. codex/static_root/assets/VCheckboxBtn-CNMFahfF.js.gz +0 -0
  99. codex/static_root/assets/VCombobox-DqBFki-9.2806f95c938d.js +1 -0
  100. codex/static_root/assets/VCombobox-DqBFki-9.2806f95c938d.js.br +0 -0
  101. codex/static_root/assets/VCombobox-DqBFki-9.2806f95c938d.js.gz +0 -0
  102. codex/static_root/assets/VCombobox-DqBFki-9.js +1 -0
  103. codex/static_root/assets/VCombobox-DqBFki-9.js.br +0 -0
  104. codex/static_root/assets/VCombobox-DqBFki-9.js.gz +0 -0
  105. codex/static_root/assets/VDialog-CQXjBvDZ.1a576c5e472f.js +1 -0
  106. codex/static_root/assets/VDialog-CQXjBvDZ.1a576c5e472f.js.br +0 -0
  107. codex/static_root/assets/VDialog-CQXjBvDZ.1a576c5e472f.js.gz +0 -0
  108. codex/static_root/assets/VDialog-CQXjBvDZ.js +1 -0
  109. codex/static_root/assets/VDialog-CQXjBvDZ.js.br +0 -0
  110. codex/static_root/assets/VDialog-CQXjBvDZ.js.gz +0 -0
  111. codex/static_root/assets/VDialog-DWos4S54.b07aca713774.css +1 -0
  112. codex/static_root/assets/VDialog-DWos4S54.b07aca713774.css.br +0 -0
  113. codex/static_root/assets/VDialog-DWos4S54.b07aca713774.css.gz +0 -0
  114. codex/static_root/assets/VDialog-DWos4S54.css +1 -0
  115. codex/static_root/assets/VDialog-DWos4S54.css.br +0 -0
  116. codex/static_root/assets/VDialog-DWos4S54.css.gz +0 -0
  117. codex/static_root/assets/VDivider-DU47sRrT.3d2e17799e5c.css +1 -0
  118. codex/static_root/assets/VDivider-DU47sRrT.3d2e17799e5c.css.br +0 -0
  119. codex/static_root/assets/VDivider-DU47sRrT.3d2e17799e5c.css.gz +0 -0
  120. codex/static_root/assets/VDivider-DU47sRrT.css +1 -0
  121. codex/static_root/assets/VDivider-DU47sRrT.css.br +0 -0
  122. codex/static_root/assets/VDivider-DU47sRrT.css.gz +0 -0
  123. codex/static_root/assets/VDivider-DUxQu-IZ.73d92ae2a07e.js +1 -0
  124. codex/static_root/assets/VDivider-DUxQu-IZ.73d92ae2a07e.js.br +0 -0
  125. codex/static_root/assets/VDivider-DUxQu-IZ.73d92ae2a07e.js.gz +0 -0
  126. codex/static_root/assets/VDivider-DUxQu-IZ.js +1 -0
  127. codex/static_root/assets/VDivider-DUxQu-IZ.js.br +0 -0
  128. codex/static_root/assets/VDivider-DUxQu-IZ.js.gz +0 -0
  129. codex/static_root/assets/VExpansionPanels-BaYzHUJp.5346826103eb.js +1 -0
  130. codex/static_root/assets/VExpansionPanels-BaYzHUJp.5346826103eb.js.br +0 -0
  131. codex/static_root/assets/VExpansionPanels-BaYzHUJp.5346826103eb.js.gz +0 -0
  132. codex/static_root/assets/VExpansionPanels-BaYzHUJp.js +1 -0
  133. codex/static_root/assets/VExpansionPanels-BaYzHUJp.js.br +0 -0
  134. codex/static_root/assets/VExpansionPanels-BaYzHUJp.js.gz +0 -0
  135. codex/static_root/assets/VForm-DxBt30-N.138c0b89b6fc.css +1 -0
  136. codex/static_root/assets/VForm-DxBt30-N.138c0b89b6fc.css.br +0 -0
  137. codex/static_root/assets/VForm-DxBt30-N.138c0b89b6fc.css.gz +0 -0
  138. codex/static_root/assets/VForm-DxBt30-N.css +1 -0
  139. codex/static_root/assets/VForm-DxBt30-N.css.br +0 -0
  140. codex/static_root/assets/VForm-DxBt30-N.css.gz +0 -0
  141. codex/static_root/assets/VForm-hB4C5jVd.a2b90ddcd8ee.js +1 -0
  142. codex/static_root/assets/VForm-hB4C5jVd.a2b90ddcd8ee.js.br +0 -0
  143. codex/static_root/assets/VForm-hB4C5jVd.a2b90ddcd8ee.js.gz +0 -0
  144. codex/static_root/assets/VForm-hB4C5jVd.js +1 -0
  145. codex/static_root/assets/VForm-hB4C5jVd.js.br +0 -0
  146. codex/static_root/assets/VForm-hB4C5jVd.js.gz +0 -0
  147. codex/static_root/assets/VRadioGroup-DOjw38qB.cbf2922d05af.js +1 -0
  148. codex/static_root/assets/VRadioGroup-DOjw38qB.cbf2922d05af.js.br +0 -0
  149. codex/static_root/assets/VRadioGroup-DOjw38qB.cbf2922d05af.js.gz +0 -0
  150. codex/static_root/assets/VRadioGroup-DOjw38qB.js +1 -0
  151. codex/static_root/assets/VRadioGroup-DOjw38qB.js.br +0 -0
  152. codex/static_root/assets/VRadioGroup-DOjw38qB.js.gz +0 -0
  153. codex/static_root/assets/VSelect-CP_CVb8s.6309f7bf17bb.css +1 -0
  154. codex/static_root/assets/VSelect-CP_CVb8s.6309f7bf17bb.css.br +0 -0
  155. codex/static_root/assets/VSelect-CP_CVb8s.6309f7bf17bb.css.gz +0 -0
  156. codex/static_root/assets/VSelect-CP_CVb8s.css +1 -0
  157. codex/static_root/assets/VSelect-CP_CVb8s.css.br +0 -0
  158. codex/static_root/assets/VSelect-CP_CVb8s.css.gz +0 -0
  159. codex/static_root/assets/VSelect-L4v_m3ag.db9fb8348617.js +1 -0
  160. codex/static_root/assets/VSelect-L4v_m3ag.db9fb8348617.js.br +0 -0
  161. codex/static_root/assets/VSelect-L4v_m3ag.db9fb8348617.js.gz +0 -0
  162. codex/static_root/assets/VSelect-L4v_m3ag.js +1 -0
  163. codex/static_root/assets/VSelect-L4v_m3ag.js.br +0 -0
  164. codex/static_root/assets/VSelect-L4v_m3ag.js.gz +0 -0
  165. codex/static_root/assets/VSelectionControl-BqB1JeKa.2fb68a673402.js +1 -0
  166. codex/static_root/assets/VSelectionControl-BqB1JeKa.2fb68a673402.js.br +0 -0
  167. codex/static_root/assets/VSelectionControl-BqB1JeKa.2fb68a673402.js.gz +0 -0
  168. codex/static_root/assets/VSelectionControl-BqB1JeKa.js +1 -0
  169. codex/static_root/assets/VSelectionControl-BqB1JeKa.js.br +0 -0
  170. codex/static_root/assets/VSelectionControl-BqB1JeKa.js.gz +0 -0
  171. codex/static_root/assets/VSelectionControl-DPpfgCW2.cc18de4e83f6.css +1 -0
  172. codex/static_root/assets/VSelectionControl-DPpfgCW2.cc18de4e83f6.css.br +0 -0
  173. codex/static_root/assets/VSelectionControl-DPpfgCW2.cc18de4e83f6.css.gz +0 -0
  174. codex/static_root/assets/VSelectionControl-DPpfgCW2.css +1 -0
  175. codex/static_root/assets/VSelectionControl-DPpfgCW2.css.br +0 -0
  176. codex/static_root/assets/VSelectionControl-DPpfgCW2.css.gz +0 -0
  177. codex/static_root/assets/VTable-CtorAbOx.bbda450cbd73.js +1 -0
  178. codex/static_root/assets/VTable-CtorAbOx.bbda450cbd73.js.br +0 -0
  179. codex/static_root/assets/VTable-CtorAbOx.bbda450cbd73.js.gz +0 -0
  180. codex/static_root/assets/VTable-CtorAbOx.js +1 -0
  181. codex/static_root/assets/VTable-CtorAbOx.js.br +0 -0
  182. codex/static_root/assets/VTable-CtorAbOx.js.gz +0 -0
  183. codex/static_root/assets/VWindowItem-Bl-fa3ss.334e6b813775.js +1 -0
  184. codex/static_root/assets/VWindowItem-Bl-fa3ss.334e6b813775.js.br +0 -0
  185. codex/static_root/assets/VWindowItem-Bl-fa3ss.334e6b813775.js.gz +0 -0
  186. codex/static_root/assets/VWindowItem-Bl-fa3ss.js +1 -0
  187. codex/static_root/assets/VWindowItem-Bl-fa3ss.js.br +0 -0
  188. codex/static_root/assets/VWindowItem-Bl-fa3ss.js.gz +0 -0
  189. codex/static_root/assets/admin-BAVKNREt.23c0966bd683.js +1 -0
  190. codex/static_root/assets/admin-BAVKNREt.23c0966bd683.js.br +0 -0
  191. codex/static_root/assets/admin-BAVKNREt.23c0966bd683.js.gz +0 -0
  192. codex/static_root/assets/admin-BAVKNREt.js +1 -0
  193. codex/static_root/assets/admin-BAVKNREt.js.br +0 -0
  194. codex/static_root/assets/admin-BAVKNREt.js.gz +0 -0
  195. codex/static_root/assets/admin-C3iCIUnm.06cb213f624d.css +1 -0
  196. codex/static_root/assets/admin-C3iCIUnm.06cb213f624d.css.br +0 -0
  197. codex/static_root/assets/admin-C3iCIUnm.06cb213f624d.css.gz +0 -0
  198. codex/static_root/assets/admin-C3iCIUnm.css +1 -0
  199. codex/static_root/assets/admin-C3iCIUnm.css.br +0 -0
  200. codex/static_root/assets/admin-C3iCIUnm.css.gz +0 -0
  201. codex/static_root/assets/admin-CHuFhx_t.a54700f97fc8.js +1 -0
  202. codex/static_root/assets/admin-CHuFhx_t.a54700f97fc8.js.br +0 -0
  203. codex/static_root/assets/admin-CHuFhx_t.a54700f97fc8.js.gz +0 -0
  204. codex/static_root/assets/admin-CHuFhx_t.js +1 -0
  205. codex/static_root/assets/admin-CHuFhx_t.js.br +0 -0
  206. codex/static_root/assets/admin-CHuFhx_t.js.gz +0 -0
  207. codex/static_root/assets/admin-menu-T8WJ_x0C.4f011540bb4c.js +1 -0
  208. codex/static_root/assets/admin-menu-T8WJ_x0C.4f011540bb4c.js.br +0 -0
  209. codex/static_root/assets/admin-menu-T8WJ_x0C.4f011540bb4c.js.gz +0 -0
  210. codex/static_root/assets/admin-menu-T8WJ_x0C.js +1 -0
  211. codex/static_root/assets/admin-menu-T8WJ_x0C.js.br +0 -0
  212. codex/static_root/assets/admin-menu-T8WJ_x0C.js.gz +0 -0
  213. codex/static_root/assets/admin-settings-button-progress-w_CqTSMl.7b36216f68b5.js +1 -0
  214. codex/static_root/assets/admin-settings-button-progress-w_CqTSMl.7b36216f68b5.js.br +0 -0
  215. codex/static_root/assets/admin-settings-button-progress-w_CqTSMl.7b36216f68b5.js.gz +0 -0
  216. codex/static_root/assets/admin-settings-button-progress-w_CqTSMl.js +1 -0
  217. codex/static_root/assets/admin-settings-button-progress-w_CqTSMl.js.br +0 -0
  218. codex/static_root/assets/admin-settings-button-progress-w_CqTSMl.js.gz +0 -0
  219. codex/static_root/assets/browser-DNzQvgkY.aea8b7d7ca40.css +1 -0
  220. codex/static_root/assets/browser-DNzQvgkY.aea8b7d7ca40.css.br +0 -0
  221. codex/static_root/assets/browser-DNzQvgkY.aea8b7d7ca40.css.gz +0 -0
  222. codex/static_root/assets/browser-DNzQvgkY.css +1 -0
  223. codex/static_root/assets/browser-DNzQvgkY.css.br +0 -0
  224. codex/static_root/assets/browser-DNzQvgkY.css.gz +0 -0
  225. codex/static_root/assets/browser-DdLCtUlr.380b79bea4a7.js +1 -0
  226. codex/static_root/assets/browser-DdLCtUlr.380b79bea4a7.js.br +0 -0
  227. codex/static_root/assets/browser-DdLCtUlr.380b79bea4a7.js.gz +0 -0
  228. codex/static_root/assets/browser-DdLCtUlr.js +1 -0
  229. codex/static_root/assets/browser-DdLCtUlr.js.br +0 -0
  230. codex/static_root/assets/browser-DdLCtUlr.js.gz +0 -0
  231. codex/static_root/assets/change-password-dialog-Cy1tU-tj.416ef5bdfd46.js +1 -0
  232. codex/static_root/assets/change-password-dialog-Cy1tU-tj.416ef5bdfd46.js.br +0 -0
  233. codex/static_root/assets/change-password-dialog-Cy1tU-tj.416ef5bdfd46.js.gz +0 -0
  234. codex/static_root/assets/change-password-dialog-Cy1tU-tj.js +1 -0
  235. codex/static_root/assets/change-password-dialog-Cy1tU-tj.js.br +0 -0
  236. codex/static_root/assets/change-password-dialog-Cy1tU-tj.js.gz +0 -0
  237. codex/static_root/assets/confirm-dialog-B_Y3KKiL.1070d18f6b2d.js +1 -0
  238. codex/static_root/assets/confirm-dialog-B_Y3KKiL.1070d18f6b2d.js.br +0 -0
  239. codex/static_root/assets/confirm-dialog-B_Y3KKiL.1070d18f6b2d.js.gz +0 -0
  240. codex/static_root/assets/confirm-dialog-B_Y3KKiL.js +1 -0
  241. codex/static_root/assets/confirm-dialog-B_Y3KKiL.js.br +0 -0
  242. codex/static_root/assets/confirm-dialog-B_Y3KKiL.js.gz +0 -0
  243. codex/static_root/assets/datetime-column-DVC0YqHC.03bb52c198e9.js +1 -0
  244. codex/static_root/assets/datetime-column-DVC0YqHC.03bb52c198e9.js.br +0 -0
  245. codex/static_root/assets/datetime-column-DVC0YqHC.03bb52c198e9.js.gz +0 -0
  246. codex/static_root/assets/datetime-column-DVC0YqHC.js +1 -0
  247. codex/static_root/assets/datetime-column-DVC0YqHC.js.br +0 -0
  248. codex/static_root/assets/datetime-column-DVC0YqHC.js.gz +0 -0
  249. codex/static_root/assets/{filter-ud5mPZpn.0f0a537959aa.js → filter-xcEcgcIx.be1bb4725c89.js} +1 -1
  250. codex/static_root/assets/filter-xcEcgcIx.be1bb4725c89.js.br +0 -0
  251. codex/static_root/assets/filter-xcEcgcIx.be1bb4725c89.js.gz +0 -0
  252. codex/static_root/assets/{filter-ud5mPZpn.js → filter-xcEcgcIx.js} +1 -1
  253. codex/static_root/assets/filter-xcEcgcIx.js.br +0 -0
  254. codex/static_root/assets/filter-xcEcgcIx.js.gz +0 -0
  255. codex/static_root/assets/flag-tab-BOyQb0kr.842fca93f19c.js +1 -0
  256. codex/static_root/assets/flag-tab-BOyQb0kr.842fca93f19c.js.br +0 -0
  257. codex/static_root/assets/flag-tab-BOyQb0kr.842fca93f19c.js.gz +0 -0
  258. codex/static_root/assets/flag-tab-BOyQb0kr.js +1 -0
  259. codex/static_root/assets/flag-tab-BOyQb0kr.js.br +0 -0
  260. codex/static_root/assets/flag-tab-BOyQb0kr.js.gz +0 -0
  261. codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css +1 -0
  262. codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css.br +0 -0
  263. codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css.gz +0 -0
  264. codex/static_root/assets/flag-tab-D2MYXCHk.css +1 -0
  265. codex/static_root/assets/flag-tab-D2MYXCHk.css.br +0 -0
  266. codex/static_root/assets/flag-tab-D2MYXCHk.css.gz +0 -0
  267. codex/static_root/assets/forwardRefs-CFNX6kJ2.9b56b4459240.css +1 -0
  268. codex/static_root/assets/forwardRefs-CFNX6kJ2.9b56b4459240.css.br +0 -0
  269. codex/static_root/assets/forwardRefs-CFNX6kJ2.9b56b4459240.css.gz +0 -0
  270. codex/static_root/assets/forwardRefs-CFNX6kJ2.css +1 -0
  271. codex/static_root/assets/forwardRefs-CFNX6kJ2.css.br +0 -0
  272. codex/static_root/assets/forwardRefs-CFNX6kJ2.css.gz +0 -0
  273. codex/static_root/assets/forwardRefs-D1ZDjzWx.96fccf773093.js +1 -0
  274. codex/static_root/assets/forwardRefs-D1ZDjzWx.96fccf773093.js.br +0 -0
  275. codex/static_root/assets/forwardRefs-D1ZDjzWx.96fccf773093.js.gz +0 -0
  276. codex/static_root/assets/forwardRefs-D1ZDjzWx.js +1 -0
  277. codex/static_root/assets/forwardRefs-D1ZDjzWx.js.br +0 -0
  278. codex/static_root/assets/forwardRefs-D1ZDjzWx.js.gz +0 -0
  279. codex/static_root/assets/group-tab-DkAIGL8z.527cad03c21d.js +1 -0
  280. codex/static_root/assets/group-tab-DkAIGL8z.527cad03c21d.js.br +0 -0
  281. codex/static_root/assets/group-tab-DkAIGL8z.527cad03c21d.js.gz +0 -0
  282. codex/static_root/assets/group-tab-DkAIGL8z.js +1 -0
  283. codex/static_root/assets/group-tab-DkAIGL8z.js.br +0 -0
  284. codex/static_root/assets/group-tab-DkAIGL8z.js.gz +0 -0
  285. codex/static_root/assets/http-error-CODU7jcH.8c13689ae574.css +1 -0
  286. codex/static_root/assets/http-error-CODU7jcH.8c13689ae574.css.br +0 -0
  287. codex/static_root/assets/http-error-CODU7jcH.8c13689ae574.css.gz +0 -0
  288. codex/static_root/assets/http-error-CODU7jcH.css +1 -0
  289. codex/static_root/assets/http-error-CODU7jcH.css.br +0 -0
  290. codex/static_root/assets/http-error-CODU7jcH.css.gz +0 -0
  291. codex/static_root/assets/http-error-CjSb8orc.ad6fc5733ed8.js +1 -0
  292. codex/static_root/assets/http-error-CjSb8orc.ad6fc5733ed8.js.br +0 -0
  293. codex/static_root/assets/http-error-CjSb8orc.ad6fc5733ed8.js.gz +0 -0
  294. codex/static_root/assets/http-error-CjSb8orc.js +1 -0
  295. codex/static_root/assets/http-error-CjSb8orc.js.br +0 -0
  296. codex/static_root/assets/http-error-CjSb8orc.js.gz +0 -0
  297. codex/static_root/assets/index-CoFXW6I0.27f397e1425e.js +1 -0
  298. codex/static_root/assets/index-CoFXW6I0.27f397e1425e.js.br +0 -0
  299. codex/static_root/assets/index-CoFXW6I0.27f397e1425e.js.gz +0 -0
  300. codex/static_root/assets/index-CoFXW6I0.js +1 -0
  301. codex/static_root/assets/index-CoFXW6I0.js.br +0 -0
  302. codex/static_root/assets/index-CoFXW6I0.js.gz +0 -0
  303. codex/static_root/assets/{library-tab-Cat0MAK5.5911f022188e.css → library-tab-CgsXOX_r.75baedb7e976.css} +1 -1
  304. codex/static_root/assets/library-tab-CgsXOX_r.75baedb7e976.css.br +0 -0
  305. codex/static_root/assets/library-tab-CgsXOX_r.75baedb7e976.css.gz +0 -0
  306. codex/static_root/assets/{library-tab-Cat0MAK5.css → library-tab-CgsXOX_r.css} +1 -1
  307. codex/static_root/assets/library-tab-CgsXOX_r.css.br +0 -0
  308. codex/static_root/assets/library-tab-CgsXOX_r.css.gz +0 -0
  309. codex/static_root/assets/library-tab-hkMMBz1x.02270491d822.js +1 -0
  310. codex/static_root/assets/library-tab-hkMMBz1x.02270491d822.js.br +0 -0
  311. codex/static_root/assets/library-tab-hkMMBz1x.02270491d822.js.gz +0 -0
  312. codex/static_root/assets/library-tab-hkMMBz1x.js +1 -0
  313. codex/static_root/assets/library-tab-hkMMBz1x.js.br +0 -0
  314. codex/static_root/assets/library-tab-hkMMBz1x.js.gz +0 -0
  315. codex/static_root/assets/main-DCaPxp2h.076707ddd123.js +35 -0
  316. codex/static_root/assets/main-DCaPxp2h.076707ddd123.js.br +0 -0
  317. codex/static_root/assets/main-DCaPxp2h.076707ddd123.js.gz +0 -0
  318. codex/static_root/assets/main-DCaPxp2h.js +35 -0
  319. codex/static_root/assets/main-DCaPxp2h.js.br +0 -0
  320. codex/static_root/assets/main-DCaPxp2h.js.gz +0 -0
  321. codex/static_root/assets/pager-full-pdf-CwmA9y3l.e7dfdd2a6937.js +1 -0
  322. codex/static_root/assets/pager-full-pdf-CwmA9y3l.e7dfdd2a6937.js.br +0 -0
  323. codex/static_root/assets/pager-full-pdf-CwmA9y3l.e7dfdd2a6937.js.gz +0 -0
  324. codex/static_root/assets/pager-full-pdf-CwmA9y3l.js +1 -0
  325. codex/static_root/assets/pager-full-pdf-CwmA9y3l.js.br +0 -0
  326. codex/static_root/assets/pager-full-pdf-CwmA9y3l.js.gz +0 -0
  327. codex/static_root/assets/pagination-toolbar-D5VQREy5.css +1 -0
  328. codex/static_root/assets/pagination-toolbar-D5VQREy5.css.br +0 -0
  329. codex/static_root/assets/pagination-toolbar-D5VQREy5.css.gz +0 -0
  330. codex/static_root/assets/pagination-toolbar-D5VQREy5.dcb0eba65827.css +1 -0
  331. codex/static_root/assets/pagination-toolbar-D5VQREy5.dcb0eba65827.css.br +0 -0
  332. codex/static_root/assets/pagination-toolbar-D5VQREy5.dcb0eba65827.css.gz +0 -0
  333. codex/static_root/assets/pagination-toolbar-DoqxSygU.f985bc705fe5.js +1 -0
  334. codex/static_root/assets/pagination-toolbar-DoqxSygU.f985bc705fe5.js.br +0 -0
  335. codex/static_root/assets/pagination-toolbar-DoqxSygU.f985bc705fe5.js.gz +0 -0
  336. codex/static_root/assets/pagination-toolbar-DoqxSygU.js +1 -0
  337. codex/static_root/assets/pagination-toolbar-DoqxSygU.js.br +0 -0
  338. codex/static_root/assets/pagination-toolbar-DoqxSygU.js.gz +0 -0
  339. codex/static_root/assets/pdf-doc-BwxvAx1z.96cbc39c321d.js +348 -0
  340. codex/static_root/assets/pdf-doc-BwxvAx1z.96cbc39c321d.js.br +0 -0
  341. codex/static_root/assets/pdf-doc-BwxvAx1z.96cbc39c321d.js.gz +0 -0
  342. codex/static_root/assets/pdf-doc-BwxvAx1z.js +348 -0
  343. codex/static_root/assets/pdf-doc-BwxvAx1z.js.br +0 -0
  344. codex/static_root/assets/pdf-doc-BwxvAx1z.js.gz +0 -0
  345. codex/static_root/assets/{reader-Dd2KmdCN.115d4bfe9280.css → reader-D_3ruSqa.2ed32f08e906.css} +1 -1
  346. codex/static_root/assets/reader-D_3ruSqa.2ed32f08e906.css.br +0 -0
  347. codex/static_root/assets/reader-D_3ruSqa.2ed32f08e906.css.gz +0 -0
  348. codex/static_root/assets/{reader-Dd2KmdCN.css → reader-D_3ruSqa.css} +1 -1
  349. codex/static_root/assets/reader-D_3ruSqa.css.br +0 -0
  350. codex/static_root/assets/reader-D_3ruSqa.css.gz +0 -0
  351. codex/static_root/assets/reader-hHIonVbA.4c12219242a9.js +2 -0
  352. codex/static_root/assets/reader-hHIonVbA.4c12219242a9.js.br +0 -0
  353. codex/static_root/assets/reader-hHIonVbA.4c12219242a9.js.gz +0 -0
  354. codex/static_root/assets/reader-hHIonVbA.js +2 -0
  355. codex/static_root/assets/reader-hHIonVbA.js.br +0 -0
  356. codex/static_root/assets/reader-hHIonVbA.js.gz +0 -0
  357. codex/static_root/assets/relation-chips-D7-5kPem.4443b085aca2.js +1 -0
  358. codex/static_root/assets/relation-chips-D7-5kPem.4443b085aca2.js.br +0 -0
  359. codex/static_root/assets/relation-chips-D7-5kPem.4443b085aca2.js.gz +0 -0
  360. codex/static_root/assets/relation-chips-D7-5kPem.js +1 -0
  361. codex/static_root/assets/relation-chips-D7-5kPem.js.br +0 -0
  362. codex/static_root/assets/relation-chips-D7-5kPem.js.gz +0 -0
  363. codex/static_root/assets/settings-drawer-CdFmOhnd.f7dcd12b3ebc.js +2 -0
  364. codex/static_root/assets/settings-drawer-CdFmOhnd.f7dcd12b3ebc.js.br +0 -0
  365. codex/static_root/assets/settings-drawer-CdFmOhnd.f7dcd12b3ebc.js.gz +0 -0
  366. codex/static_root/assets/settings-drawer-CdFmOhnd.js +2 -0
  367. codex/static_root/assets/settings-drawer-CdFmOhnd.js.br +0 -0
  368. codex/static_root/assets/settings-drawer-CdFmOhnd.js.gz +0 -0
  369. codex/static_root/assets/settings-drawer-DMSsWF8c.75a6ea969e71.css +1 -0
  370. codex/static_root/assets/settings-drawer-DMSsWF8c.75a6ea969e71.css.br +0 -0
  371. codex/static_root/assets/settings-drawer-DMSsWF8c.75a6ea969e71.css.gz +0 -0
  372. codex/static_root/assets/settings-drawer-DMSsWF8c.css +1 -0
  373. codex/static_root/assets/settings-drawer-DMSsWF8c.css.br +0 -0
  374. codex/static_root/assets/settings-drawer-DMSsWF8c.css.gz +0 -0
  375. codex/static_root/assets/stats-tab-BzaipD0m.b6bf627ea860.js +1 -0
  376. codex/static_root/assets/stats-tab-BzaipD0m.b6bf627ea860.js.br +0 -0
  377. codex/static_root/assets/stats-tab-BzaipD0m.b6bf627ea860.js.gz +0 -0
  378. codex/static_root/assets/stats-tab-BzaipD0m.js +1 -0
  379. codex/static_root/assets/stats-tab-BzaipD0m.js.br +0 -0
  380. codex/static_root/assets/stats-tab-BzaipD0m.js.gz +0 -0
  381. codex/static_root/assets/task-tab-DCnS1sM9.44d8435b4989.js +1 -0
  382. codex/static_root/assets/task-tab-DCnS1sM9.44d8435b4989.js.br +0 -0
  383. codex/static_root/assets/task-tab-DCnS1sM9.44d8435b4989.js.gz +0 -0
  384. codex/static_root/assets/task-tab-DCnS1sM9.js +1 -0
  385. codex/static_root/assets/task-tab-DCnS1sM9.js.br +0 -0
  386. codex/static_root/assets/task-tab-DCnS1sM9.js.gz +0 -0
  387. codex/static_root/assets/unauthorized-CsSak07X.c5536d9dae75.css +1 -0
  388. codex/static_root/assets/unauthorized-CsSak07X.c5536d9dae75.css.br +0 -0
  389. codex/static_root/assets/unauthorized-CsSak07X.c5536d9dae75.css.gz +0 -0
  390. codex/static_root/assets/unauthorized-CsSak07X.css +1 -0
  391. codex/static_root/assets/unauthorized-CsSak07X.css.br +0 -0
  392. codex/static_root/assets/unauthorized-CsSak07X.css.gz +0 -0
  393. codex/static_root/assets/unauthorized-DJSr03Dw.7555cbcf1064.js +1 -0
  394. codex/static_root/assets/unauthorized-DJSr03Dw.7555cbcf1064.js.br +0 -0
  395. codex/static_root/assets/unauthorized-DJSr03Dw.7555cbcf1064.js.gz +0 -0
  396. codex/static_root/assets/unauthorized-DJSr03Dw.js +1 -0
  397. codex/static_root/assets/unauthorized-DJSr03Dw.js.br +0 -0
  398. codex/static_root/assets/unauthorized-DJSr03Dw.js.gz +0 -0
  399. codex/static_root/assets/user-tab-DAK_Deoh.1832877d449a.js +1 -0
  400. codex/static_root/assets/user-tab-DAK_Deoh.1832877d449a.js.br +0 -0
  401. codex/static_root/assets/user-tab-DAK_Deoh.1832877d449a.js.gz +0 -0
  402. codex/static_root/assets/user-tab-DAK_Deoh.js +1 -0
  403. codex/static_root/assets/user-tab-DAK_Deoh.js.br +0 -0
  404. codex/static_root/assets/user-tab-DAK_Deoh.js.gz +0 -0
  405. codex/static_root/manifest.cbc39bca88fc.json +735 -0
  406. codex/static_root/manifest.cbc39bca88fc.json.br +0 -0
  407. codex/static_root/manifest.cbc39bca88fc.json.gz +0 -0
  408. codex/static_root/manifest.json +388 -365
  409. codex/static_root/manifest.json.br +0 -0
  410. codex/static_root/manifest.json.gz +0 -0
  411. codex/static_root/staticfiles.json +1 -1
  412. codex/status_controller.py +9 -12
  413. codex/templates/index.html +1 -1
  414. codex/threads.py +3 -3
  415. codex/urls/api/admin.py +4 -3
  416. codex/urls/api/browser.py +1 -1
  417. codex/urls/opds/v2.py +6 -0
  418. codex/urls/root.py +4 -3
  419. codex/views/admin/api_key.py +1 -4
  420. codex/views/admin/flag.py +5 -1
  421. codex/views/admin/library.py +4 -4
  422. codex/views/admin/stats.py +10 -10
  423. codex/views/admin/tasks.py +9 -9
  424. codex/views/auth.py +3 -8
  425. codex/views/bookmark.py +53 -41
  426. codex/views/browser/annotate/bookmark.py +6 -4
  427. codex/views/browser/annotate/card.py +3 -18
  428. codex/views/browser/annotate/order.py +51 -25
  429. codex/views/browser/bookmark.py +53 -0
  430. codex/views/browser/breadcrumbs.py +6 -5
  431. codex/views/browser/browser.py +2 -2
  432. codex/views/browser/choices.py +6 -5
  433. codex/views/browser/cover.py +6 -3
  434. codex/views/browser/download.py +4 -1
  435. codex/views/browser/filters/bookmark.py +5 -33
  436. codex/views/browser/filters/field.py +1 -1
  437. codex/views/browser/filters/filter.py +6 -8
  438. codex/views/browser/filters/group.py +5 -4
  439. codex/views/browser/filters/search/field/expression.py +1 -2
  440. codex/views/browser/filters/search/field/optimize.py +1 -1
  441. codex/views/browser/filters/search/field/parse.py +2 -2
  442. codex/views/browser/filters/search/parse.py +4 -19
  443. codex/views/browser/group_mtime.py +3 -3
  444. codex/views/browser/metadata/annotate.py +1 -1
  445. codex/views/browser/metadata/copy_intersections.py +1 -1
  446. codex/views/browser/metadata/metadata.py +2 -2
  447. codex/views/browser/mtime.py +1 -1
  448. codex/views/browser/order_by.py +9 -6
  449. codex/views/browser/params.py +1 -1
  450. codex/views/browser/settings.py +1 -1
  451. codex/views/browser/validate.py +8 -5
  452. codex/views/const.py +0 -3
  453. codex/views/frontend.py +20 -5
  454. codex/views/mixins.py +19 -30
  455. codex/views/opds/authentication_v1.py +1 -1
  456. codex/views/opds/const.py +6 -4
  457. codex/views/opds/util.py +5 -5
  458. codex/views/opds/v1/entry/entry.py +4 -2
  459. codex/views/opds/v1/entry/links.py +5 -7
  460. codex/views/opds/v1/facets.py +8 -4
  461. codex/views/opds/v1/feed.py +5 -5
  462. codex/views/opds/v1/links.py +11 -6
  463. codex/views/opds/v2/const.py +5 -2
  464. codex/views/opds/v2/feed.py +6 -5
  465. codex/views/opds/v2/href.py +60 -0
  466. codex/views/opds/v2/links.py +13 -47
  467. codex/views/opds/v2/progression.py +136 -0
  468. codex/views/opds/v2/publications.py +31 -21
  469. codex/views/opds/v2/top_links.py +2 -1
  470. codex/views/public.py +12 -5
  471. codex/views/reader/books.py +22 -10
  472. codex/views/reader/page.py +8 -8
  473. codex/views/reader/params.py +2 -2
  474. codex/views/reader/reader.py +6 -6
  475. codex/views/reader/settings.py +1 -1
  476. codex/views/session.py +8 -2
  477. codex/views/settings.py +2 -2
  478. codex/views/timezone.py +2 -2
  479. codex/views/util.py +10 -9
  480. codex/views/version.py +1 -1
  481. {codex-1.7.2.dist-info → codex-1.7.3.dist-info}/METADATA +21 -26
  482. codex-1.7.3.dist-info/RECORD +1031 -0
  483. {codex-1.7.2.dist-info → codex-1.7.3.dist-info}/WHEEL +1 -1
  484. codex/serializers/opds/v2.py +0 -178
  485. codex/static_root/assets/VCheckbox-DLMzIII1.1ff8fc2d9a21.js +0 -1
  486. codex/static_root/assets/VCheckbox-DLMzIII1.1ff8fc2d9a21.js.br +0 -0
  487. codex/static_root/assets/VCheckbox-DLMzIII1.1ff8fc2d9a21.js.gz +0 -0
  488. codex/static_root/assets/VCheckbox-DLMzIII1.js +0 -1
  489. codex/static_root/assets/VCheckbox-DLMzIII1.js.br +0 -0
  490. codex/static_root/assets/VCheckbox-DLMzIII1.js.gz +0 -0
  491. codex/static_root/assets/VCheckboxBtn-BzoQl8XC.094679a3624b.js +0 -1
  492. codex/static_root/assets/VCheckboxBtn-BzoQl8XC.094679a3624b.js.br +0 -0
  493. codex/static_root/assets/VCheckboxBtn-BzoQl8XC.094679a3624b.js.gz +0 -0
  494. codex/static_root/assets/VCheckboxBtn-BzoQl8XC.js +0 -1
  495. codex/static_root/assets/VCheckboxBtn-BzoQl8XC.js.br +0 -0
  496. codex/static_root/assets/VCheckboxBtn-BzoQl8XC.js.gz +0 -0
  497. codex/static_root/assets/VCombobox-CBY8K5CP.fcf2221a9edd.js +0 -1
  498. codex/static_root/assets/VCombobox-CBY8K5CP.fcf2221a9edd.js.br +0 -0
  499. codex/static_root/assets/VCombobox-CBY8K5CP.fcf2221a9edd.js.gz +0 -0
  500. codex/static_root/assets/VCombobox-CBY8K5CP.js +0 -1
  501. codex/static_root/assets/VCombobox-CBY8K5CP.js.br +0 -0
  502. codex/static_root/assets/VCombobox-CBY8K5CP.js.gz +0 -0
  503. codex/static_root/assets/VDialog-DXQz0Ylp.7b23d86dbd0d.css +0 -1
  504. codex/static_root/assets/VDialog-DXQz0Ylp.7b23d86dbd0d.css.br +0 -0
  505. codex/static_root/assets/VDialog-DXQz0Ylp.7b23d86dbd0d.css.gz +0 -0
  506. codex/static_root/assets/VDialog-DXQz0Ylp.css +0 -1
  507. codex/static_root/assets/VDialog-DXQz0Ylp.css.br +0 -0
  508. codex/static_root/assets/VDialog-DXQz0Ylp.css.gz +0 -0
  509. codex/static_root/assets/VDialog-Db4tJYqR.e21a79a5030e.js +0 -1
  510. codex/static_root/assets/VDialog-Db4tJYqR.e21a79a5030e.js.br +0 -0
  511. codex/static_root/assets/VDialog-Db4tJYqR.e21a79a5030e.js.gz +0 -0
  512. codex/static_root/assets/VDialog-Db4tJYqR.js +0 -1
  513. codex/static_root/assets/VDialog-Db4tJYqR.js.br +0 -0
  514. codex/static_root/assets/VDialog-Db4tJYqR.js.gz +0 -0
  515. codex/static_root/assets/VExpansionPanels-DN4yGbOt.163e59e38865.js +0 -1
  516. codex/static_root/assets/VExpansionPanels-DN4yGbOt.163e59e38865.js.br +0 -0
  517. codex/static_root/assets/VExpansionPanels-DN4yGbOt.163e59e38865.js.gz +0 -0
  518. codex/static_root/assets/VExpansionPanels-DN4yGbOt.js +0 -1
  519. codex/static_root/assets/VExpansionPanels-DN4yGbOt.js.br +0 -0
  520. codex/static_root/assets/VExpansionPanels-DN4yGbOt.js.gz +0 -0
  521. codex/static_root/assets/VRadioGroup-D2-PWEfs.ce7644863c25.js +0 -1
  522. codex/static_root/assets/VRadioGroup-D2-PWEfs.ce7644863c25.js.br +0 -0
  523. codex/static_root/assets/VRadioGroup-D2-PWEfs.ce7644863c25.js.gz +0 -0
  524. codex/static_root/assets/VRadioGroup-D2-PWEfs.js +0 -1
  525. codex/static_root/assets/VRadioGroup-D2-PWEfs.js.br +0 -0
  526. codex/static_root/assets/VRadioGroup-D2-PWEfs.js.gz +0 -0
  527. codex/static_root/assets/VSelect-DLu8bpcs.98bdcf35411c.css +0 -1
  528. codex/static_root/assets/VSelect-DLu8bpcs.98bdcf35411c.css.br +0 -0
  529. codex/static_root/assets/VSelect-DLu8bpcs.98bdcf35411c.css.gz +0 -0
  530. codex/static_root/assets/VSelect-DLu8bpcs.css +0 -1
  531. codex/static_root/assets/VSelect-DLu8bpcs.css.br +0 -0
  532. codex/static_root/assets/VSelect-DLu8bpcs.css.gz +0 -0
  533. codex/static_root/assets/VSelect-DqXJ23Pc.a1360cbed050.js +0 -1
  534. codex/static_root/assets/VSelect-DqXJ23Pc.a1360cbed050.js.br +0 -0
  535. codex/static_root/assets/VSelect-DqXJ23Pc.a1360cbed050.js.gz +0 -0
  536. codex/static_root/assets/VSelect-DqXJ23Pc.js +0 -1
  537. codex/static_root/assets/VSelect-DqXJ23Pc.js.br +0 -0
  538. codex/static_root/assets/VSelect-DqXJ23Pc.js.gz +0 -0
  539. codex/static_root/assets/VSelectionControl-CiViEYoC.c77bb19a4a06.css +0 -1
  540. codex/static_root/assets/VSelectionControl-CiViEYoC.c77bb19a4a06.css.br +0 -0
  541. codex/static_root/assets/VSelectionControl-CiViEYoC.c77bb19a4a06.css.gz +0 -0
  542. codex/static_root/assets/VSelectionControl-CiViEYoC.css +0 -1
  543. codex/static_root/assets/VSelectionControl-CiViEYoC.css.br +0 -0
  544. codex/static_root/assets/VSelectionControl-CiViEYoC.css.gz +0 -0
  545. codex/static_root/assets/VSelectionControl-CxhDNufT.dd7ca99567fc.js +0 -1
  546. codex/static_root/assets/VSelectionControl-CxhDNufT.dd7ca99567fc.js.br +0 -0
  547. codex/static_root/assets/VSelectionControl-CxhDNufT.dd7ca99567fc.js.gz +0 -0
  548. codex/static_root/assets/VSelectionControl-CxhDNufT.js +0 -1
  549. codex/static_root/assets/VSelectionControl-CxhDNufT.js.br +0 -0
  550. codex/static_root/assets/VSelectionControl-CxhDNufT.js.gz +0 -0
  551. codex/static_root/assets/VSlideGroup-BtXPhMOT.830f136ffd41.css +0 -1
  552. codex/static_root/assets/VSlideGroup-BtXPhMOT.830f136ffd41.css.br +0 -0
  553. codex/static_root/assets/VSlideGroup-BtXPhMOT.830f136ffd41.css.gz +0 -0
  554. codex/static_root/assets/VSlideGroup-BtXPhMOT.css +0 -1
  555. codex/static_root/assets/VSlideGroup-BtXPhMOT.css.br +0 -0
  556. codex/static_root/assets/VSlideGroup-BtXPhMOT.css.gz +0 -0
  557. codex/static_root/assets/VSlideGroup-DRbthp6q.7365c5542d47.js +0 -1
  558. codex/static_root/assets/VSlideGroup-DRbthp6q.7365c5542d47.js.br +0 -0
  559. codex/static_root/assets/VSlideGroup-DRbthp6q.7365c5542d47.js.gz +0 -0
  560. codex/static_root/assets/VSlideGroup-DRbthp6q.js +0 -1
  561. codex/static_root/assets/VSlideGroup-DRbthp6q.js.br +0 -0
  562. codex/static_root/assets/VSlideGroup-DRbthp6q.js.gz +0 -0
  563. codex/static_root/assets/VTable-Cbq-yJos.c884706cac21.js +0 -1
  564. codex/static_root/assets/VTable-Cbq-yJos.c884706cac21.js.br +0 -0
  565. codex/static_root/assets/VTable-Cbq-yJos.c884706cac21.js.gz +0 -0
  566. codex/static_root/assets/VTable-Cbq-yJos.js +0 -1
  567. codex/static_root/assets/VTable-Cbq-yJos.js.br +0 -0
  568. codex/static_root/assets/VTable-Cbq-yJos.js.gz +0 -0
  569. codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css +0 -1
  570. codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css.br +0 -0
  571. codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css.gz +0 -0
  572. codex/static_root/assets/VTextField-Crc3gdNh.css +0 -1
  573. codex/static_root/assets/VTextField-Crc3gdNh.css.br +0 -0
  574. codex/static_root/assets/VTextField-Crc3gdNh.css.gz +0 -0
  575. codex/static_root/assets/VTextField-X5yAw35c.155e276dd747.js +0 -1
  576. codex/static_root/assets/VTextField-X5yAw35c.155e276dd747.js.br +0 -0
  577. codex/static_root/assets/VTextField-X5yAw35c.155e276dd747.js.gz +0 -0
  578. codex/static_root/assets/VTextField-X5yAw35c.js +0 -1
  579. codex/static_root/assets/VTextField-X5yAw35c.js.br +0 -0
  580. codex/static_root/assets/VTextField-X5yAw35c.js.gz +0 -0
  581. codex/static_root/assets/VWindowItem-CRqhVh-9.cd73d01e0591.js +0 -1
  582. codex/static_root/assets/VWindowItem-CRqhVh-9.cd73d01e0591.js.br +0 -0
  583. codex/static_root/assets/VWindowItem-CRqhVh-9.cd73d01e0591.js.gz +0 -0
  584. codex/static_root/assets/VWindowItem-CRqhVh-9.js +0 -1
  585. codex/static_root/assets/VWindowItem-CRqhVh-9.js.br +0 -0
  586. codex/static_root/assets/VWindowItem-CRqhVh-9.js.gz +0 -0
  587. codex/static_root/assets/admin-BFvQwinN.6cfff21f780a.js +0 -1
  588. codex/static_root/assets/admin-BFvQwinN.6cfff21f780a.js.br +0 -0
  589. codex/static_root/assets/admin-BFvQwinN.6cfff21f780a.js.gz +0 -0
  590. codex/static_root/assets/admin-BFvQwinN.js +0 -1
  591. codex/static_root/assets/admin-BFvQwinN.js.br +0 -0
  592. codex/static_root/assets/admin-BFvQwinN.js.gz +0 -0
  593. codex/static_root/assets/admin-DJ7pIXDQ.css +0 -1
  594. codex/static_root/assets/admin-DJ7pIXDQ.css.br +0 -0
  595. codex/static_root/assets/admin-DJ7pIXDQ.css.gz +0 -0
  596. codex/static_root/assets/admin-DJ7pIXDQ.e2a77af73ef2.css +0 -1
  597. codex/static_root/assets/admin-DJ7pIXDQ.e2a77af73ef2.css.br +0 -0
  598. codex/static_root/assets/admin-DJ7pIXDQ.e2a77af73ef2.css.gz +0 -0
  599. codex/static_root/assets/admin-menu-Jfmp_Yd8.39fa7a18b3b4.js +0 -1
  600. codex/static_root/assets/admin-menu-Jfmp_Yd8.39fa7a18b3b4.js.br +0 -0
  601. codex/static_root/assets/admin-menu-Jfmp_Yd8.39fa7a18b3b4.js.gz +0 -0
  602. codex/static_root/assets/admin-menu-Jfmp_Yd8.js +0 -1
  603. codex/static_root/assets/admin-menu-Jfmp_Yd8.js.br +0 -0
  604. codex/static_root/assets/admin-menu-Jfmp_Yd8.js.gz +0 -0
  605. codex/static_root/assets/admin-settings-button-progress-BAk-B1sR.cbf73c71330d.js +0 -1
  606. codex/static_root/assets/admin-settings-button-progress-BAk-B1sR.cbf73c71330d.js.br +0 -0
  607. codex/static_root/assets/admin-settings-button-progress-BAk-B1sR.cbf73c71330d.js.gz +0 -0
  608. codex/static_root/assets/admin-settings-button-progress-BAk-B1sR.js +0 -1
  609. codex/static_root/assets/admin-settings-button-progress-BAk-B1sR.js.br +0 -0
  610. codex/static_root/assets/admin-settings-button-progress-BAk-B1sR.js.gz +0 -0
  611. codex/static_root/assets/browser-CctlSJji.css +0 -1
  612. codex/static_root/assets/browser-CctlSJji.css.br +0 -0
  613. codex/static_root/assets/browser-CctlSJji.css.gz +0 -0
  614. codex/static_root/assets/browser-CctlSJji.d42d796476d2.css +0 -1
  615. codex/static_root/assets/browser-CctlSJji.d42d796476d2.css.br +0 -0
  616. codex/static_root/assets/browser-CctlSJji.d42d796476d2.css.gz +0 -0
  617. codex/static_root/assets/browser-DJnEeVHz.a78c47516b08.js +0 -1
  618. codex/static_root/assets/browser-DJnEeVHz.a78c47516b08.js.br +0 -0
  619. codex/static_root/assets/browser-DJnEeVHz.a78c47516b08.js.gz +0 -0
  620. codex/static_root/assets/browser-DJnEeVHz.js +0 -1
  621. codex/static_root/assets/browser-DJnEeVHz.js.br +0 -0
  622. codex/static_root/assets/browser-DJnEeVHz.js.gz +0 -0
  623. codex/static_root/assets/change-password-dialog-DJtOQw7K.be7fa5ec653d.js +0 -1
  624. codex/static_root/assets/change-password-dialog-DJtOQw7K.be7fa5ec653d.js.br +0 -0
  625. codex/static_root/assets/change-password-dialog-DJtOQw7K.be7fa5ec653d.js.gz +0 -0
  626. codex/static_root/assets/change-password-dialog-DJtOQw7K.js +0 -1
  627. codex/static_root/assets/change-password-dialog-DJtOQw7K.js.br +0 -0
  628. codex/static_root/assets/change-password-dialog-DJtOQw7K.js.gz +0 -0
  629. codex/static_root/assets/confirm-dialog-CME4gKSZ.1606233e784c.js +0 -1
  630. codex/static_root/assets/confirm-dialog-CME4gKSZ.1606233e784c.js.br +0 -0
  631. codex/static_root/assets/confirm-dialog-CME4gKSZ.1606233e784c.js.gz +0 -0
  632. codex/static_root/assets/confirm-dialog-CME4gKSZ.js +0 -1
  633. codex/static_root/assets/confirm-dialog-CME4gKSZ.js.br +0 -0
  634. codex/static_root/assets/confirm-dialog-CME4gKSZ.js.gz +0 -0
  635. codex/static_root/assets/datetime-column-D_F30OLW.09cdce0ef96e.js +0 -1
  636. codex/static_root/assets/datetime-column-D_F30OLW.09cdce0ef96e.js.br +0 -2
  637. codex/static_root/assets/datetime-column-D_F30OLW.09cdce0ef96e.js.gz +0 -0
  638. codex/static_root/assets/datetime-column-D_F30OLW.js +0 -1
  639. codex/static_root/assets/datetime-column-D_F30OLW.js.br +0 -2
  640. codex/static_root/assets/datetime-column-D_F30OLW.js.gz +0 -0
  641. codex/static_root/assets/filter-ud5mPZpn.0f0a537959aa.js.br +0 -0
  642. codex/static_root/assets/filter-ud5mPZpn.0f0a537959aa.js.gz +0 -0
  643. codex/static_root/assets/filter-ud5mPZpn.js.br +0 -0
  644. codex/static_root/assets/filter-ud5mPZpn.js.gz +0 -0
  645. codex/static_root/assets/flag-tab-CqWovuBu.4dfc6b251e85.css +0 -1
  646. codex/static_root/assets/flag-tab-CqWovuBu.4dfc6b251e85.css.br +0 -0
  647. codex/static_root/assets/flag-tab-CqWovuBu.4dfc6b251e85.css.gz +0 -0
  648. codex/static_root/assets/flag-tab-CqWovuBu.css +0 -1
  649. codex/static_root/assets/flag-tab-CqWovuBu.css.br +0 -0
  650. codex/static_root/assets/flag-tab-CqWovuBu.css.gz +0 -0
  651. codex/static_root/assets/flag-tab-k2g6u_vi.3e1da9318af9.js +0 -1
  652. codex/static_root/assets/flag-tab-k2g6u_vi.3e1da9318af9.js.br +0 -0
  653. codex/static_root/assets/flag-tab-k2g6u_vi.3e1da9318af9.js.gz +0 -0
  654. codex/static_root/assets/flag-tab-k2g6u_vi.js +0 -1
  655. codex/static_root/assets/flag-tab-k2g6u_vi.js.br +0 -0
  656. codex/static_root/assets/flag-tab-k2g6u_vi.js.gz +0 -0
  657. codex/static_root/assets/group-tab-C6Ykf03Z.ff0cc204013a.js +0 -1
  658. codex/static_root/assets/group-tab-C6Ykf03Z.ff0cc204013a.js.br +0 -0
  659. codex/static_root/assets/group-tab-C6Ykf03Z.ff0cc204013a.js.gz +0 -0
  660. codex/static_root/assets/group-tab-C6Ykf03Z.js +0 -1
  661. codex/static_root/assets/group-tab-C6Ykf03Z.js.br +0 -0
  662. codex/static_root/assets/group-tab-C6Ykf03Z.js.gz +0 -0
  663. codex/static_root/assets/http-error-Ctcws1xe.cfd378a792d2.css +0 -1
  664. codex/static_root/assets/http-error-Ctcws1xe.cfd378a792d2.css.br +0 -0
  665. codex/static_root/assets/http-error-Ctcws1xe.cfd378a792d2.css.gz +0 -0
  666. codex/static_root/assets/http-error-Ctcws1xe.css +0 -1
  667. codex/static_root/assets/http-error-Ctcws1xe.css.br +0 -0
  668. codex/static_root/assets/http-error-Ctcws1xe.css.gz +0 -0
  669. codex/static_root/assets/http-error-DQBHK8v5.aea50b1327fd.js +0 -1
  670. codex/static_root/assets/http-error-DQBHK8v5.aea50b1327fd.js.br +0 -0
  671. codex/static_root/assets/http-error-DQBHK8v5.aea50b1327fd.js.gz +0 -0
  672. codex/static_root/assets/http-error-DQBHK8v5.js +0 -1
  673. codex/static_root/assets/http-error-DQBHK8v5.js.br +0 -0
  674. codex/static_root/assets/http-error-DQBHK8v5.js.gz +0 -0
  675. codex/static_root/assets/index-ClGiHwWc.0717bacf5135.js +0 -1
  676. codex/static_root/assets/index-ClGiHwWc.0717bacf5135.js.br +0 -0
  677. codex/static_root/assets/index-ClGiHwWc.0717bacf5135.js.gz +0 -0
  678. codex/static_root/assets/index-ClGiHwWc.js +0 -1
  679. codex/static_root/assets/index-ClGiHwWc.js.br +0 -0
  680. codex/static_root/assets/index-ClGiHwWc.js.gz +0 -0
  681. codex/static_root/assets/library-tab-BpinbqAu.53fa2625e727.js +0 -1
  682. codex/static_root/assets/library-tab-BpinbqAu.53fa2625e727.js.br +0 -0
  683. codex/static_root/assets/library-tab-BpinbqAu.53fa2625e727.js.gz +0 -0
  684. codex/static_root/assets/library-tab-BpinbqAu.js +0 -1
  685. codex/static_root/assets/library-tab-BpinbqAu.js.br +0 -0
  686. codex/static_root/assets/library-tab-BpinbqAu.js.gz +0 -0
  687. codex/static_root/assets/library-tab-Cat0MAK5.5911f022188e.css.br +0 -0
  688. codex/static_root/assets/library-tab-Cat0MAK5.5911f022188e.css.gz +0 -0
  689. codex/static_root/assets/library-tab-Cat0MAK5.css.br +0 -0
  690. codex/static_root/assets/library-tab-Cat0MAK5.css.gz +0 -0
  691. codex/static_root/assets/main-BVKrDunc.1c6f8cdc3afb.js +0 -35
  692. codex/static_root/assets/main-BVKrDunc.1c6f8cdc3afb.js.br +0 -0
  693. codex/static_root/assets/main-BVKrDunc.1c6f8cdc3afb.js.gz +0 -0
  694. codex/static_root/assets/main-BVKrDunc.js +0 -35
  695. codex/static_root/assets/main-BVKrDunc.js.br +0 -0
  696. codex/static_root/assets/main-BVKrDunc.js.gz +0 -0
  697. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.f2e95b19621c.js +0 -1
  698. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.f2e95b19621c.js.br +0 -0
  699. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.f2e95b19621c.js.gz +0 -0
  700. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.js +0 -1
  701. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.js.br +0 -0
  702. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.js.gz +0 -0
  703. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.546121fa7a0d.css +0 -1
  704. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.546121fa7a0d.css.br +0 -0
  705. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.546121fa7a0d.css.gz +0 -0
  706. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.css +0 -1
  707. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.css.br +0 -0
  708. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.css.gz +0 -0
  709. codex/static_root/assets/pagination-toolbar-Diad0EdD.140911bf86af.js +0 -1
  710. codex/static_root/assets/pagination-toolbar-Diad0EdD.140911bf86af.js.br +0 -0
  711. codex/static_root/assets/pagination-toolbar-Diad0EdD.140911bf86af.js.gz +0 -0
  712. codex/static_root/assets/pagination-toolbar-Diad0EdD.js +0 -1
  713. codex/static_root/assets/pagination-toolbar-Diad0EdD.js.br +0 -0
  714. codex/static_root/assets/pagination-toolbar-Diad0EdD.js.gz +0 -0
  715. codex/static_root/assets/pdf-doc-b-GyNR6z.c9d18f0d36ed.js +0 -305
  716. codex/static_root/assets/pdf-doc-b-GyNR6z.c9d18f0d36ed.js.br +0 -0
  717. codex/static_root/assets/pdf-doc-b-GyNR6z.c9d18f0d36ed.js.gz +0 -0
  718. codex/static_root/assets/pdf-doc-b-GyNR6z.js +0 -305
  719. codex/static_root/assets/pdf-doc-b-GyNR6z.js.br +0 -0
  720. codex/static_root/assets/pdf-doc-b-GyNR6z.js.gz +0 -0
  721. codex/static_root/assets/reader-2up6WEuE.c56ad81d14c6.js +0 -2
  722. codex/static_root/assets/reader-2up6WEuE.c56ad81d14c6.js.br +0 -0
  723. codex/static_root/assets/reader-2up6WEuE.c56ad81d14c6.js.gz +0 -0
  724. codex/static_root/assets/reader-2up6WEuE.js +0 -2
  725. codex/static_root/assets/reader-2up6WEuE.js.br +0 -0
  726. codex/static_root/assets/reader-2up6WEuE.js.gz +0 -0
  727. codex/static_root/assets/reader-Dd2KmdCN.115d4bfe9280.css.br +0 -0
  728. codex/static_root/assets/reader-Dd2KmdCN.115d4bfe9280.css.gz +0 -0
  729. codex/static_root/assets/reader-Dd2KmdCN.css.br +0 -0
  730. codex/static_root/assets/reader-Dd2KmdCN.css.gz +0 -0
  731. codex/static_root/assets/relation-chips-piYv1IcD.f8a2ae79de89.js +0 -1
  732. codex/static_root/assets/relation-chips-piYv1IcD.f8a2ae79de89.js.br +0 -0
  733. codex/static_root/assets/relation-chips-piYv1IcD.f8a2ae79de89.js.gz +0 -0
  734. codex/static_root/assets/relation-chips-piYv1IcD.js +0 -1
  735. codex/static_root/assets/relation-chips-piYv1IcD.js.br +0 -0
  736. codex/static_root/assets/relation-chips-piYv1IcD.js.gz +0 -0
  737. codex/static_root/assets/settings-drawer-DKncO_vX.0a2cd24cd904.css +0 -1
  738. codex/static_root/assets/settings-drawer-DKncO_vX.0a2cd24cd904.css.br +0 -0
  739. codex/static_root/assets/settings-drawer-DKncO_vX.0a2cd24cd904.css.gz +0 -0
  740. codex/static_root/assets/settings-drawer-DKncO_vX.css +0 -1
  741. codex/static_root/assets/settings-drawer-DKncO_vX.css.br +0 -0
  742. codex/static_root/assets/settings-drawer-DKncO_vX.css.gz +0 -0
  743. codex/static_root/assets/settings-drawer-yVoY-WCS.1240cc47a246.js +0 -2
  744. codex/static_root/assets/settings-drawer-yVoY-WCS.1240cc47a246.js.br +0 -0
  745. codex/static_root/assets/settings-drawer-yVoY-WCS.1240cc47a246.js.gz +0 -0
  746. codex/static_root/assets/settings-drawer-yVoY-WCS.js +0 -2
  747. codex/static_root/assets/settings-drawer-yVoY-WCS.js.br +0 -0
  748. codex/static_root/assets/settings-drawer-yVoY-WCS.js.gz +0 -0
  749. codex/static_root/assets/stats-tab-bqSPLvTp.05106cb03ef0.js +0 -1
  750. codex/static_root/assets/stats-tab-bqSPLvTp.05106cb03ef0.js.br +0 -0
  751. codex/static_root/assets/stats-tab-bqSPLvTp.05106cb03ef0.js.gz +0 -0
  752. codex/static_root/assets/stats-tab-bqSPLvTp.js +0 -1
  753. codex/static_root/assets/stats-tab-bqSPLvTp.js.br +0 -0
  754. codex/static_root/assets/stats-tab-bqSPLvTp.js.gz +0 -0
  755. codex/static_root/assets/task-tab-DWPKaGPT.da4df28dde5c.js +0 -1
  756. codex/static_root/assets/task-tab-DWPKaGPT.da4df28dde5c.js.br +0 -0
  757. codex/static_root/assets/task-tab-DWPKaGPT.da4df28dde5c.js.gz +0 -0
  758. codex/static_root/assets/task-tab-DWPKaGPT.js +0 -1
  759. codex/static_root/assets/task-tab-DWPKaGPT.js.br +0 -0
  760. codex/static_root/assets/task-tab-DWPKaGPT.js.gz +0 -0
  761. codex/static_root/assets/transition-5LRFTPo5.3d726f9bbcb0.css +0 -1
  762. codex/static_root/assets/transition-5LRFTPo5.3d726f9bbcb0.css.br +0 -4
  763. codex/static_root/assets/transition-5LRFTPo5.3d726f9bbcb0.css.gz +0 -0
  764. codex/static_root/assets/transition-5LRFTPo5.css +0 -1
  765. codex/static_root/assets/transition-5LRFTPo5.css.br +0 -4
  766. codex/static_root/assets/transition-5LRFTPo5.css.gz +0 -0
  767. codex/static_root/assets/transition-DWVQ2EZ3.0bdfaa37b937.js +0 -1
  768. codex/static_root/assets/transition-DWVQ2EZ3.0bdfaa37b937.js.br +0 -0
  769. codex/static_root/assets/transition-DWVQ2EZ3.0bdfaa37b937.js.gz +0 -0
  770. codex/static_root/assets/transition-DWVQ2EZ3.js +0 -1
  771. codex/static_root/assets/transition-DWVQ2EZ3.js.br +0 -0
  772. codex/static_root/assets/transition-DWVQ2EZ3.js.gz +0 -0
  773. codex/static_root/assets/unauthorized-CEGD20tR.064b0993a944.js +0 -1
  774. codex/static_root/assets/unauthorized-CEGD20tR.064b0993a944.js.br +0 -0
  775. codex/static_root/assets/unauthorized-CEGD20tR.064b0993a944.js.gz +0 -0
  776. codex/static_root/assets/unauthorized-CEGD20tR.js +0 -1
  777. codex/static_root/assets/unauthorized-CEGD20tR.js.br +0 -0
  778. codex/static_root/assets/unauthorized-CEGD20tR.js.gz +0 -0
  779. codex/static_root/assets/unauthorized-DyojW2ic.css +0 -1
  780. codex/static_root/assets/unauthorized-DyojW2ic.css.br +0 -0
  781. codex/static_root/assets/unauthorized-DyojW2ic.css.gz +0 -0
  782. codex/static_root/assets/unauthorized-DyojW2ic.feefa7628a23.css +0 -1
  783. codex/static_root/assets/unauthorized-DyojW2ic.feefa7628a23.css.br +0 -0
  784. codex/static_root/assets/unauthorized-DyojW2ic.feefa7628a23.css.gz +0 -0
  785. codex/static_root/assets/user-tab-EsokzMCB.b0acc46b56a3.js +0 -1
  786. codex/static_root/assets/user-tab-EsokzMCB.b0acc46b56a3.js.br +0 -0
  787. codex/static_root/assets/user-tab-EsokzMCB.b0acc46b56a3.js.gz +0 -0
  788. codex/static_root/assets/user-tab-EsokzMCB.js +0 -1
  789. codex/static_root/assets/user-tab-EsokzMCB.js.br +0 -0
  790. codex/static_root/assets/user-tab-EsokzMCB.js.gz +0 -0
  791. codex/static_root/manifest.4a38de3db1c5.json +0 -712
  792. codex/static_root/manifest.4a38de3db1c5.json.br +0 -0
  793. codex/static_root/manifest.4a38de3db1c5.json.gz +0 -0
  794. codex-1.7.2.dist-info/RECORD +0 -1015
  795. /codex/static_root/assets/{VCheckbox-CMKdyl0R.016ed8d222c4.css → VCheckbox-CvH8ekHL.016ed8d222c4.css} +0 -0
  796. /codex/static_root/assets/{VCheckbox-CMKdyl0R.016ed8d222c4.css.br → VCheckbox-CvH8ekHL.016ed8d222c4.css.br} +0 -0
  797. /codex/static_root/assets/{VCheckbox-CMKdyl0R.016ed8d222c4.css.gz → VCheckbox-CvH8ekHL.016ed8d222c4.css.gz} +0 -0
  798. /codex/static_root/assets/{VCheckbox-CMKdyl0R.css → VCheckbox-CvH8ekHL.css} +0 -0
  799. /codex/static_root/assets/{VCheckbox-CMKdyl0R.css.br → VCheckbox-CvH8ekHL.css.br} +0 -0
  800. /codex/static_root/assets/{VCheckbox-CMKdyl0R.css.gz → VCheckbox-CvH8ekHL.css.gz} +0 -0
  801. /codex/static_root/assets/{VCombobox-bwEYrXCg.9f25a34994e2.css → VCombobox-BQHELb_o.9f25a34994e2.css} +0 -0
  802. /codex/static_root/assets/{VCombobox-bwEYrXCg.9f25a34994e2.css.br → VCombobox-BQHELb_o.9f25a34994e2.css.br} +0 -0
  803. /codex/static_root/assets/{VCombobox-bwEYrXCg.9f25a34994e2.css.gz → VCombobox-BQHELb_o.9f25a34994e2.css.gz} +0 -0
  804. /codex/static_root/assets/{VCombobox-bwEYrXCg.css → VCombobox-BQHELb_o.css} +0 -0
  805. /codex/static_root/assets/{VCombobox-bwEYrXCg.css.br → VCombobox-BQHELb_o.css.br} +0 -0
  806. /codex/static_root/assets/{VCombobox-bwEYrXCg.css.gz → VCombobox-BQHELb_o.css.gz} +0 -0
  807. /codex/static_root/assets/{VExpansionPanels-6G1AUajL.5b17872981df.css → VExpansionPanels-RsCANmDP.5b17872981df.css} +0 -0
  808. /codex/static_root/assets/{VExpansionPanels-6G1AUajL.5b17872981df.css.br → VExpansionPanels-RsCANmDP.5b17872981df.css.br} +0 -0
  809. /codex/static_root/assets/{VExpansionPanels-6G1AUajL.5b17872981df.css.gz → VExpansionPanels-RsCANmDP.5b17872981df.css.gz} +0 -0
  810. /codex/static_root/assets/{VExpansionPanels-6G1AUajL.css → VExpansionPanels-RsCANmDP.css} +0 -0
  811. /codex/static_root/assets/{VExpansionPanels-6G1AUajL.css.br → VExpansionPanels-RsCANmDP.css.br} +0 -0
  812. /codex/static_root/assets/{VExpansionPanels-6G1AUajL.css.gz → VExpansionPanels-RsCANmDP.css.gz} +0 -0
  813. /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.8e3741381961.css → VRadioGroup-Cp9mZ7cb.8e3741381961.css} +0 -0
  814. /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.8e3741381961.css.br → VRadioGroup-Cp9mZ7cb.8e3741381961.css.br} +0 -0
  815. /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.8e3741381961.css.gz → VRadioGroup-Cp9mZ7cb.8e3741381961.css.gz} +0 -0
  816. /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.css → VRadioGroup-Cp9mZ7cb.css} +0 -0
  817. /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.css.br → VRadioGroup-Cp9mZ7cb.css.br} +0 -0
  818. /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.css.gz → VRadioGroup-Cp9mZ7cb.css.gz} +0 -0
  819. /codex/static_root/assets/{VTable-Y5Sc3hJd.c36f0a6a30cf.css → VTable-BnxSZ_W5.c36f0a6a30cf.css} +0 -0
  820. /codex/static_root/assets/{VTable-Y5Sc3hJd.c36f0a6a30cf.css.br → VTable-BnxSZ_W5.c36f0a6a30cf.css.br} +0 -0
  821. /codex/static_root/assets/{VTable-Y5Sc3hJd.c36f0a6a30cf.css.gz → VTable-BnxSZ_W5.c36f0a6a30cf.css.gz} +0 -0
  822. /codex/static_root/assets/{VTable-Y5Sc3hJd.css → VTable-BnxSZ_W5.css} +0 -0
  823. /codex/static_root/assets/{VTable-Y5Sc3hJd.css.br → VTable-BnxSZ_W5.css.br} +0 -0
  824. /codex/static_root/assets/{VTable-Y5Sc3hJd.css.gz → VTable-BnxSZ_W5.css.gz} +0 -0
  825. /codex/static_root/assets/{VWindowItem-ByIod57Y.css → VWindowItem-CWBhiE_Y.css} +0 -0
  826. /codex/static_root/assets/{VWindowItem-ByIod57Y.css.br → VWindowItem-CWBhiE_Y.css.br} +0 -0
  827. /codex/static_root/assets/{VWindowItem-ByIod57Y.css.gz → VWindowItem-CWBhiE_Y.css.gz} +0 -0
  828. /codex/static_root/assets/{VWindowItem-ByIod57Y.f7fb19752bf3.css → VWindowItem-CWBhiE_Y.f7fb19752bf3.css} +0 -0
  829. /codex/static_root/assets/{VWindowItem-ByIod57Y.f7fb19752bf3.css.br → VWindowItem-CWBhiE_Y.f7fb19752bf3.css.br} +0 -0
  830. /codex/static_root/assets/{VWindowItem-ByIod57Y.f7fb19752bf3.css.gz → VWindowItem-CWBhiE_Y.f7fb19752bf3.css.gz} +0 -0
  831. /codex/static_root/assets/{admin-menu-B9bzD6hV.c13b7df2ff57.css → admin-menu-B3iXsOyy.c13b7df2ff57.css} +0 -0
  832. /codex/static_root/assets/{admin-menu-B9bzD6hV.c13b7df2ff57.css.br → admin-menu-B3iXsOyy.c13b7df2ff57.css.br} +0 -0
  833. /codex/static_root/assets/{admin-menu-B9bzD6hV.c13b7df2ff57.css.gz → admin-menu-B3iXsOyy.c13b7df2ff57.css.gz} +0 -0
  834. /codex/static_root/assets/{admin-menu-B9bzD6hV.css → admin-menu-B3iXsOyy.css} +0 -0
  835. /codex/static_root/assets/{admin-menu-B9bzD6hV.css.br → admin-menu-B3iXsOyy.css.br} +0 -0
  836. /codex/static_root/assets/{admin-menu-B9bzD6hV.css.gz → admin-menu-B3iXsOyy.css.gz} +0 -0
  837. /codex/static_root/assets/{admin-settings-button-progress-DUUQfVsZ.2548c49a853e.css → admin-settings-button-progress-BGB22oTD.2548c49a853e.css} +0 -0
  838. /codex/static_root/assets/{admin-settings-button-progress-DUUQfVsZ.css → admin-settings-button-progress-BGB22oTD.css} +0 -0
  839. /codex/static_root/assets/{change-password-dialog-C_EOKOn9.a30e68c6e303.css → change-password-dialog-D0ymWcl_.a30e68c6e303.css} +0 -0
  840. /codex/static_root/assets/{change-password-dialog-C_EOKOn9.a30e68c6e303.css.br → change-password-dialog-D0ymWcl_.a30e68c6e303.css.br} +0 -0
  841. /codex/static_root/assets/{change-password-dialog-C_EOKOn9.a30e68c6e303.css.gz → change-password-dialog-D0ymWcl_.a30e68c6e303.css.gz} +0 -0
  842. /codex/static_root/assets/{change-password-dialog-C_EOKOn9.css → change-password-dialog-D0ymWcl_.css} +0 -0
  843. /codex/static_root/assets/{change-password-dialog-C_EOKOn9.css.br → change-password-dialog-D0ymWcl_.css.br} +0 -0
  844. /codex/static_root/assets/{change-password-dialog-C_EOKOn9.css.gz → change-password-dialog-D0ymWcl_.css.gz} +0 -0
  845. /codex/static_root/assets/{confirm-dialog-54rblwf7.9b5915b112c0.css → confirm-dialog-B1ABbGMU.9b5915b112c0.css} +0 -0
  846. /codex/static_root/assets/{confirm-dialog-54rblwf7.9b5915b112c0.css.br → confirm-dialog-B1ABbGMU.9b5915b112c0.css.br} +0 -0
  847. /codex/static_root/assets/{confirm-dialog-54rblwf7.css → confirm-dialog-B1ABbGMU.css} +0 -0
  848. /codex/static_root/assets/{confirm-dialog-54rblwf7.css.br → confirm-dialog-B1ABbGMU.css.br} +0 -0
  849. /codex/static_root/assets/{datetime-column-DeCthByU.1f3bf499e063.css → datetime-column-BavtvLnf.1f3bf499e063.css} +0 -0
  850. /codex/static_root/assets/{datetime-column-DeCthByU.css → datetime-column-BavtvLnf.css} +0 -0
  851. /codex/static_root/assets/{group-tab-DkIN1Heu.948e907b1e6b.css → group-tab-_vKWzoyd.948e907b1e6b.css} +0 -0
  852. /codex/static_root/assets/{group-tab-DkIN1Heu.948e907b1e6b.css.br → group-tab-_vKWzoyd.948e907b1e6b.css.br} +0 -0
  853. /codex/static_root/assets/{group-tab-DkIN1Heu.948e907b1e6b.css.gz → group-tab-_vKWzoyd.948e907b1e6b.css.gz} +0 -0
  854. /codex/static_root/assets/{group-tab-DkIN1Heu.css → group-tab-_vKWzoyd.css} +0 -0
  855. /codex/static_root/assets/{group-tab-DkIN1Heu.css.br → group-tab-_vKWzoyd.css.br} +0 -0
  856. /codex/static_root/assets/{group-tab-DkIN1Heu.css.gz → group-tab-_vKWzoyd.css.gz} +0 -0
  857. /codex/static_root/assets/{index-CL_6g4tJ.523d7b3d350f.css → index-BHXJTQ4V.523d7b3d350f.css} +0 -0
  858. /codex/static_root/assets/{index-CL_6g4tJ.523d7b3d350f.css.br → index-BHXJTQ4V.523d7b3d350f.css.br} +0 -0
  859. /codex/static_root/assets/{index-CL_6g4tJ.523d7b3d350f.css.gz → index-BHXJTQ4V.523d7b3d350f.css.gz} +0 -0
  860. /codex/static_root/assets/{index-CL_6g4tJ.css → index-BHXJTQ4V.css} +0 -0
  861. /codex/static_root/assets/{index-CL_6g4tJ.css.br → index-BHXJTQ4V.css.br} +0 -0
  862. /codex/static_root/assets/{index-CL_6g4tJ.css.gz → index-BHXJTQ4V.css.gz} +0 -0
  863. /codex/static_root/assets/{main-BZ73p_WW.css → main-K8cER0IH.css} +0 -0
  864. /codex/static_root/assets/{main-BZ73p_WW.css.br → main-K8cER0IH.css.br} +0 -0
  865. /codex/static_root/assets/{main-BZ73p_WW.css.gz → main-K8cER0IH.css.gz} +0 -0
  866. /codex/static_root/assets/{main-BZ73p_WW.d529e8b3f52a.css → main-K8cER0IH.d529e8b3f52a.css} +0 -0
  867. /codex/static_root/assets/{main-BZ73p_WW.d529e8b3f52a.css.br → main-K8cER0IH.d529e8b3f52a.css.br} +0 -0
  868. /codex/static_root/assets/{main-BZ73p_WW.d529e8b3f52a.css.gz → main-K8cER0IH.d529e8b3f52a.css.gz} +0 -0
  869. /codex/static_root/assets/{pdf-doc-CG5-AZ2M.b94aac7e3313.css → pdf-doc-B4cGW_Hl.b94aac7e3313.css} +0 -0
  870. /codex/static_root/assets/{pdf-doc-CG5-AZ2M.b94aac7e3313.css.br → pdf-doc-B4cGW_Hl.b94aac7e3313.css.br} +0 -0
  871. /codex/static_root/assets/{pdf-doc-CG5-AZ2M.b94aac7e3313.css.gz → pdf-doc-B4cGW_Hl.b94aac7e3313.css.gz} +0 -0
  872. /codex/static_root/assets/{pdf-doc-CG5-AZ2M.css → pdf-doc-B4cGW_Hl.css} +0 -0
  873. /codex/static_root/assets/{pdf-doc-CG5-AZ2M.css.br → pdf-doc-B4cGW_Hl.css.br} +0 -0
  874. /codex/static_root/assets/{pdf-doc-CG5-AZ2M.css.gz → pdf-doc-B4cGW_Hl.css.gz} +0 -0
  875. /codex/static_root/assets/{relation-chips-ByfWwuQc.01269a188e01.css → relation-chips-DpbzrZxT.01269a188e01.css} +0 -0
  876. /codex/static_root/assets/{relation-chips-ByfWwuQc.01269a188e01.css.br → relation-chips-DpbzrZxT.01269a188e01.css.br} +0 -0
  877. /codex/static_root/assets/{relation-chips-ByfWwuQc.01269a188e01.css.gz → relation-chips-DpbzrZxT.01269a188e01.css.gz} +0 -0
  878. /codex/static_root/assets/{relation-chips-ByfWwuQc.css → relation-chips-DpbzrZxT.css} +0 -0
  879. /codex/static_root/assets/{relation-chips-ByfWwuQc.css.br → relation-chips-DpbzrZxT.css.br} +0 -0
  880. /codex/static_root/assets/{relation-chips-ByfWwuQc.css.gz → relation-chips-DpbzrZxT.css.gz} +0 -0
  881. /codex/static_root/assets/{stats-tab-BlXGStge.9fdb0106124d.css → stats-tab-WvF2acoZ.9fdb0106124d.css} +0 -0
  882. /codex/static_root/assets/{stats-tab-BlXGStge.9fdb0106124d.css.br → stats-tab-WvF2acoZ.9fdb0106124d.css.br} +0 -0
  883. /codex/static_root/assets/{stats-tab-BlXGStge.9fdb0106124d.css.gz → stats-tab-WvF2acoZ.9fdb0106124d.css.gz} +0 -0
  884. /codex/static_root/assets/{stats-tab-BlXGStge.css → stats-tab-WvF2acoZ.css} +0 -0
  885. /codex/static_root/assets/{stats-tab-BlXGStge.css.br → stats-tab-WvF2acoZ.css.br} +0 -0
  886. /codex/static_root/assets/{stats-tab-BlXGStge.css.gz → stats-tab-WvF2acoZ.css.gz} +0 -0
  887. /codex/static_root/assets/{task-tab-EGlhcKTH.478e74041f80.css → task-tab-DfdUY9Rc.478e74041f80.css} +0 -0
  888. /codex/static_root/assets/{task-tab-EGlhcKTH.478e74041f80.css.br → task-tab-DfdUY9Rc.478e74041f80.css.br} +0 -0
  889. /codex/static_root/assets/{task-tab-EGlhcKTH.478e74041f80.css.gz → task-tab-DfdUY9Rc.478e74041f80.css.gz} +0 -0
  890. /codex/static_root/assets/{task-tab-EGlhcKTH.css → task-tab-DfdUY9Rc.css} +0 -0
  891. /codex/static_root/assets/{task-tab-EGlhcKTH.css.br → task-tab-DfdUY9Rc.css.br} +0 -0
  892. /codex/static_root/assets/{task-tab-EGlhcKTH.css.gz → task-tab-DfdUY9Rc.css.gz} +0 -0
  893. {codex-1.7.2.dist-info → codex-1.7.3.dist-info}/LICENSE +0 -0
  894. {codex-1.7.2.dist-info → codex-1.7.3.dist-info}/entry_points.txt +0 -0
codex/asgi.py CHANGED
@@ -1,4 +1,5 @@
1
- """ASGI config for codex project.
1
+ """
2
+ ASGI config for codex project.
2
3
 
3
4
  It exposes the ASGI callable as a module-level variable named ``DJANGO_APPLICATION``.
4
5
 
codex/choices.py CHANGED
@@ -12,17 +12,18 @@ BROWSER_BOOKMARK_FILTER_CHOICES = MappingProxyType(
12
12
  )
13
13
  BROWSER_ORDER_BY_CHOICES = MappingProxyType(
14
14
  {
15
+ "created_at": "Added Time",
15
16
  "age_rating": "Age Rating",
16
- "bookmark_updated_at": "Last Read",
17
+ "child_count": "Child Count",
17
18
  "community_rating": "Community Rating",
18
- "created_at": "Added Time",
19
19
  "critical_rating": "Critical Rating",
20
- "date": "Publish Date",
21
20
  "filename": "Filename",
22
- "page_count": "Page Count",
23
- "search_score": "Search Score",
24
21
  "size": "File Size",
22
+ "bookmark_updated_at": "Last Read",
25
23
  "sort_name": "Name",
24
+ "page_count": "Page Count",
25
+ "date": "Publish Date",
26
+ "search_score": "Search Score",
26
27
  "story_arc_number": "Story Arc Number",
27
28
  "updated_at": "Updated Time",
28
29
  }
@@ -92,7 +93,6 @@ BROWSER_DEFAULTS = MappingProxyType(
92
93
  "order_by": "sort_name",
93
94
  "order_reverse": False,
94
95
  "q": "",
95
- # "search_results_limit": 100,
96
96
  "show": _DEFAULT_SHOW,
97
97
  "top_group": "p",
98
98
  "twenty_four_hour_time": False,
@@ -116,6 +116,7 @@ ADMIN_FLAG_CHOICES = MappingProxyType(
116
116
  "NU": "Non Users",
117
117
  "RG": "Registration",
118
118
  "ST": "Send Stats",
119
+ "BT": "Banner Text",
119
120
  }
120
121
  )
121
122
 
@@ -389,11 +390,9 @@ ADMIN_TASK_GROUPS = MappingProxyType(
389
390
 
390
391
  def _group_task_values(groups):
391
392
  """Extract values into sorted tuple."""
392
- values = []
393
- for group in groups["tasks"]:
394
- for item in group["tasks"]:
395
- values.append(item["value"])
396
- return tuple(sorted(values))
393
+ return tuple(
394
+ sorted([item["value"] for group in groups["tasks"] for item in group["tasks"]])
395
+ )
397
396
 
398
397
 
399
398
  ADMIN_TASKS = _group_task_values(ADMIN_TASK_GROUPS)
codex/choices_to_json.py CHANGED
@@ -18,6 +18,7 @@ from codex.choices import (
18
18
  READER_DEFAULTS,
19
19
  WEBSOCKET_MESSAGES,
20
20
  )
21
+ from codex.serializers.route import RouteSerializer
21
22
 
22
23
  _DEFAULTS = MappingProxyType(
23
24
  {"browser-choices.json": BROWSER_DEFAULTS, "reader-choices.json": READER_DEFAULTS}
@@ -68,12 +69,11 @@ def _make_json_serializable(data):
68
69
  if isinstance(data, Mapping):
69
70
  json_dict = {}
70
71
  for key, value in data.items():
71
- if key == "pks":
72
- # Special route serializer
73
- # XXX possibly should use actual route serializer for route not just pks
74
- json_dict[key] = ",".join(str(pk) for pk in sorted(value))
72
+ if key == "breadcrumbs":
73
+ json_value = tuple(RouteSerializer(dict(route)).data for route in value)
75
74
  else:
76
- json_dict[_json_key(key)] = _make_json_serializable(value)
75
+ json_value = _make_json_serializable(value)
76
+ json_dict[_json_key(key)] = json_value
77
77
  return json_dict
78
78
  if isinstance(data, list | tuple | frozenset | set):
79
79
  return [_make_json_serializable(item) for item in data]
@@ -93,7 +93,7 @@ def _to_vuetify_dict(fn, data):
93
93
  return vuetify_data
94
94
 
95
95
 
96
- def _dump(parent_path, fn, data, vuetify=True):
96
+ def _dump(parent_path, fn, data, vuetify):
97
97
  """Dump data to json file."""
98
98
  vuetify_data = (
99
99
  _to_vuetify_dict(fn, data) if vuetify else _make_json_serializable(data)
@@ -112,10 +112,10 @@ def main():
112
112
  parent_path = Path(parent_path)
113
113
  parent_path.mkdir(exist_ok=True)
114
114
  for fn, data in _DUMPS.items():
115
- _dump(parent_path, fn, data)
115
+ _dump(parent_path, fn, data, vuetify=True)
116
116
 
117
117
  for fn, data in _MAP_DUMPS.items():
118
- _dump(parent_path, fn, data, False)
118
+ _dump(parent_path, fn, data, vuetify=False)
119
119
 
120
120
 
121
121
  if __name__ == "__main__":
codex/db.py CHANGED
@@ -62,7 +62,7 @@ def _backup_db_before_migration():
62
62
  """If there are migrations to do, backup the db."""
63
63
  backup_path = _get_backup_db_path(f"before-v{VERSION}")
64
64
  janitor = Janitor(LOG_QUEUE, LIBRARIAN_QUEUE)
65
- janitor.backup_db(backup_path, show_status=False)
65
+ janitor.backup_db(show_status=False, backup_path=backup_path)
66
66
  LOG.info("Backed up database before migrations")
67
67
 
68
68
 
@@ -71,7 +71,7 @@ def _repair_db():
71
71
  if FIX_FOREIGN_KEYS:
72
72
  fix_foreign_keys()
73
73
  if INTEGRITY_CHECK:
74
- integrity_check()
74
+ integrity_check(long=True)
75
75
  success = fts_integrity_check() if FTS_INTEGRITY_CHECK else True
76
76
  if FTS_REBUILD or not success:
77
77
  fts_rebuild()
codex/exceptions.py CHANGED
@@ -1,8 +1,8 @@
1
1
  """Special Redirect Error."""
2
2
 
3
+ from collections.abc import Mapping
3
4
  from copy import deepcopy
4
5
  from pprint import pformat
5
- from typing import TYPE_CHECKING
6
6
 
7
7
  from django.core.validators import EMPTY_VALUES
8
8
  from django.shortcuts import redirect
@@ -17,10 +17,6 @@ from codex.serializers.fields import BreadcrumbsField
17
17
  from codex.serializers.route import RouteSerializer
18
18
  from codex.views.util import pop_name
19
19
 
20
- if TYPE_CHECKING:
21
- from collections.abc import Mapping
22
-
23
-
24
20
  LOG = get_logger(__name__)
25
21
  _OPDS_REDIRECT_SETTINGS_KEYS = ("order_by", "top_group")
26
22
  _REDIRECT_SETTINGS_KEYS = ("breadcrumbs", *_OPDS_REDIRECT_SETTINGS_KEYS)
@@ -71,7 +67,10 @@ class SeeOtherRedirectError(APIException):
71
67
  def _add_query_params(self, url):
72
68
  """Change OPDS settings like the frontend does with error.detail."""
73
69
  query_params = {}
74
- settings: Mapping = self.detail.get("settings", {}) # type: ignore
70
+ if isinstance(self.detail, Mapping):
71
+ settings = self.detail.get("settings", {})
72
+ else:
73
+ settings = {}
75
74
  for key in _OPDS_REDIRECT_SETTINGS_KEYS:
76
75
  value = settings.get(key)
77
76
  if value not in EMPTY_VALUES:
@@ -14,23 +14,26 @@ class BookmarkThread(AggregateMessageQueuedThread, BookmarkUpdate):
14
14
  def aggregate_items(self, item):
15
15
  """Aggregate bookmark updates."""
16
16
  if isinstance(item, BookmarkUpdateTask):
17
- key = (tuple(item.auth_filter.items()), tuple(item.comic_filter.items()))
17
+ key = (tuple(item.auth_filter.items()), item.comic_pks)
18
18
  if key not in self.cache:
19
19
  self.cache[key] = {}
20
20
  self.cache[key].update(item.updates)
21
21
  else:
22
22
  self.log.warning(f"Unknown Bookmark task {item}")
23
23
 
24
+ def _send_item(self, filters, updates):
25
+ """Process one item."""
26
+ auth_filter, comic_pks = filters
27
+ auth_filter = dict(auth_filter)
28
+ self.update_bookmarks(auth_filter, comic_pks, updates, self.log)
29
+ self.log.debug(f"updated {auth_filter} pk__in={comic_pks}")
30
+
24
31
  def send_all_items(self):
25
32
  """Run the task method."""
26
33
  cleanup = set()
27
34
  for filters, updates in self.cache.items():
28
35
  try:
29
- auth_filter, comic_filter = filters
30
- auth_filter = dict(auth_filter)
31
- comic_filter = dict(comic_filter)
32
- self.update_bookmarks(auth_filter, comic_filter, updates, self.log)
33
- self.log.debug(f"updated {auth_filter | comic_filter}")
36
+ self._send_item(filters, updates)
34
37
  cleanup.add(filters)
35
38
  except Exception:
36
39
  self.log.exception("Updating bookmarks")
@@ -15,5 +15,5 @@ class BookmarkUpdateTask(BookmarkTask):
15
15
  """Bookmark a page."""
16
16
 
17
17
  auth_filter: Mapping[str, int | str]
18
- comic_filter: Mapping[str, Any]
18
+ comic_pks: tuple[int]
19
19
  updates: Mapping[str, Any]
@@ -10,9 +10,8 @@ from codex.librarian.notifier.tasks import NotifierTask
10
10
  from codex.models import Bookmark, Comic
11
11
  from codex.models.admin import UserActive
12
12
  from codex.views.auth import GroupACLMixin
13
- from codex.views.mixins import BookmarkSearchMixin
14
13
 
15
- VERTICAL_READING_DIRECTIONS = frozenset({"ttb", "btt"})
14
+ _VERTICAL_READING_DIRECTIONS = frozenset({"ttb", "btt"})
16
15
  _BOOKMARK_UPDATE_FIELDS = frozenset(
17
16
  {
18
17
  "page",
@@ -22,10 +21,9 @@ _BOOKMARK_UPDATE_FIELDS = frozenset(
22
21
  "reading_direction",
23
22
  }
24
23
  )
25
- _COMIC_ONLY_FIELDS = ("pk", "page_count")
26
24
 
27
25
 
28
- class BookmarkUpdate(GroupACLMixin, BookmarkSearchMixin):
26
+ class BookmarkUpdate(GroupACLMixin):
29
27
  """Update Bookmarks."""
30
28
 
31
29
  # Used by Bookmarkd and view.bookmark.
@@ -47,10 +45,8 @@ class BookmarkUpdate(GroupACLMixin, BookmarkSearchMixin):
47
45
  def _update_bookmarks_validate_two_pages(bm, updates):
48
46
  """Force vertical view to not use two pages."""
49
47
  rd = updates.get("reading_direction")
50
- if (
51
- bm.two_pages
52
- and rd in VERTICAL_READING_DIRECTIONS
53
- or bm.reading_direction in VERTICAL_READING_DIRECTIONS
48
+ if bm.two_pages and bool(
49
+ {rd, bm.reading_direction}.intersection(_VERTICAL_READING_DIRECTIONS)
54
50
  ):
55
51
  updates["two_pages"] = None
56
52
 
@@ -62,13 +58,13 @@ class BookmarkUpdate(GroupACLMixin, BookmarkSearchMixin):
62
58
  LIBRARIAN_QUEUE.put(task)
63
59
 
64
60
  @classmethod
65
- def _update_bookmarks(cls, search_kwargs, updates, user) -> int:
61
+ def _update_bookmarks(cls, auth_filter, comic_pks, updates, user) -> int:
66
62
  """Update existing bookmarks."""
67
63
  count = 0
68
64
  if not updates:
69
65
  return count
70
66
  group_acl_filter = cls.get_group_acl_filter(Bookmark, user)
71
- query_filter = group_acl_filter & Q(**search_kwargs)
67
+ query_filter = group_acl_filter & Q(**auth_filter) & Q(comic__in=comic_pks)
72
68
  existing_bookmarks = Bookmark.objects.filter(query_filter)
73
69
  if updates.get("page") is not None:
74
70
  existing_bookmarks = existing_bookmarks.annotate(
@@ -98,12 +94,12 @@ class BookmarkUpdate(GroupACLMixin, BookmarkSearchMixin):
98
94
  """Force vertical view to not use two pages."""
99
95
  if (
100
96
  updates.get("two_pages")
101
- and updates.get("reading_direction") in VERTICAL_READING_DIRECTIONS
97
+ and updates.get("reading_direction") in _VERTICAL_READING_DIRECTIONS
102
98
  ):
103
99
  updates.pop("two_pages", None)
104
100
 
105
101
  @classmethod
106
- def _create_bookmarks(cls, comic_filter, search_kwargs, updates, user) -> int:
102
+ def _create_bookmarks(cls, auth_filter, comic_pks, updates, user) -> int:
107
103
  """Create new bookmarks for comics that don't exist yet."""
108
104
  count = 0
109
105
  cls._create_bookmarks_validate_two_pages(updates)
@@ -112,27 +108,19 @@ class BookmarkUpdate(GroupACLMixin, BookmarkSearchMixin):
112
108
  create_bookmarks = []
113
109
  group_acl_filter = cls.get_group_acl_filter(Comic, user)
114
110
  exclude = {}
115
- for key, value in search_kwargs.items():
111
+ for key, value in auth_filter.items():
116
112
  exclude["bookmark__" + key] = value
117
- query_filter = group_acl_filter & Q(**comic_filter) & ~Q(**exclude)
118
- create_bookmark_comics = Comic.objects.filter(query_filter).only(
119
- *_COMIC_ONLY_FIELDS
120
- )
113
+ query_filter = group_acl_filter & Q(pk__in=comic_pks) & ~Q(**exclude)
114
+ create_bookmark_comics = Comic.objects.filter(query_filter).only("pk")
121
115
  for comic in create_bookmark_comics:
122
- defaults = {"comic": comic}
123
- defaults.update(updates)
124
- for key, value in search_kwargs.items():
125
- if not key.startswith("comic"):
126
- defaults[key] = value
127
-
128
- bm = Bookmark(**defaults)
116
+ bm = Bookmark(comic=comic, **auth_filter, **updates)
129
117
  create_bookmarks.append(bm)
130
118
  count = len(create_bookmarks)
131
119
  if count:
132
120
  Bookmark.objects.bulk_create(
133
121
  create_bookmarks,
134
122
  update_fields=tuple(_BOOKMARK_UPDATE_FIELDS),
135
- unique_fields=Bookmark._meta.unique_together[0], # type: ignore
123
+ unique_fields=Bookmark._meta.unique_together[0],
136
124
  )
137
125
  return count
138
126
 
@@ -143,22 +131,20 @@ class BookmarkUpdate(GroupACLMixin, BookmarkSearchMixin):
143
131
  try:
144
132
  UserActive.objects.update_or_create(user=user)
145
133
  except Exception as exc:
146
- reason = f"update user activity {exc}"
134
+ reason = f"Update user activity {exc}"
147
135
  log.warning(reason)
148
136
 
149
137
  @classmethod
150
- def update_bookmarks(cls, auth_filter, comic_filter, updates, log):
138
+ def update_bookmarks(cls, auth_filter, comic_pks, updates, log):
151
139
  """Update a user bookmark."""
152
- search_kwargs = cls.get_bookmark_search_kwargs(auth_filter, comic_filter)
153
-
154
140
  user = None
155
141
  for key, value in auth_filter.items():
156
142
  if key == "user":
157
143
  user = User.objects.get(pk=value)
158
144
  break
159
145
 
160
- count = cls._update_bookmarks(search_kwargs, updates, user)
161
- count += cls._create_bookmarks(comic_filter, search_kwargs, updates, user)
146
+ count = cls._update_bookmarks(auth_filter, comic_pks, updates, user)
147
+ count += cls._create_bookmarks(auth_filter, comic_pks, updates, user)
162
148
  if user:
163
149
  cls._update_user_active(user, log)
164
150
  if count:
@@ -32,7 +32,7 @@ class CoverCreateThread(QueuedThread, CoverPathMixin):
32
32
  with Image.open(image_io) as cover_image:
33
33
  cover_image.thumbnail(
34
34
  _THUMBNAIL_SIZE,
35
- Image.Resampling.LANCZOS, # type: ignore
35
+ Image.Resampling.LANCZOS,
36
36
  reducing_gap=3.0,
37
37
  )
38
38
  cover_image.save(cover_thumb_buffer, "WEBP", method=6)
@@ -41,7 +41,8 @@ class CoverCreateThread(QueuedThread, CoverPathMixin):
41
41
 
42
42
  @classmethod
43
43
  def _get_comic_cover_image(cls, comic_path):
44
- """Create comic cover if none exists.
44
+ """
45
+ Create comic cover if none exists.
45
46
 
46
47
  Return image thumb data or path to missing file thumb.
47
48
  """
@@ -59,8 +60,9 @@ class CoverCreateThread(QueuedThread, CoverPathMixin):
59
60
  return f.read()
60
61
 
61
62
  @classmethod
62
- def create_cover_from_path(cls, pk, cover_path, log, librarian_queue, custom=False):
63
- """Create cover for path.
63
+ def create_cover_from_path(cls, pk, cover_path, log, librarian_queue, custom):
64
+ """
65
+ Create cover for path.
64
66
 
65
67
  Called from views/cover.
66
68
  """
@@ -95,7 +97,7 @@ class CoverCreateThread(QueuedThread, CoverPathMixin):
95
97
  # zero length file is code for missing.
96
98
  cover_path.touch()
97
99
 
98
- def _bulk_create_comic_covers(self, pks, custom=False):
100
+ def _bulk_create_comic_covers(self, pks, custom):
99
101
  """Create bulk comic covers."""
100
102
  num_comics = len(pks)
101
103
  if not num_comics:
@@ -115,7 +117,7 @@ class CoverCreateThread(QueuedThread, CoverPathMixin):
115
117
  else:
116
118
  # bulk contributor creates covers inline
117
119
  data = self.create_cover_from_path(
118
- pk, cover_path, self.log, self.librarian_queue
120
+ pk, cover_path, self.log, self.librarian_queue, custom=False
119
121
  )
120
122
  if data:
121
123
  data.close()
@@ -134,6 +136,6 @@ class CoverCreateThread(QueuedThread, CoverPathMixin):
134
136
  def create_all_covers(self):
135
137
  """Create all covers for all libraries."""
136
138
  pks = CustomCover.objects.values_list("pk", flat=True)
137
- self._bulk_create_comic_covers(pks, True)
139
+ self._bulk_create_comic_covers(pks, custom=True)
138
140
  pks = Comic.objects.values_list("pk", flat=True)
139
- self._bulk_create_comic_covers(pks, False)
141
+ self._bulk_create_comic_covers(pks, custom=False)
@@ -21,20 +21,21 @@ class CoverPathMixin:
21
21
  """Translate an integer into an efficient filesystem path."""
22
22
  fnv = fnv1a_32(bytes(str(pk).zfill(cls._ZFILL), "utf-8"))
23
23
  hex_str = format(fnv, f"0{cls._ZFILL}x")
24
- parts = []
25
- for i in range(0, len(hex_str), cls._PATH_STEP):
26
- parts.append(hex_str[i : i + cls._PATH_STEP])
24
+ parts = [
25
+ hex_str[i : i + cls._PATH_STEP]
26
+ for i in range(0, len(hex_str), cls._PATH_STEP)
27
+ ]
27
28
  return Path("/".join(parts))
28
29
 
29
30
  @classmethod
30
- def get_cover_path(cls, pk, custom=False):
31
+ def get_cover_path(cls, pk, custom):
31
32
  """Get cover path for comic pk."""
32
33
  cover_path = cls._hex_path(pk)
33
34
  root = cls.CUSTOM_COVERS_ROOT if custom else cls.COVERS_ROOT
34
35
  return root / cover_path.with_suffix(".webp")
35
36
 
36
37
  @classmethod
37
- def get_cover_paths(cls, pks, custom=False):
38
+ def get_cover_paths(cls, pks, custom):
38
39
  """Get cover paths for many comic pks."""
39
40
  cover_paths = set()
40
41
  for pk in pks:
@@ -67,7 +67,7 @@ class CoverPurgeThread(CoverCreateThread):
67
67
  self.log.info("Removed entire comic cover cache.")
68
68
  shutil.rmtree(self.CUSTOM_COVERS_ROOT)
69
69
  self.log.info("Removed entire custom cover cache.")
70
- except Exception as exc:
70
+ except OSError as exc:
71
71
  self.log.warning(exc)
72
72
  librarian_queue.put(LIBRARY_CHANGED_TASK)
73
73
 
@@ -77,7 +77,7 @@ class CoverPurgeThread(CoverCreateThread):
77
77
  self.log.debug(f"Removing covers from missing {name}.")
78
78
  self.status_controller.start_many(self._CLEANUP_STATUS_MAP)
79
79
  pks = cover_class.objects.all().values_list("pk", flat=True)
80
- db_cover_paths = self.get_cover_paths(pks)
80
+ db_cover_paths = self.get_cover_paths(pks, custom=False)
81
81
 
82
82
  orphan_cover_paths = set()
83
83
  for root, _, filenames in os.walk(cover_root):
@@ -28,7 +28,7 @@ class CronThread(NamedThread):
28
28
  self._stop_event = Event()
29
29
  self._cond = Condition()
30
30
  self._task_times = ()
31
- super().__init__(*args, name=self.__class__.__name__, daemon=True, **kwargs)
31
+ super().__init__(*args, daemon=True, **kwargs)
32
32
 
33
33
  def _create_task_times(self):
34
34
  task_times = {}
@@ -222,10 +222,10 @@ class AggregateMetadataImporter(ExtractMetadataImporter):
222
222
  if self.task.force_import_metadata:
223
223
  import_metadata = True
224
224
  else:
225
- key = AdminFlag.FlagChoices.IMPORT_METADATA.value # type: ignore
225
+ key = AdminFlag.FlagChoices.IMPORT_METADATA.value
226
226
  import_metadata = AdminFlag.objects.get(key=key).on
227
227
  if not import_metadata:
228
- self.log.warn("Admin flag set to NOT import metadata.")
228
+ self.log.warning("Admin flag set to NOT import metadata.")
229
229
 
230
230
  # Init metadata, extract and aggregate
231
231
  self.metadata[MDS] = {}
@@ -73,7 +73,6 @@ class CacheUpdateImporter(InitImporter):
73
73
  try:
74
74
  log_list = []
75
75
  for model in GROUP_MODELS:
76
- # self.log.debug(f"Updating timestamps for {model.__name__}s...")
77
76
  count = self._update_group_model(
78
77
  force_update_group_map, model, start_time, log_list
79
78
  )
@@ -85,9 +84,7 @@ class CacheUpdateImporter(InitImporter):
85
84
 
86
85
  if total_count:
87
86
  groups_log = ", ".join(log_list)
88
- self.log.info( # type: ignore
89
- f"Updated timestamps for {groups_log}."
90
- )
87
+ self.log.info(f"Updated timestamps for {groups_log}.")
91
88
  self.changed += total_count
92
89
  finally:
93
90
  self.status_controller.finish(status)
@@ -78,7 +78,7 @@ class CreateComicsImporter(LinkComicsImporter):
78
78
  Comic.objects.bulk_update(update_comics, BULK_UPDATE_COMIC_FIELDS)
79
79
  count = len(update_comics)
80
80
 
81
- self._remove_covers(comic_pks, False) # type: ignore
81
+ self._remove_covers(comic_pks, custom=False)
82
82
  self.log.debug(f"Purging covers for {len(comic_pks)} updated comics.")
83
83
  if count:
84
84
  self.log.info(f"Updated {count} comics.")
@@ -126,7 +126,7 @@ class CreateComicsImporter(LinkComicsImporter):
126
126
  create_comics,
127
127
  update_conflicts=True,
128
128
  update_fields=BULK_CREATE_COMIC_FIELDS,
129
- unique_fields=Comic._meta.unique_together[0], # type: ignore
129
+ unique_fields=Comic._meta.unique_together[0],
130
130
  )
131
131
  count = len(create_comics)
132
132
  if count:
@@ -43,7 +43,7 @@ class CreateCoversImporter(CreateComicsImporter):
43
43
  if LINK_COVER_PKS not in self.metadata:
44
44
  self.metadata[LINK_COVER_PKS] = set()
45
45
  self.metadata[LINK_COVER_PKS].update(update_cover_pks)
46
- self._remove_covers(update_cover_pks, custom=True) # type: ignore
46
+ self._remove_covers(update_cover_pks, custom=True)
47
47
  count = len(update_covers)
48
48
  if status:
49
49
  status.add_complete(count)
@@ -1,4 +1,5 @@
1
- """Create all missing comic foreign keys for an import.
1
+ """
2
+ Create all missing comic foreign keys for an import.
2
3
 
3
4
  So we may safely create the comics next.
4
5
  """
@@ -189,7 +190,7 @@ class CreateForeignKeysImporter(CreateCoversImporter):
189
190
  create_folders,
190
191
  update_conflicts=True,
191
192
  update_fields=BULK_UPDATE_FOLDER_FIELDS,
192
- unique_fields=Folder._meta.unique_together[0], # type: ignore
193
+ unique_fields=Folder._meta.unique_together[0],
193
194
  )
194
195
  count = len(create_folders)
195
196
  status.add_complete(count)
@@ -296,7 +297,7 @@ class CreateForeignKeysImporter(CreateCoversImporter):
296
297
  create_objs,
297
298
  update_conflicts=True,
298
299
  update_fields=CREATE_DICT_UPDATE_FIELDS[model],
299
- unique_fields=model._meta.unique_together[0], # type: ignore
300
+ unique_fields=model._meta.unique_together[0],
300
301
  )
301
302
  count = len(create_objs)
302
303
  if count:
@@ -13,7 +13,7 @@ from codex.status import Status
13
13
  class DeletedImporter(CacheUpdateImporter):
14
14
  """Clean up database methods."""
15
15
 
16
- def _remove_covers(self, delete_pks, custom=False):
16
+ def _remove_covers(self, delete_pks, custom: bool):
17
17
  task = CoverRemoveTask(delete_pks, custom)
18
18
  self.librarian_queue.put(task)
19
19
 
@@ -34,7 +34,7 @@ class DeletedImporter(CacheUpdateImporter):
34
34
  )
35
35
  folders.delete()
36
36
 
37
- self._remove_covers(delete_comic_pks)
37
+ self._remove_covers(delete_comic_pks, custom=False)
38
38
 
39
39
  count = len(delete_comic_pks)
40
40
  if count:
@@ -96,7 +96,7 @@ class DeletedImporter(CacheUpdateImporter):
96
96
  delete_comic_pks = frozenset(delete_qs.values_list("pk", flat=True))
97
97
  delete_qs.delete()
98
98
 
99
- self._remove_covers(delete_comic_pks)
99
+ self._remove_covers(delete_comic_pks, custom=False)
100
100
 
101
101
  count = len(delete_comic_pks)
102
102
  if count:
@@ -94,7 +94,7 @@ class ExtractMetadataImporter(QueryForeignKeysImporter):
94
94
 
95
95
  @classmethod
96
96
  def _clean_decimal(cls, value, field_name: str):
97
- field: DecimalField = Comic._meta.get_field(field_name) # type: ignore
97
+ field: DecimalField = Comic._meta.get_field(field_name) # type: ignore[reportAssignmentType]
98
98
  try:
99
99
  quantize_str = Decimal(f"1e-{field.decimal_places}")
100
100
  value = value.quantize(quantize_str, rounding=ROUND_DOWN)
@@ -147,7 +147,7 @@ class ExtractMetadataImporter(QueryForeignKeysImporter):
147
147
  @staticmethod
148
148
  def _clean_charfield(model, field_name, value):
149
149
  try:
150
- field: CharField = model._meta.get_field(field_name) # type: ignore
150
+ field: CharField = model._meta.get_field(field_name) # type: ignore[reportAssignmentType]
151
151
  if value:
152
152
  value = value[: field.max_length].strip()
153
153
  if not value:
@@ -120,7 +120,7 @@ class FailedImportsImporter(DeletedImporter):
120
120
  create_objs,
121
121
  update_conflicts=True,
122
122
  update_fields=_BULK_UPDATE_FAILED_IMPORT_FIELDS,
123
- unique_fields=FailedImport._meta.unique_together[0], # type: ignore
123
+ unique_fields=FailedImport._meta.unique_together[0],
124
124
  )
125
125
  count = len(create_objs)
126
126
  if count:
@@ -43,7 +43,9 @@ class ComicImporter(MovedImporter):
43
43
 
44
44
  # Wait to start the search index update in case more updates are incoming.
45
45
  until = time() + 1
46
- delayed_search_task = DelayedTasks(until, (SearchIndexUpdateTask(False),))
46
+ delayed_search_task = DelayedTasks(
47
+ until, (SearchIndexUpdateTask(rebuild=False),)
48
+ )
47
49
  self.librarian_queue.put(delayed_search_task)
48
50
  else:
49
51
  self.log.info("No updates neccissary.")
@@ -35,7 +35,7 @@ class ComicImporterThread(QueuedThread):
35
35
  import_comics = Comic.objects.filter(pk__in=task.pks).only("path", "library_id")
36
36
  library_path_map = {}
37
37
  for import_comic in import_comics:
38
- library_id = import_comic.library_id # type: ignore
38
+ library_id = import_comic.library_id # type: ignore[reportAttributeAccessIssue]
39
39
  if library_id not in library_path_map:
40
40
  library_path_map[library_id] = set()
41
41
  library_path_map[library_id].add(import_comic.path)
@@ -89,7 +89,7 @@ class ComicImporterThread(QueuedThread):
89
89
  importer.bulk_folders_moved()
90
90
  return True
91
91
 
92
- def _adopt_orphan_folders(self, janitor=False):
92
+ def _adopt_orphan_folders(self, janitor: bool):
93
93
  """Find orphan folders and move them into their correct place."""
94
94
  status = Status(ImportStatusTypes.ADOPT_FOLDERS)
95
95
  moved_status = Status(ImportStatusTypes.DIRS_MOVED)
@@ -118,6 +118,6 @@ class ComicImporterThread(QueuedThread):
118
118
  elif isinstance(task, UpdateGroupsTask):
119
119
  self._update_groups(task)
120
120
  elif isinstance(task, AdoptOrphanFoldersTask):
121
- self._adopt_orphan_folders(task.janitor)
121
+ self._adopt_orphan_folders(janitor=task.janitor)
122
122
  else:
123
123
  self.log.warning(f"Bad task sent to library updater {task}")
@@ -186,7 +186,8 @@ class LinkComicsImporter(LinkCoversImporter):
186
186
  return tms, all_del_pks
187
187
 
188
188
  def bulk_fix_comic_m2m_field(self, field_name, m2m_links, status):
189
- """Recreate an m2m field for a set of comics.
189
+ """
190
+ Recreate an m2m field for a set of comics.
190
191
 
191
192
  Since we can't bulk_update or bulk_create m2m fields use a trick.
192
193
  bulk_create() on the through table: