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
@@ -46,9 +46,7 @@ class MovedImporter(AggregateMetadataImporter):
46
46
  new_path = self.task.files_moved[comic.path]
47
47
  comic.path = new_path
48
48
  new_path = Path(new_path)
49
- comic.parent_folder = Folder.objects.get( # type: ignore
50
- path=new_path.parent
51
- )
49
+ comic.parent_folder = Folder.objects.get(path=new_path.parent)
52
50
  comic.updated_at = Now()
53
51
  comic.presave()
54
52
  folder_m2m_links[comic.pk] = Folder.objects.filter(
@@ -137,7 +135,7 @@ class MovedImporter(AggregateMetadataImporter):
137
135
  f"Unlinked {len(unlink_groups)} {model.__name__} moved custom covers."
138
136
  )
139
137
 
140
- self._remove_covers(unlink_pks, custom=True) # type: ignore
138
+ self._remove_covers(unlink_pks, custom=True)
141
139
 
142
140
  def _bulk_covers_moved(self, status=None):
143
141
  """Move covers."""
@@ -194,8 +192,6 @@ class MovedImporter(AggregateMetadataImporter):
194
192
  folder.updated_at = Now()
195
193
  update_folders.append(folder)
196
194
 
197
- # delete_folders = Folder.objects.filter(library=self.library, path__in=new_paths)
198
-
199
195
  update_folders = sorted(update_folders, key=lambda x: len(Path(x.path).parts))
200
196
 
201
197
  Folder.objects.bulk_update(update_folders, MOVED_BULK_FOLDER_UPDATE_FIELDS)
@@ -212,7 +208,6 @@ class MovedImporter(AggregateMetadataImporter):
212
208
  """Move folders under existing folders."""
213
209
  while True:
214
210
  # Get existing parent folders
215
- # dest_parent_paths = tuple(str(path) for path in dest_parent_folder_paths_map)
216
211
  dest_parent_paths = tuple(dest_parent_folder_paths_map.keys())
