codex 1.6.0a3__py3-none-any.whl → 1.6.0a5__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.
- codex/exceptions.py +17 -6
- codex/integrity.py +67 -3
- codex/librarian/covers/coverd.py +2 -2
- codex/librarian/covers/create.py +29 -13
- codex/librarian/covers/path.py +8 -6
- codex/librarian/covers/purge.py +27 -16
- codex/librarian/covers/tasks.py +3 -2
- codex/librarian/importer/aggregate_metadata.py +2 -2
- codex/librarian/importer/const.py +23 -7
- codex/librarian/importer/create_fks.py +88 -28
- codex/librarian/importer/deleted.py +26 -2
- codex/librarian/importer/importerd.py +124 -27
- codex/librarian/importer/link_comics.py +55 -0
- codex/librarian/importer/moved.py +78 -3
- codex/librarian/importer/query_fks.py +68 -4
- codex/librarian/importer/status.py +6 -0
- codex/librarian/importer/tasks.py +11 -3
- codex/librarian/importer/update_comics.py +1 -3
- codex/librarian/janitor/cleanup.py +24 -0
- codex/librarian/janitor/failed_imports.py +1 -1
- codex/librarian/janitor/janitor.py +5 -0
- codex/librarian/janitor/janitord.py +1 -1
- codex/librarian/janitor/status.py +1 -0
- codex/librarian/janitor/tasks.py +5 -0
- codex/librarian/librariand.py +3 -3
- codex/librarian/search/update.py +1 -1
- codex/librarian/watchdog/db_snapshot.py +9 -6
- codex/librarian/watchdog/emitter.py +3 -0
- codex/librarian/watchdog/event_batcherd.py +19 -3
- codex/librarian/watchdog/events.py +176 -36
- codex/librarian/watchdog/observers.py +13 -3
- codex/migrations/0027_sort_name.py +2 -12
- codex/migrations/0028_custom_covers.py +166 -0
- codex/models/admin.py +0 -1
- codex/models/base.py +3 -0
- codex/models/comic.py +15 -9
- codex/models/groups.py +30 -14
- codex/models/library.py +11 -3
- codex/models/paths.py +62 -14
- codex/models/{const.py → util.py} +15 -2
- codex/serializers/admin.py +11 -2
- codex/serializers/browser/mixins.py +1 -0
- codex/serializers/browser/settings.py +3 -0
- codex/settings/settings.py +11 -5
- codex/startup.py +77 -3
- codex/static_root/assets/{VCheckbox-CRu3BJ5D.48cbd6b412f4.js → VCheckbox-BF_99tgB.7fe59e56d9d4.js} +1 -1
- codex/static_root/assets/VCheckbox-BF_99tgB.7fe59e56d9d4.js.br +0 -0
- codex/static_root/assets/VCheckbox-BF_99tgB.7fe59e56d9d4.js.gz +0 -0
- codex/static_root/assets/{VCheckbox-CRu3BJ5D.js → VCheckbox-BF_99tgB.js} +1 -1
- codex/static_root/assets/VCheckbox-BF_99tgB.js.br +0 -0
- codex/static_root/assets/VCheckbox-BF_99tgB.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-CAUrQoP4.b162429d9a68.js → VCheckboxBtn-Coc7g8m7.31e1e6aa44c9.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-Coc7g8m7.31e1e6aa44c9.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-Coc7g8m7.31e1e6aa44c9.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-CAUrQoP4.js → VCheckboxBtn-Coc7g8m7.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-Coc7g8m7.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-Coc7g8m7.js.gz +0 -0
- codex/static_root/assets/VCombobox-CTRWnOuM.0f00903c2ebc.js +1 -0
- codex/static_root/assets/VCombobox-CTRWnOuM.0f00903c2ebc.js.br +0 -0
- codex/static_root/assets/VCombobox-CTRWnOuM.0f00903c2ebc.js.gz +0 -0
- codex/static_root/assets/VCombobox-CTRWnOuM.js +1 -0
- codex/static_root/assets/VCombobox-CTRWnOuM.js.br +0 -0
- codex/static_root/assets/VCombobox-CTRWnOuM.js.gz +0 -0
- codex/static_root/assets/{VDialog-BcnzrzZO.7fa7ec337394.js → VDialog-pzwzInEh.51acf566a069.js} +1 -1
- codex/static_root/assets/VDialog-pzwzInEh.51acf566a069.js.br +0 -0
- codex/static_root/assets/VDialog-pzwzInEh.51acf566a069.js.gz +0 -0
- codex/static_root/assets/{VDialog-BcnzrzZO.js → VDialog-pzwzInEh.js} +1 -1
- codex/static_root/assets/VDialog-pzwzInEh.js.br +0 -0
- codex/static_root/assets/VDialog-pzwzInEh.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-DP3HSBJj.a5600e541dc2.js → VExpansionPanels-CKSq1GpG.0ecf702c5b67.js} +1 -1
- codex/static_root/assets/VExpansionPanels-CKSq1GpG.0ecf702c5b67.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-CKSq1GpG.0ecf702c5b67.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-DP3HSBJj.js → VExpansionPanels-CKSq1GpG.js} +1 -1
- codex/static_root/assets/VExpansionPanels-CKSq1GpG.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-CKSq1GpG.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-B9OZxVQw.28f10e381149.js → VRadioGroup-CW5GobGU.b72925bca3de.js} +1 -1
- codex/static_root/assets/VRadioGroup-CW5GobGU.b72925bca3de.js.br +0 -0
- codex/static_root/assets/VRadioGroup-CW5GobGU.b72925bca3de.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-B9OZxVQw.js → VRadioGroup-CW5GobGU.js} +1 -1
- codex/static_root/assets/VRadioGroup-CW5GobGU.js.br +0 -0
- codex/static_root/assets/VRadioGroup-CW5GobGU.js.gz +0 -0
- codex/static_root/assets/VSelect-ChOlLRyH.00b11751b25e.js +1 -0
- codex/static_root/assets/VSelect-ChOlLRyH.00b11751b25e.js.br +0 -0
- codex/static_root/assets/VSelect-ChOlLRyH.00b11751b25e.js.gz +0 -0
- codex/static_root/assets/VSelect-ChOlLRyH.js +1 -0
- codex/static_root/assets/VSelect-ChOlLRyH.js.br +0 -0
- codex/static_root/assets/VSelect-ChOlLRyH.js.gz +0 -0
- codex/static_root/assets/VSelect-MGVSeLgr.7cabd30bc5e4.css +1 -0
- codex/static_root/assets/VSelect-MGVSeLgr.7cabd30bc5e4.css.br +0 -0
- codex/static_root/assets/VSelect-MGVSeLgr.7cabd30bc5e4.css.gz +0 -0
- codex/static_root/assets/VSelect-MGVSeLgr.css +1 -0
- codex/static_root/assets/VSelect-MGVSeLgr.css.br +0 -0
- codex/static_root/assets/VSelect-MGVSeLgr.css.gz +0 -0
- codex/static_root/assets/{VSelectionControl-gDbXN6J_.js → VSelectionControl-DKOhc2zB.061dca094303.js} +1 -1
- codex/static_root/assets/VSelectionControl-DKOhc2zB.061dca094303.js.br +0 -0
- codex/static_root/assets/VSelectionControl-DKOhc2zB.061dca094303.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-gDbXN6J_.137a5bce3954.js → VSelectionControl-DKOhc2zB.js} +1 -1
- codex/static_root/assets/VSelectionControl-DKOhc2zB.js.br +0 -0
- codex/static_root/assets/VSelectionControl-DKOhc2zB.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-D8FKczaP.3c2d0e591ae3.js → VSlideGroup-zFz5_byd.e0e246b7acbb.js} +1 -1
- codex/static_root/assets/VSlideGroup-zFz5_byd.e0e246b7acbb.js.br +0 -0
- codex/static_root/assets/VSlideGroup-zFz5_byd.e0e246b7acbb.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-D8FKczaP.js → VSlideGroup-zFz5_byd.js} +1 -1
- codex/static_root/assets/VSlideGroup-zFz5_byd.js.br +0 -0
- codex/static_root/assets/VSlideGroup-zFz5_byd.js.gz +0 -0
- codex/static_root/assets/{VTable-D86x2F7y.60c6356a0b73.js → VTable-FKMTcdkF.6c1eed84d25e.js} +1 -1
- codex/static_root/assets/VTable-FKMTcdkF.6c1eed84d25e.js.br +0 -0
- codex/static_root/assets/VTable-FKMTcdkF.6c1eed84d25e.js.gz +0 -0
- codex/static_root/assets/{VTable-D86x2F7y.js → VTable-FKMTcdkF.js} +1 -1
- codex/static_root/assets/VTable-FKMTcdkF.js.br +0 -0
- codex/static_root/assets/VTable-FKMTcdkF.js.gz +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.4cc388b4aa3c.css +1 -0
- codex/static_root/assets/VTextField-BssVoDhB.4cc388b4aa3c.css.br +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.4cc388b4aa3c.css.gz +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.css +1 -0
- codex/static_root/assets/VTextField-BssVoDhB.css.br +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.css.gz +0 -0
- codex/static_root/assets/VTextField-Dftcik85.cb2f1dda87e1.js +1 -0
- codex/static_root/assets/VTextField-Dftcik85.cb2f1dda87e1.js.br +0 -0
- codex/static_root/assets/VTextField-Dftcik85.cb2f1dda87e1.js.gz +0 -0
- codex/static_root/assets/VTextField-Dftcik85.js +1 -0
- codex/static_root/assets/VTextField-Dftcik85.js.br +0 -0
- codex/static_root/assets/VTextField-Dftcik85.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-aBb7Akq5.f0d7de98e392.js → VWindowItem-CYCwnt3s.28025dc36c6a.js} +1 -1
- codex/static_root/assets/VWindowItem-CYCwnt3s.28025dc36c6a.js.br +0 -0
- codex/static_root/assets/VWindowItem-CYCwnt3s.28025dc36c6a.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-aBb7Akq5.js → VWindowItem-CYCwnt3s.js} +1 -1
- codex/static_root/assets/VWindowItem-CYCwnt3s.js.br +0 -0
- codex/static_root/assets/VWindowItem-CYCwnt3s.js.gz +0 -0
- codex/static_root/assets/{admin-BbrOU9Y9.29936748af9e.css → admin-B8Bp2Uih.82c98714bcf1.css} +1 -1
- codex/static_root/assets/admin-B8Bp2Uih.82c98714bcf1.css.br +0 -0
- codex/static_root/assets/admin-B8Bp2Uih.82c98714bcf1.css.gz +0 -0
- codex/static_root/assets/{admin-BbrOU9Y9.css → admin-B8Bp2Uih.css} +1 -1
- codex/static_root/assets/admin-B8Bp2Uih.css.br +0 -0
- codex/static_root/assets/admin-B8Bp2Uih.css.gz +0 -0
- codex/static_root/assets/admin-DH_DrB0F.dc45fb726e07.js +1 -0
- codex/static_root/assets/admin-DH_DrB0F.dc45fb726e07.js.br +0 -0
- codex/static_root/assets/admin-DH_DrB0F.dc45fb726e07.js.gz +0 -0
- codex/static_root/assets/admin-DH_DrB0F.js +1 -0
- codex/static_root/assets/admin-DH_DrB0F.js.br +0 -0
- codex/static_root/assets/admin-DH_DrB0F.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-B2rmpAVA.a9e72fbfdadc.js +30 -0
- codex/static_root/assets/admin-drawer-panel-B2rmpAVA.a9e72fbfdadc.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-B2rmpAVA.a9e72fbfdadc.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-B2rmpAVA.js +30 -0
- codex/static_root/assets/admin-drawer-panel-B2rmpAVA.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-B2rmpAVA.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-BHdNPwzF.bd2c1d6148bb.css +1 -0
- codex/static_root/assets/admin-drawer-panel-BHdNPwzF.bd2c1d6148bb.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BHdNPwzF.bd2c1d6148bb.css.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-BHdNPwzF.css +1 -0
- codex/static_root/assets/admin-drawer-panel-BHdNPwzF.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BHdNPwzF.css.gz +0 -0
- codex/static_root/assets/browser-CpppBvim.a1b5d4fe97b1.css +1 -0
- codex/static_root/assets/browser-CpppBvim.a1b5d4fe97b1.css.br +0 -0
- codex/static_root/assets/browser-CpppBvim.a1b5d4fe97b1.css.gz +0 -0
- codex/static_root/assets/browser-CpppBvim.css +1 -0
- codex/static_root/assets/browser-CpppBvim.css.br +0 -0
- codex/static_root/assets/browser-CpppBvim.css.gz +0 -0
- codex/static_root/assets/browser-lKU7rqLd.cdb86e625ed9.js +1 -0
- codex/static_root/assets/browser-lKU7rqLd.cdb86e625ed9.js.br +0 -0
- codex/static_root/assets/browser-lKU7rqLd.cdb86e625ed9.js.gz +0 -0
- codex/static_root/assets/browser-lKU7rqLd.js +1 -0
- codex/static_root/assets/browser-lKU7rqLd.js.br +0 -0
- codex/static_root/assets/browser-lKU7rqLd.js.gz +0 -0
- codex/static_root/assets/{change-password-dialog-DywVK04u.eabe6b4c3e27.js → change-password-dialog-BIBG6Bk8.3583021c124a.js} +1 -1
- codex/static_root/assets/change-password-dialog-BIBG6Bk8.3583021c124a.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BIBG6Bk8.3583021c124a.js.gz +0 -0
- codex/static_root/assets/{change-password-dialog-DywVK04u.js → change-password-dialog-BIBG6Bk8.js} +1 -1
- codex/static_root/assets/change-password-dialog-BIBG6Bk8.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BIBG6Bk8.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-UnMzYsqN.d732afc0dc59.js → confirm-dialog-DARLmXRf.53fc6938fb8c.js} +1 -1
- codex/static_root/assets/confirm-dialog-DARLmXRf.53fc6938fb8c.js.br +0 -0
- codex/static_root/assets/confirm-dialog-DARLmXRf.53fc6938fb8c.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-UnMzYsqN.js → confirm-dialog-DARLmXRf.js} +1 -1
- codex/static_root/assets/confirm-dialog-DARLmXRf.js.br +0 -0
- codex/static_root/assets/confirm-dialog-DARLmXRf.js.gz +0 -0
- codex/static_root/assets/{datetime-column-IeiZdinf.e2807c847ddc.js → datetime-column-LpLgWpkf.16ce3324970f.js} +1 -1
- codex/static_root/assets/datetime-column-LpLgWpkf.16ce3324970f.js.br +0 -0
- codex/static_root/assets/datetime-column-LpLgWpkf.16ce3324970f.js.gz +0 -0
- codex/static_root/assets/{datetime-column-IeiZdinf.js → datetime-column-LpLgWpkf.js} +1 -1
- codex/static_root/assets/datetime-column-LpLgWpkf.js.br +0 -0
- codex/static_root/assets/datetime-column-LpLgWpkf.js.gz +0 -0
- codex/static_root/assets/{filter-BT3OCu_E.39135c83c357.js → filter-jRB1Ob6r.6a559a53e805.js} +1 -1
- codex/static_root/assets/filter-jRB1Ob6r.6a559a53e805.js.br +0 -0
- codex/static_root/assets/filter-jRB1Ob6r.6a559a53e805.js.gz +0 -0
- codex/static_root/assets/{filter-BT3OCu_E.js → filter-jRB1Ob6r.js} +1 -1
- codex/static_root/assets/filter-jRB1Ob6r.js.br +0 -0
- codex/static_root/assets/filter-jRB1Ob6r.js.gz +0 -0
- codex/static_root/assets/flag-tab-BNwbLfrN.b755a99fff7e.css +1 -0
- codex/static_root/assets/flag-tab-BNwbLfrN.b755a99fff7e.css.br +0 -0
- codex/static_root/assets/flag-tab-BNwbLfrN.b755a99fff7e.css.gz +0 -0
- codex/static_root/assets/flag-tab-BNwbLfrN.css +1 -0
- codex/static_root/assets/flag-tab-BNwbLfrN.css.br +0 -0
- codex/static_root/assets/flag-tab-BNwbLfrN.css.gz +0 -0
- codex/static_root/assets/flag-tab-mYS2wg5e.17829c46cae9.js +1 -0
- codex/static_root/assets/flag-tab-mYS2wg5e.17829c46cae9.js.br +0 -0
- codex/static_root/assets/flag-tab-mYS2wg5e.17829c46cae9.js.gz +0 -0
- codex/static_root/assets/flag-tab-mYS2wg5e.js +1 -0
- codex/static_root/assets/flag-tab-mYS2wg5e.js.br +0 -0
- codex/static_root/assets/flag-tab-mYS2wg5e.js.gz +0 -0
- codex/static_root/assets/{group-tab-Bt_AURnL.59aa6b13b14b.js → group-tab-MK1lcjUU.98406d5babdc.js} +1 -1
- codex/static_root/assets/group-tab-MK1lcjUU.98406d5babdc.js.br +0 -0
- codex/static_root/assets/group-tab-MK1lcjUU.98406d5babdc.js.gz +0 -0
- codex/static_root/assets/{group-tab-Bt_AURnL.js → group-tab-MK1lcjUU.js} +1 -1
- codex/static_root/assets/group-tab-MK1lcjUU.js.br +0 -0
- codex/static_root/assets/group-tab-MK1lcjUU.js.gz +0 -0
- codex/static_root/assets/http-error-DKulXuTl.95e42988d5d5.css +1 -0
- codex/static_root/assets/{http-error-_wlDqEcp.5b78d3e332c9.css.br → http-error-DKulXuTl.95e42988d5d5.css.br} +0 -0
- codex/static_root/assets/http-error-DKulXuTl.95e42988d5d5.css.gz +0 -0
- codex/static_root/assets/http-error-DKulXuTl.css +1 -0
- codex/static_root/assets/{http-error-_wlDqEcp.css.br → http-error-DKulXuTl.css.br} +0 -0
- codex/static_root/assets/http-error-DKulXuTl.css.gz +0 -0
- codex/static_root/assets/http-error-HFeYnF0n.a3c578a0265e.js +1 -0
- codex/static_root/assets/http-error-HFeYnF0n.a3c578a0265e.js.br +0 -0
- codex/static_root/assets/http-error-HFeYnF0n.a3c578a0265e.js.gz +0 -0
- codex/static_root/assets/http-error-HFeYnF0n.js +1 -0
- codex/static_root/assets/http-error-HFeYnF0n.js.br +0 -0
- codex/static_root/assets/http-error-HFeYnF0n.js.gz +0 -0
- codex/static_root/assets/library-tab-BN0SfPcH.913e236f625e.css +1 -0
- codex/static_root/assets/library-tab-BN0SfPcH.913e236f625e.css.br +0 -0
- codex/static_root/assets/library-tab-BN0SfPcH.913e236f625e.css.gz +0 -0
- codex/static_root/assets/library-tab-BN0SfPcH.css +1 -0
- codex/static_root/assets/library-tab-BN0SfPcH.css.br +0 -0
- codex/static_root/assets/library-tab-BN0SfPcH.css.gz +0 -0
- codex/static_root/assets/library-tab-DYeEBYlT.a2a2ef088d1c.js +1 -0
- codex/static_root/assets/library-tab-DYeEBYlT.a2a2ef088d1c.js.br +0 -0
- codex/static_root/assets/library-tab-DYeEBYlT.a2a2ef088d1c.js.gz +0 -0
- codex/static_root/assets/library-tab-DYeEBYlT.js +1 -0
- codex/static_root/assets/library-tab-DYeEBYlT.js.br +0 -0
- codex/static_root/assets/library-tab-DYeEBYlT.js.gz +0 -0
- codex/static_root/assets/main-gSW7TFDY.329223b148d4.js +32 -0
- codex/static_root/assets/main-gSW7TFDY.329223b148d4.js.br +0 -0
- codex/static_root/assets/main-gSW7TFDY.329223b148d4.js.gz +0 -0
- codex/static_root/assets/main-gSW7TFDY.js +32 -0
- codex/static_root/assets/main-gSW7TFDY.js.br +0 -0
- codex/static_root/assets/main-gSW7TFDY.js.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-B3wS4_7p.7695fafdefce.css → pagination-toolbar-ClZui9Zf.697d7ae11c21.css} +1 -1
- codex/static_root/assets/pagination-toolbar-ClZui9Zf.697d7ae11c21.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-ClZui9Zf.697d7ae11c21.css.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-B3wS4_7p.css → pagination-toolbar-ClZui9Zf.css} +1 -1
- codex/static_root/assets/pagination-toolbar-ClZui9Zf.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-ClZui9Zf.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-Dlm70Bhs.8f23f8bd9a05.js +1 -0
- codex/static_root/assets/pagination-toolbar-Dlm70Bhs.8f23f8bd9a05.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-Dlm70Bhs.8f23f8bd9a05.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-Dlm70Bhs.js +1 -0
- codex/static_root/assets/pagination-toolbar-Dlm70Bhs.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-Dlm70Bhs.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-DNwjWxO_.70b904e8e4ff.js → pdf-doc-BTdS9hUz.7c966524280a.js} +1 -1
- codex/static_root/assets/pdf-doc-BTdS9hUz.7c966524280a.js.br +0 -0
- codex/static_root/assets/pdf-doc-BTdS9hUz.7c966524280a.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-DNwjWxO_.js → pdf-doc-BTdS9hUz.js} +1 -1
- codex/static_root/assets/pdf-doc-BTdS9hUz.js.br +0 -0
- codex/static_root/assets/pdf-doc-BTdS9hUz.js.gz +0 -0
- codex/static_root/assets/{reader-CScIyWY8.0f2b4c8ea2bf.js → reader-BtSTIETq.f940f66c0e58.js} +2 -2
- codex/static_root/assets/reader-BtSTIETq.f940f66c0e58.js.br +0 -0
- codex/static_root/assets/reader-BtSTIETq.f940f66c0e58.js.gz +0 -0
- codex/static_root/assets/{reader-CScIyWY8.js → reader-BtSTIETq.js} +2 -2
- codex/static_root/assets/reader-BtSTIETq.js.br +0 -0
- codex/static_root/assets/reader-BtSTIETq.js.gz +0 -0
- codex/static_root/assets/{reader-pqgXBr7J.92a23ab06864.css → reader-CF3xt6JG.19fad7f62450.css} +1 -1
- codex/static_root/assets/reader-CF3xt6JG.19fad7f62450.css.br +0 -0
- codex/static_root/assets/reader-CF3xt6JG.19fad7f62450.css.gz +0 -0
- codex/static_root/assets/{reader-pqgXBr7J.css → reader-CF3xt6JG.css} +1 -1
- codex/static_root/assets/reader-CF3xt6JG.css.br +0 -0
- codex/static_root/assets/reader-CF3xt6JG.css.gz +0 -0
- codex/static_root/assets/{relation-chips-D6T6FX7G.css → relation-chips-Bsc-gUxE.98e65384c3c9.css} +1 -1
- codex/static_root/assets/relation-chips-Bsc-gUxE.98e65384c3c9.css.br +0 -0
- codex/static_root/assets/relation-chips-Bsc-gUxE.98e65384c3c9.css.gz +0 -0
- codex/static_root/assets/{relation-chips-D6T6FX7G.db095b2497e4.css → relation-chips-Bsc-gUxE.css} +1 -1
- codex/static_root/assets/relation-chips-Bsc-gUxE.css.br +0 -0
- codex/static_root/assets/relation-chips-Bsc-gUxE.css.gz +0 -0
- codex/static_root/assets/relation-chips-C4Ob7ySi.95855a010f4a.js +1 -0
- codex/static_root/assets/relation-chips-C4Ob7ySi.95855a010f4a.js.br +0 -0
- codex/static_root/assets/relation-chips-C4Ob7ySi.95855a010f4a.js.gz +0 -0
- codex/static_root/assets/relation-chips-C4Ob7ySi.js +1 -0
- codex/static_root/assets/relation-chips-C4Ob7ySi.js.br +0 -0
- codex/static_root/assets/relation-chips-C4Ob7ySi.js.gz +0 -0
- codex/static_root/assets/settings-drawer-BJOfMtqA.6471a50fc05b.css +1 -0
- codex/static_root/assets/settings-drawer-BJOfMtqA.6471a50fc05b.css.br +0 -0
- codex/static_root/assets/settings-drawer-BJOfMtqA.6471a50fc05b.css.gz +0 -0
- codex/static_root/assets/settings-drawer-BJOfMtqA.css +1 -0
- codex/static_root/assets/settings-drawer-BJOfMtqA.css.br +0 -0
- codex/static_root/assets/settings-drawer-BJOfMtqA.css.gz +0 -0
- codex/static_root/assets/settings-drawer-xSctoxZn.4ce8afcb879a.js +2 -0
- codex/static_root/assets/settings-drawer-xSctoxZn.4ce8afcb879a.js.br +0 -0
- codex/static_root/assets/settings-drawer-xSctoxZn.4ce8afcb879a.js.gz +0 -0
- codex/static_root/assets/settings-drawer-xSctoxZn.js +2 -0
- codex/static_root/assets/settings-drawer-xSctoxZn.js.br +0 -0
- codex/static_root/assets/settings-drawer-xSctoxZn.js.gz +0 -0
- codex/static_root/assets/{stats-tab-Bn9lHtZb.b2969fd36ae9.js → stats-tab-C_uC_U7o.e6b014b6e8c6.js} +1 -1
- codex/static_root/assets/stats-tab-C_uC_U7o.e6b014b6e8c6.js.br +0 -0
- codex/static_root/assets/stats-tab-C_uC_U7o.e6b014b6e8c6.js.gz +0 -0
- codex/static_root/assets/{stats-tab-Bn9lHtZb.js → stats-tab-C_uC_U7o.js} +1 -1
- codex/static_root/assets/stats-tab-C_uC_U7o.js.br +0 -0
- codex/static_root/assets/stats-tab-C_uC_U7o.js.gz +0 -0
- codex/static_root/assets/task-tab-VIpy1Ula.c07877250c88.js +1 -0
- codex/static_root/assets/task-tab-VIpy1Ula.c07877250c88.js.br +0 -0
- codex/static_root/assets/task-tab-VIpy1Ula.c07877250c88.js.gz +0 -0
- codex/static_root/assets/task-tab-VIpy1Ula.js +1 -0
- codex/static_root/assets/task-tab-VIpy1Ula.js.br +0 -0
- codex/static_root/assets/task-tab-VIpy1Ula.js.gz +0 -0
- codex/static_root/assets/{unauthorized-DWgytUow.ca2f13dbdbf5.css → unauthorized-DHV6Q1n-.b7847b2872a1.css} +1 -1
- codex/static_root/assets/unauthorized-DHV6Q1n-.b7847b2872a1.css.br +0 -0
- codex/static_root/assets/unauthorized-DHV6Q1n-.b7847b2872a1.css.gz +0 -0
- codex/static_root/assets/{unauthorized-DWgytUow.css → unauthorized-DHV6Q1n-.css} +1 -1
- codex/static_root/assets/unauthorized-DHV6Q1n-.css.br +0 -0
- codex/static_root/assets/unauthorized-DHV6Q1n-.css.gz +0 -0
- codex/static_root/assets/unauthorized-kEuFL5br.475729603aeb.js +1 -0
- codex/static_root/assets/unauthorized-kEuFL5br.475729603aeb.js.br +0 -0
- codex/static_root/assets/unauthorized-kEuFL5br.475729603aeb.js.gz +0 -0
- codex/static_root/assets/unauthorized-kEuFL5br.js +1 -0
- codex/static_root/assets/unauthorized-kEuFL5br.js.br +0 -0
- codex/static_root/assets/unauthorized-kEuFL5br.js.gz +0 -0
- codex/static_root/assets/{user-tab-DDViQ8Q6.c258185d0ebe.js → user-tab-CZNFTTEI.f3940a75daae.js} +1 -1
- codex/static_root/assets/user-tab-CZNFTTEI.f3940a75daae.js.br +0 -0
- codex/static_root/assets/user-tab-CZNFTTEI.f3940a75daae.js.gz +0 -0
- codex/static_root/assets/{user-tab-DDViQ8Q6.js → user-tab-CZNFTTEI.js} +1 -1
- codex/static_root/assets/user-tab-CZNFTTEI.js.br +0 -0
- codex/static_root/assets/user-tab-CZNFTTEI.js.gz +0 -0
- codex/static_root/js/choices-admin.ef1ff3a8b9da.json +1 -0
- codex/static_root/js/choices-admin.ef1ff3a8b9da.json.br +0 -0
- codex/static_root/js/choices-admin.ef1ff3a8b9da.json.gz +0 -0
- codex/static_root/js/choices-admin.json +1 -1
- codex/static_root/js/choices-admin.json.br +0 -0
- codex/static_root/js/choices-admin.json.gz +0 -0
- codex/static_root/js/{choices.b60817ba0a93.json → choices.23fedac2b9ba.json} +1 -1
- codex/static_root/js/choices.23fedac2b9ba.json.br +0 -0
- codex/static_root/js/choices.23fedac2b9ba.json.gz +0 -0
- codex/static_root/js/choices.json +1 -1
- codex/static_root/js/choices.json.br +0 -0
- codex/static_root/js/choices.json.gz +0 -0
- codex/static_root/manifest.6ef112683dae.json +642 -0
- codex/static_root/manifest.6ef112683dae.json.br +0 -0
- codex/static_root/manifest.6ef112683dae.json.gz +0 -0
- codex/static_root/manifest.json +259 -258
- codex/static_root/manifest.json.br +0 -0
- codex/static_root/manifest.json.gz +0 -0
- codex/static_root/staticfiles.json +1 -1
- codex/status_controller.py +11 -2
- codex/views/admin/library.py +47 -27
- codex/views/admin/stats.py +4 -1
- codex/views/admin/tasks.py +6 -1
- codex/views/browser/base.py +2 -2
- codex/views/browser/browser.py +1 -2
- codex/views/browser/browser_annotations.py +87 -17
- codex/views/browser/browser_breadcrumbs.py +2 -2
- codex/views/browser/browser_order_by.py +31 -20
- codex/views/browser/filters/search.py +1 -1
- codex/views/browser/metadata.py +0 -1
- codex/views/cover.py +3 -2
- codex/views/session.py +1 -0
- {codex-1.6.0a3.dist-info → codex-1.6.0a5.dist-info}/METADATA +3 -2
- {codex-1.6.0a3.dist-info → codex-1.6.0a5.dist-info}/RECORD +358 -357
- codex/static_root/assets/VCheckbox-CRu3BJ5D.48cbd6b412f4.js.br +0 -0
- codex/static_root/assets/VCheckbox-CRu3BJ5D.48cbd6b412f4.js.gz +0 -0
- codex/static_root/assets/VCheckbox-CRu3BJ5D.js.br +0 -0
- codex/static_root/assets/VCheckbox-CRu3BJ5D.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-CAUrQoP4.b162429d9a68.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-CAUrQoP4.b162429d9a68.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-CAUrQoP4.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-CAUrQoP4.js.gz +0 -0
- codex/static_root/assets/VCombobox-DJFO04Gk.b335ed051992.js +0 -1
- codex/static_root/assets/VCombobox-DJFO04Gk.b335ed051992.js.br +0 -0
- codex/static_root/assets/VCombobox-DJFO04Gk.b335ed051992.js.gz +0 -0
- codex/static_root/assets/VCombobox-DJFO04Gk.js +0 -1
- codex/static_root/assets/VCombobox-DJFO04Gk.js.br +0 -0
- codex/static_root/assets/VCombobox-DJFO04Gk.js.gz +0 -0
- codex/static_root/assets/VDialog-BcnzrzZO.7fa7ec337394.js.br +0 -0
- codex/static_root/assets/VDialog-BcnzrzZO.7fa7ec337394.js.gz +0 -0
- codex/static_root/assets/VDialog-BcnzrzZO.js.br +0 -0
- codex/static_root/assets/VDialog-BcnzrzZO.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DP3HSBJj.a5600e541dc2.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-DP3HSBJj.a5600e541dc2.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DP3HSBJj.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-DP3HSBJj.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-B9OZxVQw.28f10e381149.js.br +0 -5
- codex/static_root/assets/VRadioGroup-B9OZxVQw.28f10e381149.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-B9OZxVQw.js.br +0 -5
- codex/static_root/assets/VRadioGroup-B9OZxVQw.js.gz +0 -0
- codex/static_root/assets/VSelect-ARDhJiQK.372c098fb475.css +0 -1
- codex/static_root/assets/VSelect-ARDhJiQK.372c098fb475.css.br +0 -0
- codex/static_root/assets/VSelect-ARDhJiQK.372c098fb475.css.gz +0 -0
- codex/static_root/assets/VSelect-ARDhJiQK.css +0 -1
- codex/static_root/assets/VSelect-ARDhJiQK.css.br +0 -0
- codex/static_root/assets/VSelect-ARDhJiQK.css.gz +0 -0
- codex/static_root/assets/VSelect-BIXGglsb.018666f134d5.js +0 -1
- codex/static_root/assets/VSelect-BIXGglsb.018666f134d5.js.br +0 -0
- codex/static_root/assets/VSelect-BIXGglsb.018666f134d5.js.gz +0 -0
- codex/static_root/assets/VSelect-BIXGglsb.js +0 -1
- codex/static_root/assets/VSelect-BIXGglsb.js.br +0 -0
- codex/static_root/assets/VSelect-BIXGglsb.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-gDbXN6J_.137a5bce3954.js.br +0 -0
- codex/static_root/assets/VSelectionControl-gDbXN6J_.137a5bce3954.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-gDbXN6J_.js.br +0 -0
- codex/static_root/assets/VSelectionControl-gDbXN6J_.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-D8FKczaP.3c2d0e591ae3.js.br +0 -0
- codex/static_root/assets/VSlideGroup-D8FKczaP.3c2d0e591ae3.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-D8FKczaP.js.br +0 -0
- codex/static_root/assets/VSlideGroup-D8FKczaP.js.gz +0 -0
- codex/static_root/assets/VTable-D86x2F7y.60c6356a0b73.js.br +0 -0
- codex/static_root/assets/VTable-D86x2F7y.60c6356a0b73.js.gz +0 -0
- codex/static_root/assets/VTable-D86x2F7y.js.br +0 -0
- codex/static_root/assets/VTable-D86x2F7y.js.gz +0 -0
- codex/static_root/assets/VTextField-BEgIi5E-.6a5cf9192004.js +0 -1
- codex/static_root/assets/VTextField-BEgIi5E-.6a5cf9192004.js.br +0 -0
- codex/static_root/assets/VTextField-BEgIi5E-.6a5cf9192004.js.gz +0 -0
- codex/static_root/assets/VTextField-BEgIi5E-.js +0 -1
- codex/static_root/assets/VTextField-BEgIi5E-.js.br +0 -0
- codex/static_root/assets/VTextField-BEgIi5E-.js.gz +0 -0
- codex/static_root/assets/VTextField-DuIIp-VY.580110ad24dc.css +0 -1
- codex/static_root/assets/VTextField-DuIIp-VY.580110ad24dc.css.br +0 -0
- codex/static_root/assets/VTextField-DuIIp-VY.580110ad24dc.css.gz +0 -0
- codex/static_root/assets/VTextField-DuIIp-VY.css +0 -1
- codex/static_root/assets/VTextField-DuIIp-VY.css.br +0 -0
- codex/static_root/assets/VTextField-DuIIp-VY.css.gz +0 -0
- codex/static_root/assets/VWindowItem-aBb7Akq5.f0d7de98e392.js.br +0 -0
- codex/static_root/assets/VWindowItem-aBb7Akq5.f0d7de98e392.js.gz +0 -0
- codex/static_root/assets/VWindowItem-aBb7Akq5.js.br +0 -0
- codex/static_root/assets/VWindowItem-aBb7Akq5.js.gz +0 -0
- codex/static_root/assets/admin-BbrOU9Y9.29936748af9e.css.br +0 -0
- codex/static_root/assets/admin-BbrOU9Y9.29936748af9e.css.gz +0 -0
- codex/static_root/assets/admin-BbrOU9Y9.css.br +0 -0
- codex/static_root/assets/admin-BbrOU9Y9.css.gz +0 -0
- codex/static_root/assets/admin-CUlXuIkb.2c5ca314c698.js +0 -1
- codex/static_root/assets/admin-CUlXuIkb.2c5ca314c698.js.br +0 -0
- codex/static_root/assets/admin-CUlXuIkb.2c5ca314c698.js.gz +0 -0
- codex/static_root/assets/admin-CUlXuIkb.js +0 -1
- codex/static_root/assets/admin-CUlXuIkb.js.br +0 -0
- codex/static_root/assets/admin-CUlXuIkb.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-B98ueC5c.3fb257a9e9e8.js +0 -30
- codex/static_root/assets/admin-drawer-panel-B98ueC5c.3fb257a9e9e8.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-B98ueC5c.3fb257a9e9e8.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-B98ueC5c.js +0 -30
- codex/static_root/assets/admin-drawer-panel-B98ueC5c.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-B98ueC5c.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.1514926c78e8.css +0 -1
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.1514926c78e8.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.1514926c78e8.css.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.css +0 -1
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.css.gz +0 -0
- codex/static_root/assets/browser-C3YcP-vH.31dac9c003c4.js +0 -1
- codex/static_root/assets/browser-C3YcP-vH.31dac9c003c4.js.br +0 -0
- codex/static_root/assets/browser-C3YcP-vH.31dac9c003c4.js.gz +0 -0
- codex/static_root/assets/browser-C3YcP-vH.js +0 -1
- codex/static_root/assets/browser-C3YcP-vH.js.br +0 -0
- codex/static_root/assets/browser-C3YcP-vH.js.gz +0 -0
- codex/static_root/assets/browser-CwzOGMJs.css +0 -1
- codex/static_root/assets/browser-CwzOGMJs.css.br +0 -0
- codex/static_root/assets/browser-CwzOGMJs.css.gz +0 -0
- codex/static_root/assets/browser-CwzOGMJs.e53bf262a521.css +0 -1
- codex/static_root/assets/browser-CwzOGMJs.e53bf262a521.css.br +0 -0
- codex/static_root/assets/browser-CwzOGMJs.e53bf262a521.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-DywVK04u.eabe6b4c3e27.js.br +0 -0
- codex/static_root/assets/change-password-dialog-DywVK04u.eabe6b4c3e27.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-DywVK04u.js.br +0 -0
- codex/static_root/assets/change-password-dialog-DywVK04u.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-UnMzYsqN.d732afc0dc59.js.br +0 -0
- codex/static_root/assets/confirm-dialog-UnMzYsqN.d732afc0dc59.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-UnMzYsqN.js.br +0 -0
- codex/static_root/assets/confirm-dialog-UnMzYsqN.js.gz +0 -0
- codex/static_root/assets/datetime-column-IeiZdinf.e2807c847ddc.js.br +0 -0
- codex/static_root/assets/datetime-column-IeiZdinf.e2807c847ddc.js.gz +0 -0
- codex/static_root/assets/datetime-column-IeiZdinf.js.br +0 -0
- codex/static_root/assets/datetime-column-IeiZdinf.js.gz +0 -0
- codex/static_root/assets/filter-BT3OCu_E.39135c83c357.js.br +0 -0
- codex/static_root/assets/filter-BT3OCu_E.39135c83c357.js.gz +0 -0
- codex/static_root/assets/filter-BT3OCu_E.js.br +0 -0
- codex/static_root/assets/filter-BT3OCu_E.js.gz +0 -0
- codex/static_root/assets/flag-tab-BQmB4JNc.29dd38ce57d1.js +0 -1
- codex/static_root/assets/flag-tab-BQmB4JNc.29dd38ce57d1.js.br +0 -0
- codex/static_root/assets/flag-tab-BQmB4JNc.29dd38ce57d1.js.gz +0 -0
- codex/static_root/assets/flag-tab-BQmB4JNc.js +0 -1
- codex/static_root/assets/flag-tab-BQmB4JNc.js.br +0 -0
- codex/static_root/assets/flag-tab-BQmB4JNc.js.gz +0 -0
- codex/static_root/assets/flag-tab-BacZLlVi.8deba6a5370d.css +0 -1
- codex/static_root/assets/flag-tab-BacZLlVi.8deba6a5370d.css.br +0 -0
- codex/static_root/assets/flag-tab-BacZLlVi.8deba6a5370d.css.gz +0 -0
- codex/static_root/assets/flag-tab-BacZLlVi.css +0 -1
- codex/static_root/assets/flag-tab-BacZLlVi.css.br +0 -0
- codex/static_root/assets/flag-tab-BacZLlVi.css.gz +0 -0
- codex/static_root/assets/group-tab-Bt_AURnL.59aa6b13b14b.js.br +0 -0
- codex/static_root/assets/group-tab-Bt_AURnL.59aa6b13b14b.js.gz +0 -0
- codex/static_root/assets/group-tab-Bt_AURnL.js.br +0 -0
- codex/static_root/assets/group-tab-Bt_AURnL.js.gz +0 -0
- codex/static_root/assets/http-error-Cy29flzW.26884b2f42da.js +0 -1
- codex/static_root/assets/http-error-Cy29flzW.26884b2f42da.js.br +0 -4
- codex/static_root/assets/http-error-Cy29flzW.26884b2f42da.js.gz +0 -0
- codex/static_root/assets/http-error-Cy29flzW.js +0 -1
- codex/static_root/assets/http-error-Cy29flzW.js.br +0 -4
- codex/static_root/assets/http-error-Cy29flzW.js.gz +0 -0
- codex/static_root/assets/http-error-_wlDqEcp.5b78d3e332c9.css +0 -1
- codex/static_root/assets/http-error-_wlDqEcp.5b78d3e332c9.css.gz +0 -0
- codex/static_root/assets/http-error-_wlDqEcp.css +0 -1
- codex/static_root/assets/http-error-_wlDqEcp.css.gz +0 -0
- codex/static_root/assets/library-tab-0LLO3xlP.3636f75510b6.js +0 -1
- codex/static_root/assets/library-tab-0LLO3xlP.3636f75510b6.js.br +0 -0
- codex/static_root/assets/library-tab-0LLO3xlP.3636f75510b6.js.gz +0 -0
- codex/static_root/assets/library-tab-0LLO3xlP.js +0 -1
- codex/static_root/assets/library-tab-0LLO3xlP.js.br +0 -0
- codex/static_root/assets/library-tab-0LLO3xlP.js.gz +0 -0
- codex/static_root/assets/library-tab-CXbkxNZt.954f2850a439.css +0 -1
- codex/static_root/assets/library-tab-CXbkxNZt.954f2850a439.css.br +0 -2
- codex/static_root/assets/library-tab-CXbkxNZt.954f2850a439.css.gz +0 -0
- codex/static_root/assets/library-tab-CXbkxNZt.css +0 -1
- codex/static_root/assets/library-tab-CXbkxNZt.css.br +0 -2
- codex/static_root/assets/library-tab-CXbkxNZt.css.gz +0 -0
- codex/static_root/assets/main-BCYKxiL-.67d660e491ad.js +0 -32
- codex/static_root/assets/main-BCYKxiL-.67d660e491ad.js.br +0 -0
- codex/static_root/assets/main-BCYKxiL-.67d660e491ad.js.gz +0 -0
- codex/static_root/assets/main-BCYKxiL-.js +0 -32
- codex/static_root/assets/main-BCYKxiL-.js.br +0 -0
- codex/static_root/assets/main-BCYKxiL-.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-B3wS4_7p.7695fafdefce.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-B3wS4_7p.7695fafdefce.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-B3wS4_7p.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-B3wS4_7p.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-DQ8B0BSx.845b2f091ae7.js +0 -1
- codex/static_root/assets/pagination-toolbar-DQ8B0BSx.845b2f091ae7.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-DQ8B0BSx.845b2f091ae7.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-DQ8B0BSx.js +0 -1
- codex/static_root/assets/pagination-toolbar-DQ8B0BSx.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-DQ8B0BSx.js.gz +0 -0
- codex/static_root/assets/pdf-doc-DNwjWxO_.70b904e8e4ff.js.br +0 -0
- codex/static_root/assets/pdf-doc-DNwjWxO_.70b904e8e4ff.js.gz +0 -0
- codex/static_root/assets/pdf-doc-DNwjWxO_.js.br +0 -0
- codex/static_root/assets/pdf-doc-DNwjWxO_.js.gz +0 -0
- codex/static_root/assets/reader-CScIyWY8.0f2b4c8ea2bf.js.br +0 -0
- codex/static_root/assets/reader-CScIyWY8.0f2b4c8ea2bf.js.gz +0 -0
- codex/static_root/assets/reader-CScIyWY8.js.br +0 -0
- codex/static_root/assets/reader-CScIyWY8.js.gz +0 -0
- codex/static_root/assets/reader-pqgXBr7J.92a23ab06864.css.br +0 -0
- codex/static_root/assets/reader-pqgXBr7J.92a23ab06864.css.gz +0 -0
- codex/static_root/assets/reader-pqgXBr7J.css.br +0 -0
- codex/static_root/assets/reader-pqgXBr7J.css.gz +0 -0
- codex/static_root/assets/relation-chips-D6T6FX7G.css.br +0 -0
- codex/static_root/assets/relation-chips-D6T6FX7G.css.gz +0 -0
- codex/static_root/assets/relation-chips-D6T6FX7G.db095b2497e4.css.br +0 -0
- codex/static_root/assets/relation-chips-D6T6FX7G.db095b2497e4.css.gz +0 -0
- codex/static_root/assets/relation-chips-LT1N5iCN.37fceb98c9dd.js +0 -1
- codex/static_root/assets/relation-chips-LT1N5iCN.37fceb98c9dd.js.br +0 -0
- codex/static_root/assets/relation-chips-LT1N5iCN.37fceb98c9dd.js.gz +0 -0
- codex/static_root/assets/relation-chips-LT1N5iCN.js +0 -1
- codex/static_root/assets/relation-chips-LT1N5iCN.js.br +0 -0
- codex/static_root/assets/relation-chips-LT1N5iCN.js.gz +0 -0
- codex/static_root/assets/settings-drawer-BgUazs7O.7bbeb1fd98f1.css +0 -1
- codex/static_root/assets/settings-drawer-BgUazs7O.7bbeb1fd98f1.css.br +0 -0
- codex/static_root/assets/settings-drawer-BgUazs7O.7bbeb1fd98f1.css.gz +0 -0
- codex/static_root/assets/settings-drawer-BgUazs7O.css +0 -1
- codex/static_root/assets/settings-drawer-BgUazs7O.css.br +0 -0
- codex/static_root/assets/settings-drawer-BgUazs7O.css.gz +0 -0
- codex/static_root/assets/settings-drawer-DwqbWCCT.c6f1febbec8d.js +0 -2
- codex/static_root/assets/settings-drawer-DwqbWCCT.c6f1febbec8d.js.br +0 -0
- codex/static_root/assets/settings-drawer-DwqbWCCT.c6f1febbec8d.js.gz +0 -0
- codex/static_root/assets/settings-drawer-DwqbWCCT.js +0 -2
- codex/static_root/assets/settings-drawer-DwqbWCCT.js.br +0 -0
- codex/static_root/assets/settings-drawer-DwqbWCCT.js.gz +0 -0
- codex/static_root/assets/stats-tab-Bn9lHtZb.b2969fd36ae9.js.br +0 -0
- codex/static_root/assets/stats-tab-Bn9lHtZb.b2969fd36ae9.js.gz +0 -0
- codex/static_root/assets/stats-tab-Bn9lHtZb.js.br +0 -0
- codex/static_root/assets/stats-tab-Bn9lHtZb.js.gz +0 -0
- codex/static_root/assets/task-tab-BBfwR3Q4.d0de374d7ec0.js +0 -1
- codex/static_root/assets/task-tab-BBfwR3Q4.d0de374d7ec0.js.br +0 -0
- codex/static_root/assets/task-tab-BBfwR3Q4.d0de374d7ec0.js.gz +0 -0
- codex/static_root/assets/task-tab-BBfwR3Q4.js +0 -1
- codex/static_root/assets/task-tab-BBfwR3Q4.js.br +0 -0
- codex/static_root/assets/task-tab-BBfwR3Q4.js.gz +0 -0
- codex/static_root/assets/unauthorized-BWF4C258.3da18d521795.js +0 -1
- codex/static_root/assets/unauthorized-BWF4C258.3da18d521795.js.br +0 -0
- codex/static_root/assets/unauthorized-BWF4C258.3da18d521795.js.gz +0 -0
- codex/static_root/assets/unauthorized-BWF4C258.js +0 -1
- codex/static_root/assets/unauthorized-BWF4C258.js.br +0 -0
- codex/static_root/assets/unauthorized-BWF4C258.js.gz +0 -0
- codex/static_root/assets/unauthorized-DWgytUow.ca2f13dbdbf5.css.br +0 -0
- codex/static_root/assets/unauthorized-DWgytUow.ca2f13dbdbf5.css.gz +0 -0
- codex/static_root/assets/unauthorized-DWgytUow.css.br +0 -0
- codex/static_root/assets/unauthorized-DWgytUow.css.gz +0 -0
- codex/static_root/assets/user-tab-DDViQ8Q6.c258185d0ebe.js.br +0 -0
- codex/static_root/assets/user-tab-DDViQ8Q6.c258185d0ebe.js.gz +0 -0
- codex/static_root/assets/user-tab-DDViQ8Q6.js.br +0 -0
- codex/static_root/assets/user-tab-DDViQ8Q6.js.gz +0 -0
- codex/static_root/js/choices-admin.248384ece3f6.json +0 -1
- codex/static_root/js/choices-admin.248384ece3f6.json.br +0 -0
- codex/static_root/js/choices-admin.248384ece3f6.json.gz +0 -0
- codex/static_root/js/choices.b60817ba0a93.json.br +0 -0
- codex/static_root/js/choices.b60817ba0a93.json.gz +0 -0
- codex/static_root/manifest.776c8d59c3e4.json +0 -641
- codex/static_root/manifest.776c8d59c3e4.json.br +0 -0
- codex/static_root/manifest.776c8d59c3e4.json.gz +0 -0
- {codex-1.6.0a3.dist-info → codex-1.6.0a5.dist-info}/LICENSE +0 -0
- {codex-1.6.0a3.dist-info → codex-1.6.0a5.dist-info}/WHEEL +0 -0
- {codex-1.6.0a3.dist-info → codex-1.6.0a5.dist-info}/entry_points.txt +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"paths": {"rest_framework/docs/js/highlight.pack.js": "rest_framework/docs/js/highlight.pack.479b5f21dcba.js", "rest_framework/docs/js/jquery.json-view.min.js": "rest_framework/docs/js/jquery.json-view.min.b7c2d6981377.js", "rest_framework/docs/js/api.js": "rest_framework/docs/js/api.18a5ba8a1bd8.js", "rest_framework/docs/css/jquery.json-view.min.css": "rest_framework/docs/css/jquery.json-view.min.a2e6beeb6710.css", "rest_framework/docs/css/highlight.css": "rest_framework/docs/css/highlight.e0e4d973c6d7.css", "rest_framework/docs/css/base.css": "rest_framework/docs/css/base.e630f8f4990e.css", "rest_framework/docs/img/grid.png": "rest_framework/docs/img/grid.a4b938cf382b.png", "rest_framework/docs/img/favicon.ico": "rest_framework/docs/img/favicon.5195b4d0f3eb.ico", "rest_framework/js/ajax-form.js": "rest_framework/js/ajax-form.4e1cdcb7acab.js", "rest_framework/js/load-ajax-form.js": "rest_framework/js/load-ajax-form.8cdb3a9f3466.js", "rest_framework/js/prettify-min.js": "rest_framework/js/prettify-min.709bfcc456c6.js", "rest_framework/js/default.js": "rest_framework/js/default.5b08897dbdc3.js", "rest_framework/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "rest_framework/fonts/glyphicons-halflings-regular.woff": "rest_framework/fonts/glyphicons-halflings-regular.fa2772327f55.woff", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/fontawesome-webfont.svg": "rest_framework/fonts/fontawesome-webfont.83e37a11f9d7.svg", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "rest_framework/fonts/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "rest_framework/fonts/glyphicons-halflings-regular.ttf": "rest_framework/fonts/glyphicons-halflings-regular.e18bbf611f2a.ttf", "rest_framework/fonts/fontawesome-webfont.ttf": "rest_framework/fonts/fontawesome-webfont.dcb26c7239d8.ttf", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "rest_framework/css/bootstrap.min.css": "rest_framework/css/bootstrap.min.f17d4516b026.css", "rest_framework/css/bootstrap-theme.min.css": "rest_framework/css/bootstrap-theme.min.1d4b05b397c3.css", "rest_framework/css/bootstrap-tweaks.css": "rest_framework/css/bootstrap-tweaks.ee4ee6acf9eb.css", "rest_framework/css/bootstrap-theme.min.css.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "rest_framework/css/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/font-awesome-4.0.3.css": "rest_framework/css/font-awesome-4.0.3.c1e1ea213abf.css", "rest_framework/css/prettify.css": "rest_framework/css/prettify.a987f72342ee.css", "rest_framework/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "rest_framework/img/grid.png": "rest_framework/img/grid.a4b938cf382b.png", "rest_framework/img/glyphicons-halflings.png": "rest_framework/img/glyphicons-halflings.90233c9067e9.png", "rest_framework/img/glyphicons-halflings-white.png": "rest_framework/img/glyphicons-halflings-white.9bbc6e960299.png", "img/story-arc.svg": "img/story-arc.ca10014355ef.svg", "img/volume.svg": "img/volume.814e4c79461a.svg", "img/publisher.svg": "img/publisher.82d378fcd601.svg", "img/logo-maskable.svg": "img/logo-maskable.8f7de7f1c6a8.svg", "img/series.svg": "img/series.ec8a889b8f95.svg", "img/missing-cover-165.webp": "img/missing-cover-165.0743171f2148.webp", "img/missing-cover.svg": "img/missing-cover.ddb038cc2c56.svg", "img/folder.svg": "img/folder.f28936a3701d.svg", "img/logo.svg": "img/logo.0f5344a028ca.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.c58d966aa64e.webp", "img/imprint.svg": "img/imprint.7c2adebb76d6.svg", "img/logo-32.webp": "img/logo-32.5688944495bf.webp", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "js/choices-admin.json": "js/choices-admin.248384ece3f6.json", "js/choices.json": "js/choices.b60817ba0a93.json", "assets/relation-chips-D6T6FX7G.css": "assets/relation-chips-D6T6FX7G.db095b2497e4.css", "assets/unauthorized-BWF4C258.js": "assets/unauthorized-BWF4C258.3da18d521795.js", "assets/relation-chips-LT1N5iCN.js": "assets/relation-chips-LT1N5iCN.37fceb98c9dd.js", "assets/VDialog-BcnzrzZO.js": "assets/VDialog-BcnzrzZO.7fa7ec337394.js", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/VDialog-C5Nxd_zP.css": "assets/VDialog-C5Nxd_zP.d327f505ef0e.css", "assets/reader-pqgXBr7J.css": "assets/reader-pqgXBr7J.92a23ab06864.css", "assets/change-password-dialog-DywVK04u.js": "assets/change-password-dialog-DywVK04u.eabe6b4c3e27.js", "assets/VTable-D86x2F7y.js": "assets/VTable-D86x2F7y.60c6356a0b73.js", "assets/VWindowItem-aBb7Akq5.js": "assets/VWindowItem-aBb7Akq5.f0d7de98e392.js", "assets/VCheckbox-CRu3BJ5D.js": "assets/VCheckbox-CRu3BJ5D.48cbd6b412f4.js", "assets/VTable-DflzroDq.css": "assets/VTable-DflzroDq.160504d82195.css", "assets/VExpansionPanels-DsEXVcCv.css": "assets/VExpansionPanels-DsEXVcCv.20b475255e66.css", "assets/http-error-_wlDqEcp.css": "assets/http-error-_wlDqEcp.5b78d3e332c9.css", "assets/admin-drawer-panel-BF0dMvEE.css": "assets/admin-drawer-panel-BF0dMvEE.1514926c78e8.css", "assets/admin-drawer-panel-B98ueC5c.js": "assets/admin-drawer-panel-B98ueC5c.3fb257a9e9e8.js", "assets/confirm-dialog-UnMzYsqN.js": "assets/confirm-dialog-UnMzYsqN.d732afc0dc59.js", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/settings-drawer-BgUazs7O.css": "assets/settings-drawer-BgUazs7O.7bbeb1fd98f1.css", "assets/datetime-column-IeiZdinf.js": "assets/datetime-column-IeiZdinf.e2807c847ddc.js", "assets/VSelect-ARDhJiQK.css": "assets/VSelect-ARDhJiQK.372c098fb475.css", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/VSelect-BIXGglsb.js": "assets/VSelect-BIXGglsb.018666f134d5.js", "assets/VSelectionControl-gDbXN6J_.js": "assets/VSelectionControl-gDbXN6J_.137a5bce3954.js", "assets/filter-BT3OCu_E.js": "assets/filter-BT3OCu_E.39135c83c357.js", "assets/flag-tab-BacZLlVi.css": "assets/flag-tab-BacZLlVi.8deba6a5370d.css", "assets/VSlideGroup-Dk_1upHt.css": "assets/VSlideGroup-Dk_1upHt.2c836070ec75.css", "assets/VExpansionPanels-DP3HSBJj.js": "assets/VExpansionPanels-DP3HSBJj.a5600e541dc2.js", "assets/browser-C3YcP-vH.js": "assets/browser-C3YcP-vH.31dac9c003c4.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/library-tab-0LLO3xlP.js": "assets/library-tab-0LLO3xlP.3636f75510b6.js", "assets/reader-CScIyWY8.js": "assets/reader-CScIyWY8.0f2b4c8ea2bf.js", "assets/pagination-toolbar-DQ8B0BSx.js": "assets/pagination-toolbar-DQ8B0BSx.845b2f091ae7.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/VRadioGroup-B9OZxVQw.js": "assets/VRadioGroup-B9OZxVQw.28f10e381149.js", "assets/VTextField-BEgIi5E-.js": "assets/VTextField-BEgIi5E-.6a5cf9192004.js", "assets/main-BCYKxiL-.js": "assets/main-BCYKxiL-.67d660e491ad.js", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/VSlideGroup-D8FKczaP.js": "assets/VSlideGroup-D8FKczaP.3c2d0e591ae3.js", "assets/VCheckboxBtn-CAUrQoP4.js": "assets/VCheckboxBtn-CAUrQoP4.b162429d9a68.js", "assets/change-password-dialog-HvIvmmIE.css": "assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css", "assets/VTextField-DuIIp-VY.css": "assets/VTextField-DuIIp-VY.580110ad24dc.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/index-DUjeNg4x.js": "assets/index-DUjeNg4x.36d50c91b2c1.js", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/user-tab-DDViQ8Q6.js": "assets/user-tab-DDViQ8Q6.c258185d0ebe.js", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/admin-BbrOU9Y9.css": "assets/admin-BbrOU9Y9.29936748af9e.css", "assets/unauthorized-DWgytUow.css": "assets/unauthorized-DWgytUow.ca2f13dbdbf5.css", "assets/http-error-Cy29flzW.js": "assets/http-error-Cy29flzW.26884b2f42da.js", "assets/datetime-column-Dg_RxTVM.css": "assets/datetime-column-Dg_RxTVM.1fa7c5cbead7.css", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/to-case-kUm8NPpW.js": "assets/to-case-kUm8NPpW.5b3369f511b8.js", "assets/stats-tab-TsyG3wH_.css": "assets/stats-tab-TsyG3wH_.b93c080356fc.css", "assets/group-tab-CBKuS3Iv.css": "assets/group-tab-CBKuS3Iv.7e4746634782.css", "assets/settings-drawer-DwqbWCCT.js": "assets/settings-drawer-DwqbWCCT.c6f1febbec8d.js", "assets/main-sK7HC5h4.css": "assets/main-sK7HC5h4.6f04ddfc5f1a.css", "assets/flag-tab-BQmB4JNc.js": "assets/flag-tab-BQmB4JNc.29dd38ce57d1.js", "assets/pdf-doc-DNwjWxO_.js": "assets/pdf-doc-DNwjWxO_.70b904e8e4ff.js", "assets/admin-CUlXuIkb.js": "assets/admin-CUlXuIkb.2c5ca314c698.js", "assets/pagination-toolbar-B3wS4_7p.css": "assets/pagination-toolbar-B3wS4_7p.7695fafdefce.css", "assets/group-tab-Bt_AURnL.js": "assets/group-tab-Bt_AURnL.59aa6b13b14b.js", "assets/VCombobox-DJFO04Gk.js": "assets/VCombobox-DJFO04Gk.b335ed051992.js", "assets/library-tab-CXbkxNZt.css": "assets/library-tab-CXbkxNZt.954f2850a439.css", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/browser-CwzOGMJs.css": "assets/browser-CwzOGMJs.e53bf262a521.css", "assets/task-tab-BBfwR3Q4.js": "assets/task-tab-BBfwR3Q4.d0de374d7ec0.js", "assets/stats-tab-Bn9lHtZb.js": "assets/stats-tab-Bn9lHtZb.b2969fd36ae9.js", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.776c8d59c3e4.json"}, "version": "1.1", "hash": "5f14b674bee7"}
|
|
1
|
+
{"paths": {"rest_framework/docs/js/highlight.pack.js": "rest_framework/docs/js/highlight.pack.479b5f21dcba.js", "rest_framework/docs/js/jquery.json-view.min.js": "rest_framework/docs/js/jquery.json-view.min.b7c2d6981377.js", "rest_framework/docs/js/api.js": "rest_framework/docs/js/api.18a5ba8a1bd8.js", "rest_framework/docs/css/jquery.json-view.min.css": "rest_framework/docs/css/jquery.json-view.min.a2e6beeb6710.css", "rest_framework/docs/css/highlight.css": "rest_framework/docs/css/highlight.e0e4d973c6d7.css", "rest_framework/docs/css/base.css": "rest_framework/docs/css/base.e630f8f4990e.css", "rest_framework/docs/img/grid.png": "rest_framework/docs/img/grid.a4b938cf382b.png", "rest_framework/docs/img/favicon.ico": "rest_framework/docs/img/favicon.5195b4d0f3eb.ico", "rest_framework/js/ajax-form.js": "rest_framework/js/ajax-form.4e1cdcb7acab.js", "rest_framework/js/load-ajax-form.js": "rest_framework/js/load-ajax-form.8cdb3a9f3466.js", "rest_framework/js/prettify-min.js": "rest_framework/js/prettify-min.709bfcc456c6.js", "rest_framework/js/default.js": "rest_framework/js/default.5b08897dbdc3.js", "rest_framework/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "rest_framework/fonts/glyphicons-halflings-regular.woff": "rest_framework/fonts/glyphicons-halflings-regular.fa2772327f55.woff", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/fontawesome-webfont.svg": "rest_framework/fonts/fontawesome-webfont.83e37a11f9d7.svg", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "rest_framework/fonts/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "rest_framework/fonts/glyphicons-halflings-regular.ttf": "rest_framework/fonts/glyphicons-halflings-regular.e18bbf611f2a.ttf", "rest_framework/fonts/fontawesome-webfont.ttf": "rest_framework/fonts/fontawesome-webfont.dcb26c7239d8.ttf", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "rest_framework/css/bootstrap.min.css": "rest_framework/css/bootstrap.min.f17d4516b026.css", "rest_framework/css/bootstrap-theme.min.css": "rest_framework/css/bootstrap-theme.min.1d4b05b397c3.css", "rest_framework/css/bootstrap-tweaks.css": "rest_framework/css/bootstrap-tweaks.ee4ee6acf9eb.css", "rest_framework/css/bootstrap-theme.min.css.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "rest_framework/css/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/font-awesome-4.0.3.css": "rest_framework/css/font-awesome-4.0.3.c1e1ea213abf.css", "rest_framework/css/prettify.css": "rest_framework/css/prettify.a987f72342ee.css", "rest_framework/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "rest_framework/img/grid.png": "rest_framework/img/grid.a4b938cf382b.png", "rest_framework/img/glyphicons-halflings.png": "rest_framework/img/glyphicons-halflings.90233c9067e9.png", "rest_framework/img/glyphicons-halflings-white.png": "rest_framework/img/glyphicons-halflings-white.9bbc6e960299.png", "img/story-arc.svg": "img/story-arc.ca10014355ef.svg", "img/volume.svg": "img/volume.814e4c79461a.svg", "img/publisher.svg": "img/publisher.82d378fcd601.svg", "img/logo-maskable.svg": "img/logo-maskable.8f7de7f1c6a8.svg", "img/series.svg": "img/series.ec8a889b8f95.svg", "img/missing-cover-165.webp": "img/missing-cover-165.0743171f2148.webp", "img/missing-cover.svg": "img/missing-cover.ddb038cc2c56.svg", "img/folder.svg": "img/folder.f28936a3701d.svg", "img/logo.svg": "img/logo.0f5344a028ca.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.c58d966aa64e.webp", "img/imprint.svg": "img/imprint.7c2adebb76d6.svg", "img/logo-32.webp": "img/logo-32.5688944495bf.webp", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "js/choices-admin.json": "js/choices-admin.ef1ff3a8b9da.json", "js/choices.json": "js/choices.23fedac2b9ba.json", "assets/VDialog-pzwzInEh.js": "assets/VDialog-pzwzInEh.51acf566a069.js", "assets/VTextField-Dftcik85.js": "assets/VTextField-Dftcik85.cb2f1dda87e1.js", "assets/pdf-doc-BTdS9hUz.js": "assets/pdf-doc-BTdS9hUz.7c966524280a.js", "assets/confirm-dialog-DARLmXRf.js": "assets/confirm-dialog-DARLmXRf.53fc6938fb8c.js", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/VDialog-C5Nxd_zP.css": "assets/VDialog-C5Nxd_zP.d327f505ef0e.css", "assets/http-error-HFeYnF0n.js": "assets/http-error-HFeYnF0n.a3c578a0265e.js", "assets/VTable-DflzroDq.css": "assets/VTable-DflzroDq.160504d82195.css", "assets/VExpansionPanels-DsEXVcCv.css": "assets/VExpansionPanels-DsEXVcCv.20b475255e66.css", "assets/main-gSW7TFDY.js": "assets/main-gSW7TFDY.329223b148d4.js", "assets/VSelect-ChOlLRyH.js": "assets/VSelect-ChOlLRyH.00b11751b25e.js", "assets/datetime-column-LpLgWpkf.js": "assets/datetime-column-LpLgWpkf.16ce3324970f.js", "assets/VCombobox-CTRWnOuM.js": "assets/VCombobox-CTRWnOuM.0f00903c2ebc.js", "assets/unauthorized-kEuFL5br.js": "assets/unauthorized-kEuFL5br.475729603aeb.js", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/relation-chips-Bsc-gUxE.css": "assets/relation-chips-Bsc-gUxE.98e65384c3c9.css", "assets/VCheckboxBtn-Coc7g8m7.js": "assets/VCheckboxBtn-Coc7g8m7.31e1e6aa44c9.js", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/VSlideGroup-Dk_1upHt.css": "assets/VSlideGroup-Dk_1upHt.2c836070ec75.css", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/flag-tab-BNwbLfrN.css": "assets/flag-tab-BNwbLfrN.b755a99fff7e.css", "assets/flag-tab-mYS2wg5e.js": "assets/flag-tab-mYS2wg5e.17829c46cae9.js", "assets/filter-jRB1Ob6r.js": "assets/filter-jRB1Ob6r.6a559a53e805.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/group-tab-MK1lcjUU.js": "assets/group-tab-MK1lcjUU.98406d5babdc.js", "assets/user-tab-CZNFTTEI.js": "assets/user-tab-CZNFTTEI.f3940a75daae.js", "assets/VSlideGroup-zFz5_byd.js": "assets/VSlideGroup-zFz5_byd.e0e246b7acbb.js", "assets/VCheckbox-BF_99tgB.js": "assets/VCheckbox-BF_99tgB.7fe59e56d9d4.js", "assets/VExpansionPanels-CKSq1GpG.js": "assets/VExpansionPanels-CKSq1GpG.0ecf702c5b67.js", "assets/library-tab-BN0SfPcH.css": "assets/library-tab-BN0SfPcH.913e236f625e.css", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/unauthorized-DHV6Q1n-.css": "assets/unauthorized-DHV6Q1n-.b7847b2872a1.css", "assets/reader-CF3xt6JG.css": "assets/reader-CF3xt6JG.19fad7f62450.css", "assets/settings-drawer-BJOfMtqA.css": "assets/settings-drawer-BJOfMtqA.6471a50fc05b.css", "assets/change-password-dialog-HvIvmmIE.css": "assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css", "assets/library-tab-DYeEBYlT.js": "assets/library-tab-DYeEBYlT.a2a2ef088d1c.js", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/index-DUjeNg4x.js": "assets/index-DUjeNg4x.36d50c91b2c1.js", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/VWindowItem-CYCwnt3s.js": "assets/VWindowItem-CYCwnt3s.28025dc36c6a.js", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/admin-drawer-panel-B2rmpAVA.js": "assets/admin-drawer-panel-B2rmpAVA.a9e72fbfdadc.js", "assets/pagination-toolbar-Dlm70Bhs.js": "assets/pagination-toolbar-Dlm70Bhs.8f23f8bd9a05.js", "assets/datetime-column-Dg_RxTVM.css": "assets/datetime-column-Dg_RxTVM.1fa7c5cbead7.css", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/to-case-kUm8NPpW.js": "assets/to-case-kUm8NPpW.5b3369f511b8.js", "assets/stats-tab-TsyG3wH_.css": "assets/stats-tab-TsyG3wH_.b93c080356fc.css", "assets/VSelectionControl-DKOhc2zB.js": "assets/VSelectionControl-DKOhc2zB.061dca094303.js", "assets/group-tab-CBKuS3Iv.css": "assets/group-tab-CBKuS3Iv.7e4746634782.css", "assets/main-sK7HC5h4.css": "assets/main-sK7HC5h4.6f04ddfc5f1a.css", "assets/browser-CpppBvim.css": "assets/browser-CpppBvim.a1b5d4fe97b1.css", "assets/VTable-FKMTcdkF.js": "assets/VTable-FKMTcdkF.6c1eed84d25e.js", "assets/settings-drawer-xSctoxZn.js": "assets/settings-drawer-xSctoxZn.4ce8afcb879a.js", "assets/VRadioGroup-CW5GobGU.js": "assets/VRadioGroup-CW5GobGU.b72925bca3de.js", "assets/browser-lKU7rqLd.js": "assets/browser-lKU7rqLd.cdb86e625ed9.js", "assets/admin-B8Bp2Uih.css": "assets/admin-B8Bp2Uih.82c98714bcf1.css", "assets/pagination-toolbar-ClZui9Zf.css": "assets/pagination-toolbar-ClZui9Zf.697d7ae11c21.css", "assets/admin-drawer-panel-BHdNPwzF.css": "assets/admin-drawer-panel-BHdNPwzF.bd2c1d6148bb.css", "assets/VSelect-MGVSeLgr.css": "assets/VSelect-MGVSeLgr.7cabd30bc5e4.css", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/admin-DH_DrB0F.js": "assets/admin-DH_DrB0F.dc45fb726e07.js", "assets/http-error-DKulXuTl.css": "assets/http-error-DKulXuTl.95e42988d5d5.css", "assets/stats-tab-C_uC_U7o.js": "assets/stats-tab-C_uC_U7o.e6b014b6e8c6.js", "assets/change-password-dialog-BIBG6Bk8.js": "assets/change-password-dialog-BIBG6Bk8.3583021c124a.js", "assets/reader-BtSTIETq.js": "assets/reader-BtSTIETq.f940f66c0e58.js", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/task-tab-VIpy1Ula.js": "assets/task-tab-VIpy1Ula.c07877250c88.js", "assets/relation-chips-C4Ob7ySi.js": "assets/relation-chips-C4Ob7ySi.95855a010f4a.js", "assets/VTextField-BssVoDhB.css": "assets/VTextField-BssVoDhB.4cc388b4aa3c.css", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.6ef112683dae.json"}, "version": "1.1", "hash": "7695af48b4aa"}
|
codex/status_controller.py
CHANGED
|
@@ -130,9 +130,18 @@ class StatusController(LoggerBaseMixin):
|
|
|
130
130
|
types += [self._to_status_type_value(status)]
|
|
131
131
|
ls_filter = {"status_type__in": types} if types else {}
|
|
132
132
|
updates = {**STATUS_DEFAULTS, "updated_at": Now()}
|
|
133
|
-
LibrarianStatus.objects.filter(**ls_filter)
|
|
133
|
+
lses = LibrarianStatus.objects.filter(**ls_filter)
|
|
134
|
+
update_ls = []
|
|
135
|
+
for ls in lses.iterator():
|
|
136
|
+
for key, value in updates.items():
|
|
137
|
+
setattr(ls, key, value)
|
|
138
|
+
update_ls.append(ls)
|
|
139
|
+
LibrarianStatus.objects.bulk_update(update_ls, tuple(updates.keys()))
|
|
134
140
|
self._enqueue_notifier_task(notify, until)
|
|
135
|
-
if
|
|
141
|
+
if filter:
|
|
142
|
+
# self.log.debug(f"Cleared {types} librarian statuses")
|
|
143
|
+
pass
|
|
144
|
+
else:
|
|
136
145
|
self.log.info("Cleared all librarian statuses")
|
|
137
146
|
except Exception as exc:
|
|
138
147
|
self.log.warning(f"Finish status {statii}: {exc}")
|
codex/views/admin/library.py
CHANGED
|
@@ -5,6 +5,7 @@ from time import time
|
|
|
5
5
|
from typing import ClassVar
|
|
6
6
|
|
|
7
7
|
from django.core.cache import cache
|
|
8
|
+
from django.db.utils import NotSupportedError
|
|
8
9
|
from drf_spectacular.utils import extend_schema
|
|
9
10
|
from rest_framework.exceptions import ValidationError
|
|
10
11
|
from rest_framework.generics import GenericAPIView
|
|
@@ -15,7 +16,10 @@ from rest_framework.viewsets import ModelViewSet
|
|
|
15
16
|
from codex.librarian.mp_queue import LIBRARIAN_QUEUE
|
|
16
17
|
from codex.librarian.notifier.tasks import LIBRARY_CHANGED_TASK
|
|
17
18
|
from codex.librarian.tasks import DelayedTasks
|
|
18
|
-
from codex.librarian.watchdog.tasks import
|
|
19
|
+
from codex.librarian.watchdog.tasks import (
|
|
20
|
+
WatchdogPollLibrariesTask,
|
|
21
|
+
WatchdogSyncTask,
|
|
22
|
+
)
|
|
19
23
|
from codex.logger.logging import get_logger
|
|
20
24
|
from codex.models import FailedImport, Folder, Library
|
|
21
25
|
from codex.serializers.admin import (
|
|
@@ -28,16 +32,35 @@ from codex.serializers.admin import (
|
|
|
28
32
|
LOG = get_logger(__name__)
|
|
29
33
|
|
|
30
34
|
|
|
31
|
-
class
|
|
32
|
-
"""Admin
|
|
35
|
+
class AdminModelViewSet(ModelViewSet):
|
|
36
|
+
"""Admin ModelViewSet."""
|
|
33
37
|
|
|
34
38
|
permission_classes: ClassVar[list] = [IsAdminUser] # type: ignore
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class AdminLibraryViewSet(AdminModelViewSet):
|
|
42
|
+
"""Admin Library Viewset."""
|
|
43
|
+
|
|
44
|
+
WATCHDOG_SYNC_FIELDS = frozenset({"events", "poll", "pollEvery"})
|
|
45
|
+
|
|
35
46
|
queryset = Library.objects.prefetch_related("groups").defer(
|
|
36
47
|
"update_in_progress", "created_at", "updated_at"
|
|
37
48
|
)
|
|
38
49
|
serializer_class = LibrarySerializer
|
|
39
50
|
|
|
40
|
-
|
|
51
|
+
@classmethod
|
|
52
|
+
def _sync_watchdog(cls, validated_keys=None):
|
|
53
|
+
if validated_keys is None or validated_keys.intersection(
|
|
54
|
+
cls.WATCHDOG_SYNC_FIELDS
|
|
55
|
+
):
|
|
56
|
+
task = DelayedTasks(time() + 2, (WatchdogSyncTask(),))
|
|
57
|
+
LIBRARIAN_QUEUE.put(task)
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def _on_change():
|
|
61
|
+
cache.clear()
|
|
62
|
+
task = LIBRARY_CHANGED_TASK
|
|
63
|
+
LIBRARIAN_QUEUE.put(task)
|
|
41
64
|
|
|
42
65
|
def _create_library_folder(self, library):
|
|
43
66
|
folder = Folder(
|
|
@@ -45,36 +68,19 @@ class AdminLibraryViewSet(ModelViewSet):
|
|
|
45
68
|
)
|
|
46
69
|
folder.save()
|
|
47
70
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
task = DelayedTasks(time() + 2, (WatchdogSyncTask(),))
|
|
51
|
-
LIBRARIAN_QUEUE.put(task)
|
|
52
|
-
|
|
53
|
-
@staticmethod
|
|
54
|
-
def _on_change():
|
|
55
|
-
cache.clear()
|
|
56
|
-
task = LIBRARY_CHANGED_TASK
|
|
57
|
-
LIBRARIAN_QUEUE.put(task)
|
|
71
|
+
def _get_pk(self):
|
|
72
|
+
return self.kwargs["pk"]
|
|
58
73
|
|
|
59
74
|
@staticmethod
|
|
60
75
|
def _poll(pk, force):
|
|
61
76
|
task = WatchdogPollLibrariesTask(frozenset({pk}), force)
|
|
62
77
|
LIBRARIAN_QUEUE.put(task)
|
|
63
78
|
|
|
64
|
-
def perform_update(self, serializer):
|
|
65
|
-
"""Perform update an run hooks."""
|
|
66
|
-
validated_keys = set(serializer.validated_data.keys())
|
|
67
|
-
super().perform_update(serializer)
|
|
68
|
-
if "groupSet" in validated_keys:
|
|
69
|
-
self._on_change()
|
|
70
|
-
if validated_keys.intersection(self.WATCHDOG_SYNC_FIELDS):
|
|
71
|
-
self._sync_watchdog()
|
|
72
|
-
pk = self.kwargs.get("pk")
|
|
73
|
-
self._poll(pk, False)
|
|
74
|
-
|
|
75
79
|
def perform_create(self, serializer):
|
|
76
80
|
"""Perform create and run hooks."""
|
|
77
81
|
super().perform_create(serializer)
|
|
82
|
+
if serializer.validated_data.get("covers_only"):
|
|
83
|
+
raise NotSupportedError
|
|
78
84
|
library = Library.objects.only("pk", "path").get(
|
|
79
85
|
path=serializer.validated_data["path"]
|
|
80
86
|
)
|
|
@@ -82,17 +88,31 @@ class AdminLibraryViewSet(ModelViewSet):
|
|
|
82
88
|
self._sync_watchdog()
|
|
83
89
|
self._poll(library.pk, False)
|
|
84
90
|
|
|
91
|
+
def perform_update(self, serializer):
|
|
92
|
+
"""Perform update an run hooks."""
|
|
93
|
+
validated_keys = frozenset(serializer.validated_data.keys())
|
|
94
|
+
pk = self.kwargs["pk"]
|
|
95
|
+
library = Library.objects.get(pk=pk)
|
|
96
|
+
if library.covers_only and serializer.validated_data.get("path"):
|
|
97
|
+
raise NotSupportedError
|
|
98
|
+
super().perform_update(serializer)
|
|
99
|
+
if "groupSet" in validated_keys:
|
|
100
|
+
self._on_change()
|
|
101
|
+
self._sync_watchdog(validated_keys)
|
|
102
|
+
self._poll(pk, False)
|
|
103
|
+
|
|
85
104
|
def perform_destroy(self, instance):
|
|
86
105
|
"""Perform destroy and run hooks."""
|
|
106
|
+
if instance.covers_only:
|
|
107
|
+
raise NotSupportedError
|
|
87
108
|
super().perform_destroy(instance)
|
|
88
109
|
self._sync_watchdog()
|
|
89
110
|
self._on_change()
|
|
90
111
|
|
|
91
112
|
|
|
92
|
-
class AdminFailedImportViewSet(
|
|
113
|
+
class AdminFailedImportViewSet(AdminModelViewSet):
|
|
93
114
|
"""Admin FailedImport Viewset."""
|
|
94
115
|
|
|
95
|
-
permission_classes: ClassVar[list] = [IsAdminUser] # type: ignore
|
|
96
116
|
queryset = FailedImport.objects.defer("updated_at")
|
|
97
117
|
serializer_class = FailedImportSerializer
|
|
98
118
|
|
codex/views/admin/stats.py
CHANGED
|
@@ -150,7 +150,10 @@ class AdminStatsView(GenericAPIView):
|
|
|
150
150
|
|
|
151
151
|
vnp_name = snakecase(title)
|
|
152
152
|
vnp_name += "_count"
|
|
153
|
-
|
|
153
|
+
qs = model.objects
|
|
154
|
+
if model == Library:
|
|
155
|
+
qs = qs.filter(covers_only=False)
|
|
156
|
+
obj[vnp_name] = qs.count()
|
|
154
157
|
return obj
|
|
155
158
|
|
|
156
159
|
@staticmethod
|
codex/views/admin/tasks.py
CHANGED
|
@@ -17,6 +17,7 @@ from codex.librarian.covers.tasks import (
|
|
|
17
17
|
from codex.librarian.janitor.tasks import (
|
|
18
18
|
ForceUpdateAllFailedImportsTask,
|
|
19
19
|
JanitorBackupTask,
|
|
20
|
+
JanitorCleanCoversTask,
|
|
20
21
|
JanitorCleanFKsTask,
|
|
21
22
|
JanitorCleanupSessionsTask,
|
|
22
23
|
JanitorClearStatusTask,
|
|
@@ -36,7 +37,10 @@ from codex.librarian.search.tasks import (
|
|
|
36
37
|
SearchIndexRemoveStaleTask,
|
|
37
38
|
SearchIndexUpdateTask,
|
|
38
39
|
)
|
|
39
|
-
from codex.librarian.watchdog.tasks import
|
|
40
|
+
from codex.librarian.watchdog.tasks import (
|
|
41
|
+
WatchdogPollLibrariesTask,
|
|
42
|
+
WatchdogSyncTask,
|
|
43
|
+
)
|
|
40
44
|
from codex.logger.logging import get_logger
|
|
41
45
|
from codex.models import LibrarianStatus
|
|
42
46
|
from codex.serializers.admin import AdminLibrarianTaskSerializer
|
|
@@ -86,6 +90,7 @@ class AdminLibrarianTaskView(APIView):
|
|
|
86
90
|
"notify_library_changed": LIBRARY_CHANGED_TASK,
|
|
87
91
|
"notify_librarian_status": LIBRARIAN_STATUS_TASK,
|
|
88
92
|
"cleanup_fks": JanitorCleanFKsTask(),
|
|
93
|
+
"cleanup_db_custom_covers": JanitorCleanCoversTask(),
|
|
89
94
|
"cleanup_sessions": JanitorCleanupSessionsTask(),
|
|
90
95
|
"cleanup_covers": CoverRemoveOrphansTask(),
|
|
91
96
|
"librarian_clear_status": JanitorClearStatusTask(),
|
codex/views/browser/base.py
CHANGED
|
@@ -149,9 +149,9 @@ class BrowserBaseView(
|
|
|
149
149
|
data = {}
|
|
150
150
|
|
|
151
151
|
serializer = self.input_serializer_class(data=data)
|
|
152
|
-
|
|
153
152
|
serializer.is_valid(raise_exception=True)
|
|
154
|
-
|
|
153
|
+
|
|
154
|
+
params = deepcopy(self.request.session[self.SESSION_KEY])
|
|
155
155
|
params.update(serializer.validated_data)
|
|
156
156
|
self.params = MappingProxyType(params)
|
|
157
157
|
|
codex/views/browser/browser.py
CHANGED
|
@@ -50,7 +50,6 @@ class BrowserView(BrowserBreadcrumbsView):
|
|
|
50
50
|
{
|
|
51
51
|
AdminFlag.FlagChoices.FOLDER_VIEW.value: "folder_view",
|
|
52
52
|
AdminFlag.FlagChoices.IMPORT_METADATA.value: "import_metadata",
|
|
53
|
-
AdminFlag.FlagChoices.DYNAMIC_GROUP_COVERS.value: "dynamic_group_covers",
|
|
54
53
|
}
|
|
55
54
|
)
|
|
56
55
|
|
|
@@ -370,7 +369,7 @@ class BrowserView(BrowserBreadcrumbsView):
|
|
|
370
369
|
title = self._get_browser_page_title()
|
|
371
370
|
# needs to happen after pagination
|
|
372
371
|
# runs obj list query twice :/
|
|
373
|
-
libraries_exist = Library.objects.exists()
|
|
372
|
+
libraries_exist = Library.objects.filter(covers_only=False).exists()
|
|
374
373
|
covers_timestamp = int(
|
|
375
374
|
Timestamp.objects.get(
|
|
376
375
|
key=Timestamp.TimestampChoices.COVERS.value
|
|
@@ -20,13 +20,33 @@ from django.db.models import (
|
|
|
20
20
|
from django.db.models.fields import CharField, PositiveSmallIntegerField
|
|
21
21
|
from django.db.models.functions import Least, Reverse, Right, StrIndex
|
|
22
22
|
|
|
23
|
-
from codex.models import
|
|
23
|
+
from codex.models import (
|
|
24
|
+
BrowserGroupModel,
|
|
25
|
+
Comic,
|
|
26
|
+
Folder,
|
|
27
|
+
Imprint,
|
|
28
|
+
Publisher,
|
|
29
|
+
Series,
|
|
30
|
+
StoryArc,
|
|
31
|
+
Volume,
|
|
32
|
+
)
|
|
24
33
|
from codex.models.functions import JsonGroupArray
|
|
25
34
|
from codex.views.browser.browser_order_by import (
|
|
26
35
|
BrowserOrderByView,
|
|
27
36
|
)
|
|
28
37
|
from codex.views.mixins import SharedAnnotationsMixin
|
|
29
38
|
|
|
39
|
+
_REL_MAP = MappingProxyType(
|
|
40
|
+
{
|
|
41
|
+
Publisher: "publisher",
|
|
42
|
+
Imprint: "imprint",
|
|
43
|
+
Series: "series",
|
|
44
|
+
Volume: "volume",
|
|
45
|
+
Folder: "parent_folder",
|
|
46
|
+
StoryArc: "story_arc_numbers__story_arc",
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
|
|
30
50
|
|
|
31
51
|
class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
|
|
32
52
|
"""Base class for views that need special metadata annotations."""
|
|
@@ -34,7 +54,7 @@ class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
|
|
|
34
54
|
_NONE_INTEGERFIELD = Value(None, PositiveSmallIntegerField())
|
|
35
55
|
_NONE_DATETIMEFIELD = Value(None, DateTimeField())
|
|
36
56
|
_ORDER_AGGREGATE_FUNCS = MappingProxyType(
|
|
37
|
-
# These are annotated to order_value
|
|
57
|
+
# These are annotated to order_value because they're simple relations
|
|
38
58
|
{
|
|
39
59
|
"age_rating": Avg,
|
|
40
60
|
"community_rating": Avg,
|
|
@@ -205,12 +225,31 @@ class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
|
|
|
205
225
|
# Select comics for the children by an outer ref for annotation
|
|
206
226
|
# Order the descendant comics by the sort argumentst
|
|
207
227
|
if model == Comic:
|
|
208
|
-
qs = qs.annotate(cover_pk=F("pk"))
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
228
|
+
qs = qs.annotate(cover_pk=F("pk"), cover_mtime=F("updated_at"))
|
|
229
|
+
else:
|
|
230
|
+
cover_style = self.params.get("cover_style")
|
|
231
|
+
if cover_style == "i":
|
|
232
|
+
default_cover_pk = None
|
|
233
|
+
default_cover_mtime = None
|
|
234
|
+
else:
|
|
235
|
+
# At this point it's only been filtered.
|
|
236
|
+
default_cover_pk = F(self.rel_prefix + "pk")
|
|
237
|
+
default_cover_mtime = F(self.rel_prefix + "updated_at")
|
|
238
|
+
|
|
239
|
+
qs = qs.annotate(
|
|
240
|
+
cover_custom=F("custom_cover"),
|
|
241
|
+
cover_pk=Case(
|
|
242
|
+
When(custom_cover__isnull=False, then=F("custom_cover__pk")),
|
|
243
|
+
default=default_cover_pk,
|
|
244
|
+
),
|
|
245
|
+
cover_mtime=Case(
|
|
246
|
+
When(
|
|
247
|
+
custom_cover__isnull=False, then=F("custom_cover__updated_at")
|
|
248
|
+
),
|
|
249
|
+
default=default_cover_mtime,
|
|
250
|
+
),
|
|
251
|
+
cover_pks=JsonGroupArray("cover_pk", distinct=True),
|
|
252
|
+
)
|
|
214
253
|
return qs
|
|
215
254
|
|
|
216
255
|
def _annotate_group(self, qs, model):
|
|
@@ -316,14 +355,44 @@ class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
|
|
|
316
355
|
"""Annotations only for metadata."""
|
|
317
356
|
return qs.annotate(mtime=Max("updated_at"))
|
|
318
357
|
|
|
319
|
-
def _get_cover_pk_query(self, cover_pks):
|
|
358
|
+
def _get_cover_pk_query(self, cover_pks, group_ids):
|
|
320
359
|
"""Get Cover Pk queryset for comic queryset."""
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
360
|
+
cover_style = self.params.get("cover_style")
|
|
361
|
+
if cover_style == "d":
|
|
362
|
+
# DYNAMIC COVERS
|
|
363
|
+
comic_qs = Comic.objects.filter(pk__in=cover_pks)
|
|
364
|
+
comic_qs = self.annotate_search_score(
|
|
365
|
+
comic_qs, Comic, self.cover_search_score_pairs
|
|
366
|
+
)
|
|
367
|
+
comic_qs = self.annotate_order_aggregates(comic_qs, Comic)
|
|
368
|
+
comic_qs = self.add_order_by(comic_qs, Comic) # type: ignore
|
|
369
|
+
else: # "f"
|
|
370
|
+
# FIRST COVERS
|
|
371
|
+
# The only filter at all is the model relation.
|
|
372
|
+
group_rel = _REL_MAP[self.model] # type: ignore
|
|
373
|
+
comic_qs = Comic.objects.filter(**{f"{group_rel}__in": group_ids})
|
|
374
|
+
|
|
375
|
+
# Order generated irrespective of browser filters and order
|
|
376
|
+
if self.kwargs["group"] == "f":
|
|
377
|
+
order_key = "filename"
|
|
378
|
+
elif self.kwargs["group"] == "a":
|
|
379
|
+
order_key = "story_arc_number"
|
|
380
|
+
else:
|
|
381
|
+
order_key = "sort_name"
|
|
382
|
+
|
|
383
|
+
model_group = self.model_group # type: ignore
|
|
384
|
+
show = MappingProxyType(self.params["show"]) # type: ignore
|
|
385
|
+
model_group = self.kwargs["group"]
|
|
386
|
+
comic_qs, comic_sort_names = self.alias_sort_names(
|
|
387
|
+
comic_qs, Comic, cover_pks, model_group, show
|
|
388
|
+
)
|
|
389
|
+
comic_qs = self.add_order_by(
|
|
390
|
+
comic_qs,
|
|
391
|
+
Comic,
|
|
392
|
+
order_key=order_key,
|
|
393
|
+
do_reverse=False,
|
|
394
|
+
comic_sort_names=comic_sort_names,
|
|
395
|
+
)
|
|
327
396
|
comic_qs = comic_qs.group_by("id")
|
|
328
397
|
return comic_qs.only("pk", "updated_at")
|
|
329
398
|
|
|
@@ -331,8 +400,9 @@ class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
|
|
|
331
400
|
"""Python hack to re-cover groups collapsed with group_by."""
|
|
332
401
|
# This would be better in the main query but OuterRef can't access annotations.
|
|
333
402
|
# So cover_pks aggregates all covers from multi groups like ids does.
|
|
334
|
-
if self.is_model_comic or
|
|
403
|
+
if self.is_model_comic or self.params.get("cover_style") == "i":
|
|
335
404
|
return group_qs
|
|
405
|
+
|
|
336
406
|
recovered_group_list = []
|
|
337
407
|
for group in group_qs:
|
|
338
408
|
cover_pks = group.cover_pks
|
|
@@ -340,7 +410,7 @@ class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
|
|
|
340
410
|
cover_pk = cover_pks[0]
|
|
341
411
|
cover_updated_at = group.updated_at
|
|
342
412
|
else:
|
|
343
|
-
comic_qs = self._get_cover_pk_query(cover_pks)
|
|
413
|
+
comic_qs = self._get_cover_pk_query(cover_pks, group.ids)
|
|
344
414
|
# print(comic_qs.explain())
|
|
345
415
|
# print(comic_qs.query)
|
|
346
416
|
cover = comic_qs[0]
|
|
@@ -7,7 +7,7 @@ from codex.views.browser.browser_annotations import BrowserAnnotationsView
|
|
|
7
7
|
from codex.views.const import GROUP_NAME_MAP
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
|
-
from codex.models.
|
|
10
|
+
from codex.models.groups import Folder
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class BrowserBreadcrumbsView(BrowserAnnotationsView):
|
|
@@ -150,7 +150,7 @@ class BrowserBreadcrumbsView(BrowserAnnotationsView):
|
|
|
150
150
|
) -> tuple[dict[str, str | tuple[int, ...] | int], ...]:
|
|
151
151
|
"""Get the breadcrumbs."""
|
|
152
152
|
breadcrumbs: list[dict[str, str | tuple[int, ...] | int]] = list(
|
|
153
|
-
self.
|
|
153
|
+
self.params.get("breadcrumbs", [])
|
|
154
154
|
)
|
|
155
155
|
|
|
156
156
|
if not self._is_breadcrumbs_identical(breadcrumbs):
|
|
@@ -26,33 +26,44 @@ class BrowserOrderByView(BrowserAnnotationsFilterView):
|
|
|
26
26
|
order_reverse = self.params.get("order_reverse")
|
|
27
27
|
self.order_agg_func = Max if order_reverse else Min
|
|
28
28
|
|
|
29
|
-
def
|
|
29
|
+
def _add_comic_order_by(self, order_key, comic_sort_names):
|
|
30
|
+
"""Order by for comics (and covers)."""
|
|
31
|
+
if not order_key:
|
|
32
|
+
order_key = self.order_key
|
|
33
|
+
if order_key == "sort_name":
|
|
34
|
+
if not comic_sort_names:
|
|
35
|
+
comic_sort_names = self.comic_sort_names # type: ignore
|
|
36
|
+
order_fields_head = [
|
|
37
|
+
*comic_sort_names,
|
|
38
|
+
"issue_number",
|
|
39
|
+
"issue_suffix",
|
|
40
|
+
"sort_name",
|
|
41
|
+
]
|
|
42
|
+
else:
|
|
43
|
+
# Comic orders on indexed fields directly
|
|
44
|
+
# Which is allegedly faster than using tmp b-trees (annotations)
|
|
45
|
+
# And since that's every cover sort, it's worth it.
|
|
46
|
+
order_fields_head = [order_key]
|
|
47
|
+
# Comic order micro optimizations
|
|
48
|
+
if order_key == "story_arc_number":
|
|
49
|
+
order_fields_head += ["date"]
|
|
50
|
+
elif order_key == "bookmark_updated_at":
|
|
51
|
+
order_fields_head += ["updated_at"]
|
|
52
|
+
return order_fields_head
|
|
53
|
+
|
|
54
|
+
def add_order_by( # noqa: PLR0913
|
|
55
|
+
self, qs, model, order_key="", do_reverse=True, comic_sort_names=None
|
|
56
|
+
):
|
|
30
57
|
"""Create the order_by list."""
|
|
31
|
-
order_fields_head =
|
|
58
|
+
order_fields_head = ()
|
|
32
59
|
if model == Comic:
|
|
33
|
-
|
|
34
|
-
order_fields_head = [
|
|
35
|
-
*self.comic_sort_names, # type: ignore
|
|
36
|
-
"issue_number",
|
|
37
|
-
"issue_suffix",
|
|
38
|
-
"sort_name",
|
|
39
|
-
]
|
|
40
|
-
else:
|
|
41
|
-
# Comic orders on indexed fields directly
|
|
42
|
-
# Which is allegedly faster than using tmp b-trees (annotations)
|
|
43
|
-
# And since that's every cover sort, it's worth it.
|
|
44
|
-
order_fields_head = [self.order_key]
|
|
45
|
-
# Comic order micro optimizations
|
|
46
|
-
if self.order_key == "story_arc_number":
|
|
47
|
-
order_fields_head += ["date"]
|
|
48
|
-
elif self.order_key == "bookmark_updated_at":
|
|
49
|
-
order_fields_head += ["updated_at"]
|
|
60
|
+
order_fields_head = self._add_comic_order_by(order_key, comic_sort_names)
|
|
50
61
|
else:
|
|
51
62
|
order_fields_head = ["order_value"]
|
|
52
63
|
|
|
53
64
|
order_fields = (*order_fields_head, "pk")
|
|
54
65
|
|
|
55
|
-
prefix = "-" if self.params.get("order_reverse") else ""
|
|
66
|
+
prefix = "-" if do_reverse and self.params.get("order_reverse") else ""
|
|
56
67
|
order_by = []
|
|
57
68
|
if prefix:
|
|
58
69
|
for field in order_fields:
|
|
@@ -175,7 +175,7 @@ class SearchFilterMixin:
|
|
|
175
175
|
binary
|
|
176
176
|
)
|
|
177
177
|
qs = self.annotate_search_score(qs, model, score_pairs, prev_pks, next_pks)
|
|
178
|
-
if score_pairs:
|
|
178
|
+
if score_pairs or scored_pks:
|
|
179
179
|
search_filter = self._get_search_query_filter(model, scored_pks)
|
|
180
180
|
qs = qs.filter(**search_filter)
|
|
181
181
|
self.cover_search_score_pairs = score_pairs
|
codex/views/browser/metadata.py
CHANGED
codex/views/cover.py
CHANGED
|
@@ -58,11 +58,12 @@ class CoverView(APIView, GroupACLMixin):
|
|
|
58
58
|
thumb_image_data = None
|
|
59
59
|
content_type = "image/webp"
|
|
60
60
|
|
|
61
|
+
custom: bool = self.request.GET.get("custom") == "1"
|
|
61
62
|
pk = self.kwargs.get("pk")
|
|
62
|
-
cover_path = CoverPathMixin.get_cover_path(pk)
|
|
63
|
+
cover_path = CoverPathMixin.get_cover_path(pk, custom)
|
|
63
64
|
if not cover_path.exists():
|
|
64
65
|
thumb_image_data = CoverCreateMixin.create_cover_from_path(
|
|
65
|
-
pk, cover_path, LOG, LIBRARIAN_QUEUE
|
|
66
|
+
pk, cover_path, LOG, LIBRARIAN_QUEUE, custom
|
|
66
67
|
)
|
|
67
68
|
if not thumb_image_data:
|
|
68
69
|
cover_path, content_type = self._get_missing_cover_path()
|
codex/views/session.py
CHANGED
|
@@ -104,6 +104,7 @@ class BrowserSessionViewBase(SessionViewBaseBase):
|
|
|
104
104
|
"q": DEFAULTS["q"],
|
|
105
105
|
"search_results_limit": DEFAULTS["searchResultsLimit"],
|
|
106
106
|
"show": DEFAULTS["show"],
|
|
107
|
+
"cover_style": DEFAULTS["coverStyle"],
|
|
107
108
|
"twenty_four_hour_time": False,
|
|
108
109
|
"top_group": DEFAULTS["topGroup"],
|
|
109
110
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codex
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.0a5
|
|
4
4
|
Summary: A comic archive web server.
|
|
5
5
|
Home-page: https://github.com/ajslater/codex
|
|
6
6
|
License: GPL-3.0-only
|
|
@@ -26,10 +26,11 @@ Classifier: Topic :: Multimedia :: Graphics :: Viewers
|
|
|
26
26
|
Requires-Dist: Pillow (>=10.0.0,<11.0.0)
|
|
27
27
|
Requires-Dist: aioprocessing (>=2.0.1,<3.0.0)
|
|
28
28
|
Requires-Dist: ansicolors (>=1.1,<2.0)
|
|
29
|
+
Requires-Dist: bidict (>=0.23.1,<0.24.0)
|
|
29
30
|
Requires-Dist: case-converter (>=1.1.0,<2.0.0)
|
|
30
31
|
Requires-Dist: channels (>=4.0.0,<5.0.0)
|
|
31
32
|
Requires-Dist: comicbox[pdf] (>=1.1.7,<2.0.0)
|
|
32
|
-
Requires-Dist: django (>=5.0.
|
|
33
|
+
Requires-Dist: django (>=5.0.6,<6.0.0)
|
|
33
34
|
Requires-Dist: django-cachalot (>=2.6.2,<3.0.0)
|
|
34
35
|
Requires-Dist: django-cors-headers (>=4.0,<5.0)
|
|
35
36
|
Requires-Dist: django-rest-registration (>=0.8.0,<0.9.0)
|