217
212
  extant_parent_folders = Folder.objects.filter(
218
213
  library=self.library, path__in=dest_parent_paths
@@ -96,7 +96,7 @@ class QueryForeignKeysImporter(QueryCustomCoversImporter):
96
96
  if extra_fields:
97
97
  fields += extra_fields
98
98
  flat = len(fields) == 1 and fk_cls != Publisher
99
- qs = fk_cls.objects.filter(fk_filter).values_list(*fields, flat=flat)
99
+ qs = fk_cls.objects.filter(fk_filter).distinct().values_list(*fields, flat=flat)
100
100
  return frozenset(qs)
101
101
 
102
102
  def _query_create_metadata( # noqa: PLR0913
@@ -229,9 +229,7 @@ class QueryForeignKeysImporter(QueryCustomCoversImporter):
229
229
 
230
230
  group_filter = Q()
231
231
  for group_tree, count_value in update_group_trees.items():
232
- compare_filter = {}
233
- for field_name, value in zip(compare_fields, group_tree, strict=False):
234
- compare_filter[field_name] = value
232
+ compare_filter = dict(zip(compare_fields, group_tree, strict=False))
235
233
  compare_filter[count_field_name] = count_value
236
234
  group_filter |= Q(**compare_filter)
237
235
  return group_filter
@@ -449,7 +447,7 @@ class QueryForeignKeysImporter(QueryCustomCoversImporter):
449
447
 
450
448
  # Build combined query object from the value_filter
451
449
  model = DICT_MODEL_FIELD_MODEL_MAP[field_name]
452
- if model == Identifier:
450
+ if model in (Identifier, Contributor):
453
451
  for filter_and_prefix, value_filter in query_filter_map.items():
454
452
  self._query_create_metadata(
455
453
  model,
@@ -494,7 +492,6 @@ class QueryForeignKeysImporter(QueryCustomCoversImporter):
494
492
 
495
493
  def _query_missing_simple_models(self, names, fk_data, status):
496
494
  """Find missing named models and folders."""
497
- # count = 0
498
495
  if not names:
499
496
  return 0
500
497
  create_fks, base_cls, field, fk_field = fk_data
@@ -18,7 +18,7 @@ class ImportDBDiffTask(ImportTask):
18
18
 
19
19
  dirs_moved: Mapping[str, str] = field(default_factory=dict)
20
20
  dirs_modified: frozenset[str] = frozenset()
21
- # dirs_created: frozenset[str] | None = frozenset()
21
+ # dirs_created: frozenset[str] | None = frozenset() # noqa: ERA001
22
22
  dirs_deleted: frozenset[str] = frozenset()
23
23
 
24
24
  files_moved: Mapping[str, str] = field(default_factory=dict)
@@ -2,6 +2,7 @@
2
2
  # Uses app.get_model() because functions may also be called before the models are ready on startup.
3
3
 
4
4
  import re
5
+ from typing import TYPE_CHECKING
5
6
 
6
7
  from django.apps import apps
7
8
  from django.db import DEFAULT_DB_ALIAS, connections
@@ -19,6 +20,13 @@ from codex.settings.settings import (
19
20
  from codex.status import Status
20
21
  from codex.worker_base import WorkerBaseMixin
21
22
 
23
+ if TYPE_CHECKING:
24
+ from django.db.models.manager import BaseManager
25
+
26
+ from codex.models.base import BaseModel
27
+ from codex.models.comic import Comic
28
+
29
+
22
30
  REPAIR_FLAG_PATH = CONFIG_PATH / "rebuild_db"
23
31
  REBUILT_DB_PATH = DB_PATH.parent / (DB_PATH.name + ".rebuilt")
24
32
  BACKUP_DB_PATH = DB_PATH.parent / (DB_PATH.name + ".bak")
@@ -105,7 +113,7 @@ def _null_bad_fk_rels_table(table_name, bad_rows, log):
105
113
  fields = model._meta.fields
106
114
  field_names = {}
107
115
  update_objs = []
108
- objs = model.objects.filter(pk__in=bad_rows.keys())
116
+ objs: BaseManager[BaseModel] = model.objects.filter(pk__in=bad_rows.keys()) # type: ignore[reportAssignmentType]
109
117
  update_fields = {"updated_at"}
110
118
  now = Now()
111
119
  for obj in objs:
@@ -119,7 +127,7 @@ def _null_bad_fk_rels_table(table_name, bad_rows, log):
119
127
  field_name = field_names[fkid]
120
128
  setattr(obj, field_name, None)
121
129
  update_fields.add(field_name)
122
- obj.updated_at = now # type: ignore
130
+ obj.updated_at = now
123
131
  update_objs.append(obj)
124
132
  except Exception as exc:
125
133
  log.warning(
@@ -142,10 +150,10 @@ def _null_bad_fk_rels(bad_fk_rels, log):
142
150
  for table_name, bad_rows in bad_fk_rels.items():
143
151
  try:
144
152
  fix_comic_pks |= _null_bad_fk_rels_table(table_name, bad_rows, log)
145
- except Exception as exc:
153
+ except Exception:
146
154
  pks = sorted(bad_rows.keys())
147
- log.error( # noqa: TRY400
148
- f"Unable to null {len(pks)} {table_name} rows with bad foreign keys - {exc}"
155
+ log.exception(
156
+ f"Unable to null {len(pks)} {table_name} rows with bad foreign keys"
149
157
  )
150
158
  log.error(f"{table_name}: {pks}") # noqa: TRY400
151
159
  return fix_comic_pks
@@ -175,10 +183,8 @@ def _delete_bad_m2m_rows(bad_m2m_rows, log):
175
183
  for table_name, ids in bad_m2m_rows.items():
176
184
  try:
177
185
  count += _delete_bad_m2m_rows_table(table_name, ids, fix_comic_pks, log)
178
- except Exception as exc:
179
- log.error( # noqa: TRY400
180
- f"Could not delete bad foreign keys in table {table_name} - {exc}"
181
- )
186
+ except Exception:
187
+ log.exception(f"Could not delete bad foreign keys in table {table_name}")
182
188
  if count:
183
189
  log.info(f"Removed {count} bad foreign key relations.")
184
190
  return fix_comic_pks
@@ -189,7 +195,9 @@ def _mark_comics_for_update(fix_comic_pks, log):
189
195
  if not fix_comic_pks:
190
196
  return
191
197
  comic_model = apps.get_model(app_label="codex", model_name="comic")
192
- outdated_comics = comic_model.objects.filter(pk__in=fix_comic_pks).only(
198
+ outdated_comics: BaseManager[Comic] = comic_model.objects.filter(
199
+ pk__in=fix_comic_pks
200
+ ).only( # type: ignore[reportAssignmentType]
193
201
  "stat", "updated_at"
194
202
  )
195
203
  if not outdated_comics:
@@ -198,12 +206,12 @@ def _mark_comics_for_update(fix_comic_pks, log):
198
206
  update_comics = []
199
207
  now = Now()
200
208
  for comic in outdated_comics:
201
- stat_list = comic.stat # type: ignore
209
+ stat_list = comic.stat
202
210
  if not stat_list:
203
211
  continue
204
212
  stat_list[8] = 0.0
205
- comic.stat = stat_list # type: ignore
206
- comic.updated_at = now # type: ignore
213
+ comic.stat = stat_list # type: ignore[reportAttributeAccessIssue]
214
+ comic.updated_at = now
207
215
  update_comics.append(comic)
208
216
 
209
217
  if update_comics:
@@ -227,8 +235,8 @@ def fix_foreign_keys(log=None):
227
235
  fix_comic_pks |= _delete_bad_m2m_rows(bad_m2m_rows, log)
228
236
  try:
229
237
  _mark_comics_for_update(fix_comic_pks, log)
230
- except Exception as exc:
231
- LOG.warning(f"Could not mark comics with bad relations for update: {exc}")
238
+ except Exception:
239
+ LOG.exception("Could not mark comics with bad relations for update")
232
240
 
233
241
 
234
242
  def _repair_extra_custom_cover_libraries(library_model, log):
@@ -277,7 +285,7 @@ def _is_integrity_ok(results):
277
285
  )
278
286
 
279
287
 
280
- def integrity_check(long=True, log=None):
288
+ def integrity_check(long, log=None):
281
289
  """Run sqlite3 integrity check."""
282
290
  if not log:
283
291
  log = LOG
@@ -318,9 +326,8 @@ def fts_integrity_check(log=None):
318
326
  if results:
319
327
  # I'm not sure if this raises or puts the error in the results.
320
328
  raise ValueError(results) # noqa: TRY301
321
- except Exception as exc:
322
- log.warning("Full Text Search Index failed integrity check.")
323
- log.warning(exc)
329
+ except Exception:
330
+ log.exception("Full Text Search Index failed integrity check.")
324
331
  else:
325
332
  log.info("Full Text Search Index passed integrity check.")
326
333
  success = True
@@ -340,7 +347,7 @@ class IntegrityMixin(WorkerBaseMixin):
340
347
  finally:
341
348
  self.status_controller.finish(status)
342
349
 
343
- def integrity_check(self, long=False):
350
+ def integrity_check(self, long: bool):
344
351
  """Integrity check task."""
345
352
  subtitle = "" if long else "Quick"
346
353
  status = Status(JanitorStatusTypes.INTEGRITY_CHECK, subtitle=subtitle)
@@ -109,7 +109,7 @@ class Janitor(
109
109
  case JanitorVacuumTask():
110
110
  self.vacuum_db()
111
111
  case JanitorBackupTask():
112
- self.backup_db()
112
+ self.backup_db(show_status=True)
113
113
  case JanitorLatestVersionTask():
114
114
  self.update_latest_version(task.force)
115
115
  case JanitorUpdateTask():
@@ -149,7 +149,10 @@ class Janitor(
149
149
  for next_task in next_tasks:
150
150
  self.librarian_queue.put(next_task)
151
151
  case JanitorSearchOptimizeFinishedTask():
152
- next_tasks = (JanitorVacuumTask(), JanitorBackupTask())
152
+ next_tasks = (
153
+ JanitorVacuumTask(),
154
+ JanitorBackupTask(),
155
+ )
153
156
  for next_task in next_tasks:
154
157
  self.librarian_queue.put(next_task)
155
158
  case _:
@@ -28,7 +28,7 @@ class LatestVersionMixin(WorkerBaseMixin):
28
28
  response = requests.get(_REPO_URL, timeout=_REPO_TIMEOUT)
29
29
  return json.loads(response.text)["info"]["version"]
30
30
 
31
- def update_latest_version(self, force=False):
31
+ def update_latest_version(self, force: bool):
32
32
  """Get the latest version from a remote repo using a cache."""
33
33
  status = Status(JanitorStatusTypes.CODEX_LATEST_VERSION)
34
34
  try:
@@ -27,7 +27,7 @@ class UpdateMixin(WorkerBaseMixin):
27
27
  versio_latest_version = Version(latest_version)
28
28
 
29
29
  installed_versio_version = Version(VERSION)
30
- if versio_latest_version.parts[1] and not installed_versio_version.parts[1]: # type: ignore
30
+ if versio_latest_version.parts[1] and not installed_versio_version.parts[1]: # type: ignore[reportIndexIssue]
31
31
  pre_blurb = "latest version is a prerelease. But installed version is not."
32
32
  else:
33
33
  result = versio_latest_version > installed_versio_version
@@ -35,7 +35,7 @@ class UpdateMixin(WorkerBaseMixin):
35
35
  self.log.debug(f"{latest_version=} > {VERSION=} = {result}{pre_blurb}")
36
36
  return result
37
37
 
38
- def update_codex(self, force=False):
38
+ def update_codex(self, force: bool):
39
39
  """Update the package and restart everything if the version changed."""
40
40
  status = Status(JanitorStatusTypes.CODEX_UPDATE)
41
41
  try:
@@ -30,7 +30,7 @@ class VacuumMixin(WorkerBaseMixin):
30
30
  finally:
31
31
  self.status_controller.finish(status)
32
32
 
33
- def backup_db(self, backup_path=BACKUP_DB_PATH, show_status=True):
33
+ def backup_db(self, show_status: bool, backup_path=BACKUP_DB_PATH):
34
34
  """Backup the database."""
35
35
  status = Status(JanitorStatusTypes.DB_BACKUP) if show_status else ""
36
36
  try:
@@ -79,7 +79,7 @@ class LibrarianDaemon(Process, LoggerBaseMixin):
79
79
  startup_tasks = (
80
80
  AdoptOrphanFoldersTask(),
81
81
  WatchdogSyncTask(),
82
- SearchIndexUpdateTask(False),
82
+ SearchIndexUpdateTask(rebuild=False),
83
83
  )
84
84
 
85
85
  for task in startup_tasks:
@@ -121,7 +121,7 @@ class LibrarianDaemon(Process, LoggerBaseMixin):
121
121
  case DelayedTasks():
122
122
  self._threads.delayed_tasks_thread.queue.put(task)
123
123
  case LibrarianShutdownTask():
124
- self.log.info(f"Shutting down {self.__class__.__name__}...")
124
+ self.log.info(f"Shutting down {self.name}...")
125
125
  self.run_loop = False
126
126
  case _:
127
127
  self.log.warning(f"Unhandled Librarian task: {task}")
@@ -150,34 +150,34 @@ class LibrarianDaemon(Process, LoggerBaseMixin):
150
150
 
151
151
  def _start_threads(self):
152
152
  """Start all librarian's threads."""
153
- self.log.debug(f"{self.__class__.__name__} starting all threads.")
153
+ self.log.debug(f"{self.name} starting all threads.")
154
154
  for thread in self._threads:
155
155
  thread.start()
156
- self.log.info(f"{self.__class__.__name__} started all threads.")
156
+ self.log.info(f"{self.name} started all threads.")
157
157
 
158
158
  def _startup(self):
159
159
  """Initialize threads."""
160
160
  self.init_logger(self.log_queue)
161
- self.log.debug(f"Started {self.__class__.__name__}.")
161
+ self.log.debug(f"Started {self.name}.")
162
162
  self.janitor = Janitor(self.log_queue, self.queue)
163
163
  self._create_threads() # can't do this in init.
164
164
  self._start_threads()
165
165
  self.run_loop = True
166
- self.log.info(f"{self.__class__.__name__} ready for tasks.")
166
+ self.log.info(f"{self.name} ready for tasks.")
167
167
 
168
168
  def _stop_threads(self):
169
169
  """Stop all librarian's threads."""
170
- self.log.debug(f"{self.__class__.__name__} stopping all threads...")
170
+ self.log.debug(f"{self.name} stopping all threads...")
171
171
  for thread in self._reversed_threads:
172
172
  thread.stop()
173
- self.log.debug(f"{self.__class__.__name__} stopped all threads.")
173
+ self.log.debug(f"{self.name} stopped all threads.")
174
174
 
175
175
  def _join_threads(self):
176
176
  """Join all librarian threads."""
177
- self.log.debug(f"{self.__class__.__name__} joining all threads...")
177
+ self.log.debug(f"{self.name} joining all threads...")
178
178
  for thread in self._reversed_threads:
179
179
  thread.join()
180
- self.log.info(f"{self.__class__.__name__} joined all threads.")
180
+ self.log.info(f"{self.name} joined all threads.")
181
181
 
182
182
  def _shutdown(self):
183
183
  """Shutdown threads and queues."""
@@ -188,12 +188,13 @@ class LibrarianDaemon(Process, LoggerBaseMixin):
188
188
  self.queue.get_nowait()
189
189
  self.queue.close()
190
190
  self.queue.join_thread()
191
- self.log.info(f"{self.__class__.__name__} finished.")
191
+ self.log.info(f"{self.name} finished.")
192
192
  self.log_queue.close()
193
193
  self.log_queue.join_thread()
194
194
 
195
195
  def run(self):
196
- """Process tasks from the queue.
196
+ """
197
+ Process tasks from the queue.
197
198
 
198
199
  This process also runs the crond thread and the Watchdog Observer
199
200
  threads.
@@ -205,11 +206,11 @@ class LibrarianDaemon(Process, LoggerBaseMixin):
205
206
  task = self.queue.get()
206
207
  self._process_task(task)
207
208
  except Exception:
208
- self.log.exception(f"In {self.__class__.__name__} loop")
209
+ self.log.exception(f"In {self.name} loop")
209
210
  except Exception:
210
- self.log.exception(f"{self.__class__.__name__} crashed.")
211
+ self.log.exception(f"{self.name} crashed.")
211
212
  except KeyboardInterrupt:
212
- self.log.debug(f"{self.__class__.__name__} Keyboard interrupt")
213
+ self.log.debug(f"{self.name} Keyboard interrupt")
213
214
  finally:
214
215
  self._shutdown()
215
216
 
@@ -16,7 +16,8 @@ class NotifierThread(AggregateMessageQueuedThread):
16
16
  self.cache[item.text] = item
17
17
 
18
18
  def _send_task(self, task):
19
- """Send a group_send message to the mulitprocess broadcast channel.
19
+ """
20
+ Send a group_send message to the mulitprocess broadcast channel.
20
21
 
21
22
  A random consumer awaiting the broadcast channel will consume it,
22
23
  and do a group_send with it's message.
@@ -22,7 +22,7 @@ class OptimizeMixin(QueuedThread):
22
22
  self.abort_event = abort_event
23
23
  super().__init__(*args, **kwargs)
24
24
 
25
- def optimize(self, janitor=False):
25
+ def optimize(self, janitor: bool):
26
26
  """Remove records not in the database from the index, trapping exceptions."""
27
27
  start_time = time()
28
28
  status = Status(SearchIndexStatusTypes.SEARCH_INDEX_OPTIMIZE)
@@ -21,7 +21,7 @@ class RemoveMixin(OptimizeMixin):
21
21
  self.status_controller.finish(clear_status)
22
22
  self.log.info("Old search index cleared.")
23
23
 
24
- def _remove_stale_records(self, status): # type: ignore
24
+ def _remove_stale_records(self, status):
25
25
  """Remove records not in the database from the index."""
26
26
  start_time = time()
27
27
  delete_comicfts = ComicFTS.objects.filter(comic__isnull=True)
@@ -114,7 +114,7 @@ class FTSUpdateMixin(RemoveMixin):
114
114
  return ""
115
115
  return ",".join((iso_code, field_instance.to_representation(iso_code)))
116
116
 
117
- def _get_comicts_fts_list(
117
+ def _get_comics_fts_list(
118
118
  self, comics, country_field, language_field, obj_list, create
119
119
  ):
120
120
  """Prepare a batch of search entries."""
@@ -157,14 +157,15 @@ class FTSUpdateMixin(RemoveMixin):
157
157
  if create:
158
158
  comicfts.created_at = now
159
159
  obj_list.append(comicfts)
160
+ self.log.debug(f"{len(obj_list)}/{comics.count()} entries prepped.")
160
161
 
161
- def _get_comicfts_list(self, comics, create=False):
162
+ def _get_comicfts_list(self, comics, create: bool):
162
163
  """Create a ComicFTS object for bulk_create or bulk_update."""
163
164
  country_field = CountryField()
164
165
  language_field = LanguageField()
165
166
  obj_list = []
166
167
  comics = self._annotate_fts_query(comics)
167
- self._get_comicts_fts_list(
168
+ self._get_comics_fts_list(
168
169
  comics, country_field, language_field, obj_list, create
169
170
  )
170
171
  return obj_list
@@ -177,7 +178,7 @@ class FTSUpdateMixin(RemoveMixin):
177
178
  self.log.debug(f"{verb} no search entries.")
178
179
  self.status_controller.finish(status)
179
180
 
180
- def _update_search_index_operate(self, comics_qs, create=False):
181
+ def _update_search_index_operate(self, comics_qs, create: bool):
181
182
  count = comics_qs.count()
182
183
  verb = "create" if create else "update"
183
184
  if not count:
@@ -205,11 +206,14 @@ class FTSUpdateMixin(RemoveMixin):
205
206
  batch_start = time()
206
207
  batch_to = batch_from + SEARCH_INDEX_BATCH_SIZE
207
208
  comics_batch = comics_qs[batch_from:batch_to]
208
-
209
+ self.log.debug(
210
+ f"Checking {comics_batch.count()}/{count} comics for search index operations..."
211
+ )
209
212
  if self.abort_event.is_set():
210
213
  break
211
214
  operate_comicfts = self._get_comicfts_list(comics_batch, create)
212
215
  operate_comicfts_count = len(operate_comicfts)
216
+ self.log.debug(f"{verb}ing {operate_comicfts_count} search entries...")
213
217
  if self.abort_event.is_set():
214
218
  break
215
219
  if create:
@@ -223,7 +227,7 @@ class FTSUpdateMixin(RemoveMixin):
223
227
  batch_time = time() - batch_start
224
228
  eps = round(count / batch_time)
225
229
  self.log.debug(
226
- f"{verb} {count}/{operate_comicfts_count} search entries in {batch_time}, {eps} per second."
230
+ f"{verb} {operate_comicfts_count}/{count} search entries in {batch_time}, {eps} per second."
227
231
  )
228
232
  batch_from = batch_to
229
233
  finally:
@@ -281,7 +285,7 @@ class FTSUpdateMixin(RemoveMixin):
281
285
  elapsed = naturaldelta(elapsed_time)
282
286
  self.log.info(f"Search index updated in {elapsed}.")
283
287
 
284
- def update_search_index(self, rebuild=False):
288
+ def update_search_index(self, rebuild: bool):
285
289
  """Update or Rebuild the search index."""
286
290
  start_time = time()
287
291
  self.abort_event.clear()
@@ -62,11 +62,12 @@ class CodexStats:
62
62
  request_model_set = self.params.get(key, {})
63
63
  all_models = _KEY_MODELS_MAP[key]
64
64
  if request_model_set:
65
- models = []
66
- for model_name in request_model_set:
67
- for model in all_models:
68
- if model.__name__.lower() == model_name.lower():
69
- models.append(model)
65
+ models = [
66
+ model
67
+ for model in all_models
68
+ for model_name in request_model_set
69
+ if model.__name__.lower() == model_name.lower()
70
+ ]
70
71
  else:
71
72
  models = all_models
72
73
  return tuple(models)
@@ -149,7 +150,7 @@ class CodexStats:
149
150
 
150
151
  def _add_file_types(self, obj):
151
152
  """Query for file types."""
152
- if self.params and "fileTypes" not in self.params:
153
+ if self.params and "file_types" not in self.params:
153
154
  return
154
155
  file_types = {}
155
156
  qs = (
@@ -68,7 +68,6 @@ def _send_telemetry(log):
68
68
  stats = CodexStats().get()
69
69
  data = {"stats": stats, "uuid": ts.version}
70
70
  _post_stats(log, data)
71
- # log.debug("Sent anonymous stats")
72
71
  ts.save() # update updated_at
73
72
 
74
73
 
@@ -61,12 +61,12 @@ class CodexDatabaseSnapshot(DirectorySnapshot, LoggerBaseMixin):
61
61
  def __init__(
62
62
  self,
63
63
  path,
64
- _recursive=True, # unused, always recursive
64
+ _recursive=True, # noqa: FBT002 unused, always recursive
65
65
  stat=os.stat,
66
66
  _listdir=os.listdir, # unused for database
67
- force=False,
67
+ force=False, # noqa: FBT002
68
68
  log_queue=None,
69
- covers_only=False,
69
+ covers_only=False, # noqa: FBT002
70
70
  ):
71
71
  """Initialize like DirectorySnapshot but use a database walk."""
72
72
  self._covers_only = covers_only
@@ -33,7 +33,8 @@ class CodexDirectorySnapshotDiff(DirectorySnapshotDiff):
33
33
  return self._get_inode(data.ref, path) == self._get_inode(data.snapshot, path)
34
34
 
35
35
  def _is_stats_equal(self, data, old_path, new_path):
36
- """Return if the mtime and size are equal.
36
+ """
37
+ Return if the mtime and size are equal.
37
38
 
38
39
  For old paths in the ref and new paths in the snapshot.
39
40
  """
@@ -84,9 +85,7 @@ class CodexDirectorySnapshotDiff(DirectorySnapshotDiff):
84
85
  if not self._is_stats_equal(data, old_path, new_path):
85
86
  data.modified.add(new_path)
86
87
 
87
- def __init__( # C901, PLR0912
88
- self, ref, snapshot, ignore_device=False, inode_only_modified=False
89
- ):
88
+ def __init__(self, ref, snapshot, ignore_device: bool, inode_only_modified: bool):
90
89
  """Create diff object."""
91
90
  self._ignore_device = ignore_device
92
91
  self._inode_only_modified = inode_only_modified
@@ -46,14 +46,14 @@ class DatabasePollingEmitter(EventEmitter, WorkerBaseMixin):
46
46
 
47
47
  _DIR_NOT_FOUND_TIMEOUT = 15 * 60
48
48
 
49
- def __init__( # noqa PLR0913
49
+ def __init__( # noqa: PLR0913
50
50
  self,
51
51
  event_queue,
52
52
  watch,
53
53
  timeout=DEFAULT_EMITTER_TIMEOUT,
54
54
  log_queue=None,
55
55
  librarian_queue=None,
56
- covers_only=False,
56
+ covers_only=False, # noqa: FBT002
57
57
  ):
58
58
  """Initialize snapshot methods."""
59
59
  self.init_worker(log_queue, librarian_queue)
@@ -72,7 +72,7 @@ class DatabasePollingEmitter(EventEmitter, WorkerBaseMixin):
72
72
  # default stat and listdir params
73
73
  )
74
74
 
75
- def poll(self, force=False):
75
+ def poll(self, force: bool):
76
76
  """Poll now, sooner than timeout."""
77
77
  self._force = force
78
78
  with self._poll_cond:
@@ -118,7 +118,7 @@ class DatabasePollingEmitter(EventEmitter, WorkerBaseMixin):
118
118
  return ok
119
119
 
120
120
  @property
121
- def timeout(self) -> int | None: # type: ignore
121
+ def timeout(self) -> int | None: # type: ignore[reportIncompatibleMethodOverride]
122
122
  """Get the timeout for this emitter from its library."""
123
123
  # The timeout from the constructor, self._timeout, is thrown away in favor
124
124
  # of a dynamic timeout from the database.
@@ -1,4 +1,5 @@
1
- """Batch watchdog events into bulk database tasks.
1
+ """
2
+ Batch watchdog events into bulk database tasks.
2
3
 
3
4
  Watchdog actually starts events as bulk events with the DirSnapshotDiff
4
5
  but the built-in filesystem event emitters serialize them, so the most
@@ -198,8 +198,7 @@ class CodexLibraryEventHandler(CodexEventHandlerBase):
198
198
  task = WatchdogEventTask(self.library_pk, sub_event)
199
199
  self.librarian_queue.put(task)
200
200
 
201
- # Calls stub event dispatchers
202
- # super().dispatch(event)
201
+ # Do not call super dispatch to call stub event dispatchers
203
202
  except Exception:
204
203
  self.log.exception(f"{self.__class__.__name__} dispatch")
205
204
 
@@ -1,5 +1,6 @@
1
1
  """The Codex Library Watchdog Observer threads."""
2
2
 
3
+ from watchdog.events import FileSystemEvent, FileSystemEventHandler
3
4
  from watchdog.observers import Observer
4
5
  from watchdog.observers.api import (
5
6
  DEFAULT_OBSERVER_TIMEOUT,
@@ -98,14 +99,16 @@ class UatuMixin(BaseObserver, WorkerBaseMixin):
98
99
  except Exception:
99
100
  self.log.exception(f"{self.__class__.__name__} sync library watches")
100
101
 
101
- def schedule( # type: ignore
102
+ def schedule(
102
103
  self,
103
- event_handler,
104
- path,
105
- recursive=False,
106
- _event_filter=None,
107
- ):
108
- """Override BaseObserver for Codex emitter class.
104
+ event_handler: FileSystemEventHandler,
105
+ path: str,
106
+ *,
107
+ recursive: bool = False,
108
+ event_filter: list[type[FileSystemEvent]] | None = None, # noqa: ARG002, F841, RUF100
109
+ ) -> ObservedWatch:
110
+ """
111
+ Override BaseObserver for Codex emitter class.
109
112
 
110
113
  https://pythonhosted.org/watchdog/_modules/watchdog/observers/api.html#BaseObserver
111
114
  """
@@ -137,9 +140,11 @@ class UatuMixin(BaseObserver, WorkerBaseMixin):
137
140
  # watchdog class structure doesn't work that way.
138
141
 
139
142
 
140
- class LibraryEventObserver(UatuMixin, Observer): # type: ignore
143
+ class LibraryEventObserver(UatuMixin, Observer): # type: ignore[reportGeneralTypeIssues]
141
144
  """Regular observer."""
142
145
 
146
+ # Observer is a dynamically generated class by platform at runtime.
147
+
143
148
  ENABLE_FIELD = "events"
144
149
 
145
150
 
@@ -156,7 +161,7 @@ class LibraryPollingObserver(UatuMixin):
156
161
  *args, emitter_class=DatabasePollingEmitter, timeout=timeout, **kwargs
157
162
  )
158
163
 
159
- def poll(self, library_pks, force=False):
164
+ def poll(self, library_pks, force: bool):
160
165
  """Poll each requested emitter."""
161
166
  try:
162
167
  qs = Library.objects.all()
@@ -165,7 +170,7 @@ class LibraryPollingObserver(UatuMixin):
165
170
  paths = frozenset(qs.values_list("path", flat=True))
166
171
 
167
172
  for emitter in self.emitters:
168
- polling_emitter: DatabasePollingEmitter = emitter # type: ignore
173
+ polling_emitter: DatabasePollingEmitter = emitter # type: ignore[reportAssignmentType]
169
174
  if emitter.watch.path in paths:
170
175
  polling_emitter.poll(force)
171
176
  except Exception: