codex 1.6.0a4__py3-none-any.whl → 1.6.0a6__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 +28 -18
- codex/librarian/covers/tasks.py +3 -2
- codex/librarian/importer/aggregate_metadata.py +2 -2
- codex/librarian/importer/const.py +31 -3
- codex/librarian/importer/covers.py +47 -0
- codex/librarian/importer/create_fks.py +88 -28
- codex/librarian/importer/deleted.py +71 -9
- codex/librarian/importer/importerd.py +133 -28
- codex/librarian/importer/link_comics.py +55 -0
- codex/librarian/importer/moved.py +78 -3
- codex/librarian/importer/query_fks.py +65 -1
- codex/librarian/importer/status.py +6 -0
- codex/librarian/importer/tasks.py +11 -3
- codex/librarian/importer/update_comics.py +1 -5
- 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/migrations/0029_choices_adminflag_and_timestamp.py +44 -0
- codex/models/admin.py +0 -2
- 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/page.py +0 -1
- codex/serializers/browser/settings.py +3 -0
- codex/settings/settings.py +11 -5
- codex/startup.py +77 -3
- codex/static_root/assets/{VCheckbox-CN6Sn_k7.9bf27129091c.js → VCheckbox-BS5fdM4M.a5d446e4aeb3.js} +1 -1
- codex/static_root/assets/VCheckbox-BS5fdM4M.a5d446e4aeb3.js.br +0 -0
- codex/static_root/assets/VCheckbox-BS5fdM4M.a5d446e4aeb3.js.gz +0 -0
- codex/static_root/assets/{VCheckbox-CN6Sn_k7.js → VCheckbox-BS5fdM4M.js} +1 -1
- codex/static_root/assets/VCheckbox-BS5fdM4M.js.br +0 -0
- codex/static_root/assets/VCheckbox-BS5fdM4M.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-CN1RPZPQ.b763c6a7abaf.js → VCheckboxBtn-m4IbdjEe.f0c4a814ded8.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-m4IbdjEe.f0c4a814ded8.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-m4IbdjEe.f0c4a814ded8.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-CN1RPZPQ.js → VCheckboxBtn-m4IbdjEe.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-m4IbdjEe.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-m4IbdjEe.js.gz +0 -0
- codex/static_root/assets/VCombobox-jg7SI5mn.af66f18b4c54.js +1 -0
- codex/static_root/assets/VCombobox-jg7SI5mn.af66f18b4c54.js.br +0 -0
- codex/static_root/assets/VCombobox-jg7SI5mn.af66f18b4c54.js.gz +0 -0
- codex/static_root/assets/VCombobox-jg7SI5mn.js +1 -0
- codex/static_root/assets/VCombobox-jg7SI5mn.js.br +0 -0
- codex/static_root/assets/VCombobox-jg7SI5mn.js.gz +0 -0
- codex/static_root/assets/{VDialog-DC3KGsMT.71e2a460e44b.js → VDialog-DiixpkQL.f84fd1fd1f84.js} +1 -1
- codex/static_root/assets/VDialog-DiixpkQL.f84fd1fd1f84.js.br +0 -0
- codex/static_root/assets/VDialog-DiixpkQL.f84fd1fd1f84.js.gz +0 -0
- codex/static_root/assets/{VDialog-DC3KGsMT.js → VDialog-DiixpkQL.js} +1 -1
- codex/static_root/assets/VDialog-DiixpkQL.js.br +0 -0
- codex/static_root/assets/VDialog-DiixpkQL.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-DJQYXCn2.f0d471a1b80a.js → VExpansionPanels-Db5mPFue.56d0ad094a62.js} +1 -1
- codex/static_root/assets/VExpansionPanels-Db5mPFue.56d0ad094a62.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-Db5mPFue.56d0ad094a62.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-DJQYXCn2.js → VExpansionPanels-Db5mPFue.js} +1 -1
- codex/static_root/assets/VExpansionPanels-Db5mPFue.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-Db5mPFue.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-CgodTThy.b20290d57146.js → VRadioGroup-DULWiMSI.4ae535e01d2b.js} +1 -1
- codex/static_root/assets/VRadioGroup-DULWiMSI.4ae535e01d2b.js.br +0 -0
- codex/static_root/assets/VRadioGroup-DULWiMSI.4ae535e01d2b.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-CgodTThy.js → VRadioGroup-DULWiMSI.js} +1 -1
- codex/static_root/assets/VRadioGroup-DULWiMSI.js.br +0 -0
- codex/static_root/assets/VRadioGroup-DULWiMSI.js.gz +0 -0
- codex/static_root/assets/VSelect-BnoCfCLY.4d50fd11c77c.js +1 -0
- codex/static_root/assets/VSelect-BnoCfCLY.4d50fd11c77c.js.br +0 -0
- codex/static_root/assets/VSelect-BnoCfCLY.4d50fd11c77c.js.gz +0 -0
- codex/static_root/assets/VSelect-BnoCfCLY.js +1 -0
- codex/static_root/assets/VSelect-BnoCfCLY.js.br +0 -0
- codex/static_root/assets/VSelect-BnoCfCLY.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-zPp4DXWq.635b7f5aa882.js → VSelectionControl-BSL0qeL9.5b5835d286df.js} +1 -1
- codex/static_root/assets/VSelectionControl-BSL0qeL9.5b5835d286df.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BSL0qeL9.5b5835d286df.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-zPp4DXWq.js → VSelectionControl-BSL0qeL9.js} +1 -1
- codex/static_root/assets/VSelectionControl-BSL0qeL9.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BSL0qeL9.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-pK9Xompk.67014b86fc74.js → VSlideGroup-BQtz8h9p.ff97dbf209e1.js} +1 -1
- codex/static_root/assets/VSlideGroup-BQtz8h9p.ff97dbf209e1.js.br +0 -0
- codex/static_root/assets/VSlideGroup-BQtz8h9p.ff97dbf209e1.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-pK9Xompk.js → VSlideGroup-BQtz8h9p.js} +1 -1
- codex/static_root/assets/VSlideGroup-BQtz8h9p.js.br +0 -0
- codex/static_root/assets/VSlideGroup-BQtz8h9p.js.gz +0 -0
- codex/static_root/assets/{VTable-CMi6sDtP.8445f91d9023.js → VTable-C0gAriFq.fa6e4b60d4ef.js} +1 -1
- codex/static_root/assets/VTable-C0gAriFq.fa6e4b60d4ef.js.br +0 -0
- codex/static_root/assets/VTable-C0gAriFq.fa6e4b60d4ef.js.gz +0 -0
- codex/static_root/assets/{VTable-CMi6sDtP.js → VTable-C0gAriFq.js} +1 -1
- codex/static_root/assets/VTable-C0gAriFq.js.br +0 -0
- codex/static_root/assets/VTable-C0gAriFq.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-Da_Hs7ls.c295f24c251e.js +1 -0
- codex/static_root/assets/VTextField-Da_Hs7ls.c295f24c251e.js.br +0 -0
- codex/static_root/assets/VTextField-Da_Hs7ls.c295f24c251e.js.gz +0 -0
- codex/static_root/assets/VTextField-Da_Hs7ls.js +1 -0
- codex/static_root/assets/VTextField-Da_Hs7ls.js.br +0 -0
- codex/static_root/assets/VTextField-Da_Hs7ls.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-DNsRQx9l.c42f636c386e.js → VWindowItem-CFhKCj49.b2458002a937.js} +1 -1
- codex/static_root/assets/VWindowItem-CFhKCj49.b2458002a937.js.br +0 -0
- codex/static_root/assets/VWindowItem-CFhKCj49.b2458002a937.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-DNsRQx9l.js → VWindowItem-CFhKCj49.js} +1 -1
- codex/static_root/assets/VWindowItem-CFhKCj49.js.br +0 -0
- codex/static_root/assets/VWindowItem-CFhKCj49.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-BpGFsvOH.d7193c78d0dd.js +1 -0
- codex/static_root/assets/admin-BpGFsvOH.d7193c78d0dd.js.br +0 -0
- codex/static_root/assets/admin-BpGFsvOH.d7193c78d0dd.js.gz +0 -0
- codex/static_root/assets/admin-BpGFsvOH.js +1 -0
- codex/static_root/assets/admin-BpGFsvOH.js.br +0 -0
- codex/static_root/assets/admin-BpGFsvOH.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/admin-drawer-panel-C34Ze3-5.113c50cdf2cc.js +30 -0
- codex/static_root/assets/admin-drawer-panel-C34Ze3-5.113c50cdf2cc.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-C34Ze3-5.113c50cdf2cc.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-C34Ze3-5.js +30 -0
- codex/static_root/assets/admin-drawer-panel-C34Ze3-5.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-C34Ze3-5.js.gz +0 -0
- codex/static_root/assets/browser-CRPvEdqv.f355a71f4380.js +1 -0
- codex/static_root/assets/browser-CRPvEdqv.f355a71f4380.js.br +0 -0
- codex/static_root/assets/browser-CRPvEdqv.f355a71f4380.js.gz +0 -0
- codex/static_root/assets/browser-CRPvEdqv.js +1 -0
- codex/static_root/assets/browser-CRPvEdqv.js.br +0 -0
- codex/static_root/assets/browser-CRPvEdqv.js.gz +0 -0
- codex/static_root/assets/browser-Zqc9cR6T.b7d6ddeff130.css +1 -0
- codex/static_root/assets/browser-Zqc9cR6T.b7d6ddeff130.css.br +0 -0
- codex/static_root/assets/browser-Zqc9cR6T.b7d6ddeff130.css.gz +0 -0
- codex/static_root/assets/browser-Zqc9cR6T.css +1 -0
- codex/static_root/assets/browser-Zqc9cR6T.css.br +0 -0
- codex/static_root/assets/browser-Zqc9cR6T.css.gz +0 -0
- codex/static_root/assets/{change-password-dialog-BHTkpC6Z.2d5d5dd57ad3.js → change-password-dialog-JYM9aAR9.f71d378f4fa6.js} +1 -1
- codex/static_root/assets/change-password-dialog-JYM9aAR9.f71d378f4fa6.js.br +0 -0
- codex/static_root/assets/change-password-dialog-JYM9aAR9.f71d378f4fa6.js.gz +0 -0
- codex/static_root/assets/{change-password-dialog-BHTkpC6Z.js → change-password-dialog-JYM9aAR9.js} +1 -1
- codex/static_root/assets/change-password-dialog-JYM9aAR9.js.br +0 -0
- codex/static_root/assets/change-password-dialog-JYM9aAR9.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-DmXGDg4z.284812bd376d.js → confirm-dialog-ZAZ6P1Rc.515858dd21e8.js} +1 -1
- codex/static_root/assets/confirm-dialog-ZAZ6P1Rc.515858dd21e8.js.br +0 -0
- codex/static_root/assets/confirm-dialog-ZAZ6P1Rc.515858dd21e8.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-DmXGDg4z.js → confirm-dialog-ZAZ6P1Rc.js} +1 -1
- codex/static_root/assets/confirm-dialog-ZAZ6P1Rc.js.br +0 -0
- codex/static_root/assets/confirm-dialog-ZAZ6P1Rc.js.gz +0 -0
- codex/static_root/assets/{datetime-column-DKaH5S3z.5c6042016200.js → datetime-column-BT1MSP82.9617f6b94ebf.js} +1 -1
- codex/static_root/assets/datetime-column-BT1MSP82.9617f6b94ebf.js.br +0 -0
- codex/static_root/assets/datetime-column-BT1MSP82.9617f6b94ebf.js.gz +0 -0
- codex/static_root/assets/{datetime-column-DKaH5S3z.js → datetime-column-BT1MSP82.js} +1 -1
- codex/static_root/assets/datetime-column-BT1MSP82.js.br +0 -0
- codex/static_root/assets/datetime-column-BT1MSP82.js.gz +0 -0
- codex/static_root/assets/{filter-DUVATQW3.e1e7aa6d0b18.js → filter-frSNsexx.eab1570bd32d.js} +1 -1
- codex/static_root/assets/filter-frSNsexx.eab1570bd32d.js.br +0 -0
- codex/static_root/assets/filter-frSNsexx.eab1570bd32d.js.gz +0 -0
- codex/static_root/assets/{filter-DUVATQW3.js → filter-frSNsexx.js} +1 -1
- codex/static_root/assets/filter-frSNsexx.js.br +0 -0
- codex/static_root/assets/filter-frSNsexx.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-Ci_XcDT0.a5ea640a08d6.js +1 -0
- codex/static_root/assets/flag-tab-Ci_XcDT0.a5ea640a08d6.js.br +0 -0
- codex/static_root/assets/flag-tab-Ci_XcDT0.a5ea640a08d6.js.gz +0 -0
- codex/static_root/assets/flag-tab-Ci_XcDT0.js +1 -0
- codex/static_root/assets/flag-tab-Ci_XcDT0.js.br +0 -0
- codex/static_root/assets/flag-tab-Ci_XcDT0.js.gz +0 -0
- codex/static_root/assets/{group-tab-D3CyU-Il.fbf9ce5ef593.js → group-tab-DFma2R-E.879c37b15bbd.js} +1 -1
- codex/static_root/assets/group-tab-DFma2R-E.879c37b15bbd.js.br +0 -0
- codex/static_root/assets/group-tab-DFma2R-E.879c37b15bbd.js.gz +0 -0
- codex/static_root/assets/{group-tab-D3CyU-Il.js → group-tab-DFma2R-E.js} +1 -1
- codex/static_root/assets/group-tab-DFma2R-E.js.br +0 -0
- codex/static_root/assets/group-tab-DFma2R-E.js.gz +0 -0
- codex/static_root/assets/{http-error-0ef6-Ajc.e2879bcd242f.js → http-error-B3fQGxpt.9efc29496e30.js} +1 -1
- codex/static_root/assets/http-error-B3fQGxpt.9efc29496e30.js.br +0 -0
- codex/static_root/assets/http-error-B3fQGxpt.9efc29496e30.js.gz +0 -0
- codex/static_root/assets/{http-error-0ef6-Ajc.js → http-error-B3fQGxpt.js} +1 -1
- codex/static_root/assets/http-error-B3fQGxpt.js.br +0 -0
- codex/static_root/assets/http-error-B3fQGxpt.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-V8DUGoHN.809c548ff347.js +1 -0
- codex/static_root/assets/library-tab-V8DUGoHN.809c548ff347.js.br +0 -0
- codex/static_root/assets/library-tab-V8DUGoHN.809c548ff347.js.gz +0 -0
- codex/static_root/assets/library-tab-V8DUGoHN.js +1 -0
- codex/static_root/assets/library-tab-V8DUGoHN.js.br +0 -0
- codex/static_root/assets/library-tab-V8DUGoHN.js.gz +0 -0
- codex/static_root/assets/{main-CuzJev9T.js → main-Cavvqkyp.a9c4df906406.js} +6 -6
- codex/static_root/assets/main-Cavvqkyp.a9c4df906406.js.br +0 -0
- codex/static_root/assets/main-Cavvqkyp.a9c4df906406.js.gz +0 -0
- codex/static_root/assets/{main-CuzJev9T.f58771cc37e2.js → main-Cavvqkyp.js} +6 -6
- codex/static_root/assets/main-Cavvqkyp.js.br +0 -0
- codex/static_root/assets/main-Cavvqkyp.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-Dg9tH1Ju.b2eb1e0c6985.js +1 -0
- codex/static_root/assets/pagination-toolbar-Dg9tH1Ju.b2eb1e0c6985.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-Dg9tH1Ju.b2eb1e0c6985.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-Dg9tH1Ju.js +1 -0
- codex/static_root/assets/pagination-toolbar-Dg9tH1Ju.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-Dg9tH1Ju.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-BlU5mm5n.0431bcdf48d1.js → pdf-doc-4PKLN-Z3.62d8de4d1fd8.js} +1 -1
- codex/static_root/assets/pdf-doc-4PKLN-Z3.62d8de4d1fd8.js.br +0 -0
- codex/static_root/assets/pdf-doc-4PKLN-Z3.62d8de4d1fd8.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-BlU5mm5n.js → pdf-doc-4PKLN-Z3.js} +1 -1
- codex/static_root/assets/pdf-doc-4PKLN-Z3.js.br +0 -0
- codex/static_root/assets/pdf-doc-4PKLN-Z3.js.gz +0 -0
- codex/static_root/assets/{reader-s7jttB_F.f7b43b04961a.js → reader-C39uGGxn.67b0f324cd5e.js} +2 -2
- codex/static_root/assets/reader-C39uGGxn.67b0f324cd5e.js.br +0 -0
- codex/static_root/assets/reader-C39uGGxn.67b0f324cd5e.js.gz +0 -0
- codex/static_root/assets/{reader-s7jttB_F.js → reader-C39uGGxn.js} +2 -2
- codex/static_root/assets/reader-C39uGGxn.js.br +0 -0
- codex/static_root/assets/reader-C39uGGxn.js.gz +0 -0
- codex/static_root/assets/{reader-BiKxuxj7.css → reader-N2Ei_y2K.8c0cdc0d513f.css} +1 -1
- codex/static_root/assets/reader-N2Ei_y2K.8c0cdc0d513f.css.br +0 -0
- codex/static_root/assets/reader-N2Ei_y2K.8c0cdc0d513f.css.gz +0 -0
- codex/static_root/assets/{reader-BiKxuxj7.dabe592f46f1.css → reader-N2Ei_y2K.css} +1 -1
- codex/static_root/assets/reader-N2Ei_y2K.css.br +0 -0
- codex/static_root/assets/reader-N2Ei_y2K.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-CAC5ytqH.f205d920ffea.js +1 -0
- codex/static_root/assets/relation-chips-CAC5ytqH.f205d920ffea.js.br +0 -0
- codex/static_root/assets/relation-chips-CAC5ytqH.f205d920ffea.js.gz +0 -0
- codex/static_root/assets/relation-chips-CAC5ytqH.js +1 -0
- codex/static_root/assets/relation-chips-CAC5ytqH.js.br +0 -0
- codex/static_root/assets/relation-chips-CAC5ytqH.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-DbJuixzh.352aaaab5925.js → settings-drawer-CT73ieiV.fac6f69e86ff.js} +2 -2
- codex/static_root/assets/settings-drawer-CT73ieiV.fac6f69e86ff.js.br +0 -0
- codex/static_root/assets/settings-drawer-CT73ieiV.fac6f69e86ff.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-DbJuixzh.js → settings-drawer-CT73ieiV.js} +2 -2
- codex/static_root/assets/settings-drawer-CT73ieiV.js.br +0 -0
- codex/static_root/assets/settings-drawer-CT73ieiV.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-BJOfMtqA.6471a50fc05b.css → settings-drawer-nZ9HvKSZ.01744e131806.css} +1 -1
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.01744e131806.css.br +0 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.01744e131806.css.gz +0 -0
- codex/static_root/assets/{settings-drawer-BJOfMtqA.css → settings-drawer-nZ9HvKSZ.css} +1 -1
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.css.br +0 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.css.gz +0 -0
- codex/static_root/assets/{stats-tab-BhRLh7XB.7be95b5021c3.js → stats-tab-C6qAnV6-.f08c46b5f141.js} +1 -1
- codex/static_root/assets/stats-tab-C6qAnV6-.f08c46b5f141.js.br +0 -0
- codex/static_root/assets/stats-tab-C6qAnV6-.f08c46b5f141.js.gz +0 -0
- codex/static_root/assets/{stats-tab-BhRLh7XB.js → stats-tab-C6qAnV6-.js} +1 -1
- codex/static_root/assets/stats-tab-C6qAnV6-.js.br +0 -0
- codex/static_root/assets/stats-tab-C6qAnV6-.js.gz +0 -0
- codex/static_root/assets/task-tab-JcG2vvgt.eed6e03db487.js +1 -0
- codex/static_root/assets/task-tab-JcG2vvgt.eed6e03db487.js.br +0 -0
- codex/static_root/assets/task-tab-JcG2vvgt.eed6e03db487.js.gz +0 -0
- codex/static_root/assets/task-tab-JcG2vvgt.js +1 -0
- codex/static_root/assets/task-tab-JcG2vvgt.js.br +0 -0
- codex/static_root/assets/task-tab-JcG2vvgt.js.gz +0 -0
- codex/static_root/assets/{unauthorized-BgXQnNpn.f63b36d526b5.js → unauthorized-28bmiwAU.c74825b5c16f.js} +1 -1
- codex/static_root/assets/unauthorized-28bmiwAU.c74825b5c16f.js.br +0 -0
- codex/static_root/assets/unauthorized-28bmiwAU.c74825b5c16f.js.gz +0 -0
- codex/static_root/assets/{unauthorized-BgXQnNpn.js → unauthorized-28bmiwAU.js} +1 -1
- codex/static_root/assets/unauthorized-28bmiwAU.js.br +0 -0
- codex/static_root/assets/unauthorized-28bmiwAU.js.gz +0 -0
- codex/static_root/assets/{user-tab-cZoJDlb-.2a497e8b2b24.js → user-tab-BOq4BMMc.b64ac15dd772.js} +1 -1
- codex/static_root/assets/user-tab-BOq4BMMc.b64ac15dd772.js.br +0 -0
- codex/static_root/assets/user-tab-BOq4BMMc.b64ac15dd772.js.gz +0 -0
- codex/static_root/assets/{user-tab-cZoJDlb-.js → user-tab-BOq4BMMc.js} +1 -1
- codex/static_root/assets/user-tab-BOq4BMMc.js.br +0 -0
- codex/static_root/assets/user-tab-BOq4BMMc.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.ad9da9714e46.json +642 -0
- codex/static_root/manifest.ad9da9714e46.json.br +0 -0
- codex/static_root/manifest.ad9da9714e46.json.gz +0 -0
- codex/static_root/manifest.json +256 -256
- 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 +3 -3
- codex/views/browser/browser.py +1 -9
- codex/views/browser/browser_annotations.py +101 -20
- codex/views/browser/browser_breadcrumbs.py +2 -2
- codex/views/browser/browser_order_by.py +31 -20
- codex/views/browser/filters/field.py +3 -1
- 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.0a4.dist-info → codex-1.6.0a6.dist-info}/METADATA +3 -2
- {codex-1.6.0a4.dist-info → codex-1.6.0a6.dist-info}/RECORD +350 -347
- codex/static_root/assets/VCheckbox-CN6Sn_k7.9bf27129091c.js.br +0 -0
- codex/static_root/assets/VCheckbox-CN6Sn_k7.9bf27129091c.js.gz +0 -0
- codex/static_root/assets/VCheckbox-CN6Sn_k7.js.br +0 -0
- codex/static_root/assets/VCheckbox-CN6Sn_k7.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-CN1RPZPQ.b763c6a7abaf.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-CN1RPZPQ.b763c6a7abaf.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-CN1RPZPQ.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-CN1RPZPQ.js.gz +0 -0
- codex/static_root/assets/VCombobox-CtLUGYtD.6e49097cea2c.js +0 -1
- codex/static_root/assets/VCombobox-CtLUGYtD.6e49097cea2c.js.br +0 -0
- codex/static_root/assets/VCombobox-CtLUGYtD.6e49097cea2c.js.gz +0 -0
- codex/static_root/assets/VCombobox-CtLUGYtD.js +0 -1
- codex/static_root/assets/VCombobox-CtLUGYtD.js.br +0 -0
- codex/static_root/assets/VCombobox-CtLUGYtD.js.gz +0 -0
- codex/static_root/assets/VDialog-DC3KGsMT.71e2a460e44b.js.br +0 -0
- codex/static_root/assets/VDialog-DC3KGsMT.71e2a460e44b.js.gz +0 -0
- codex/static_root/assets/VDialog-DC3KGsMT.js.br +0 -0
- codex/static_root/assets/VDialog-DC3KGsMT.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DJQYXCn2.f0d471a1b80a.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-DJQYXCn2.f0d471a1b80a.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DJQYXCn2.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-DJQYXCn2.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-CgodTThy.b20290d57146.js.br +0 -0
- codex/static_root/assets/VRadioGroup-CgodTThy.b20290d57146.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-CgodTThy.js.br +0 -0
- codex/static_root/assets/VRadioGroup-CgodTThy.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-B6s-x36h.de1030c82785.js +0 -1
- codex/static_root/assets/VSelect-B6s-x36h.de1030c82785.js.br +0 -0
- codex/static_root/assets/VSelect-B6s-x36h.de1030c82785.js.gz +0 -0
- codex/static_root/assets/VSelect-B6s-x36h.js +0 -1
- codex/static_root/assets/VSelect-B6s-x36h.js.br +0 -0
- codex/static_root/assets/VSelect-B6s-x36h.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-zPp4DXWq.635b7f5aa882.js.br +0 -0
- codex/static_root/assets/VSelectionControl-zPp4DXWq.635b7f5aa882.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-zPp4DXWq.js.br +0 -0
- codex/static_root/assets/VSelectionControl-zPp4DXWq.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-pK9Xompk.67014b86fc74.js.br +0 -0
- codex/static_root/assets/VSlideGroup-pK9Xompk.67014b86fc74.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-pK9Xompk.js.br +0 -0
- codex/static_root/assets/VSlideGroup-pK9Xompk.js.gz +0 -0
- codex/static_root/assets/VTable-CMi6sDtP.8445f91d9023.js.br +0 -0
- codex/static_root/assets/VTable-CMi6sDtP.8445f91d9023.js.gz +0 -0
- codex/static_root/assets/VTable-CMi6sDtP.js.br +0 -0
- codex/static_root/assets/VTable-CMi6sDtP.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/VTextField-dMTizQEN.e93eefec0fdf.js +0 -1
- codex/static_root/assets/VTextField-dMTizQEN.e93eefec0fdf.js.br +0 -0
- codex/static_root/assets/VTextField-dMTizQEN.e93eefec0fdf.js.gz +0 -0
- codex/static_root/assets/VTextField-dMTizQEN.js +0 -1
- codex/static_root/assets/VTextField-dMTizQEN.js.br +0 -0
- codex/static_root/assets/VTextField-dMTizQEN.js.gz +0 -0
- codex/static_root/assets/VWindowItem-DNsRQx9l.c42f636c386e.js.br +0 -0
- codex/static_root/assets/VWindowItem-DNsRQx9l.c42f636c386e.js.gz +0 -0
- codex/static_root/assets/VWindowItem-DNsRQx9l.js.br +0 -0
- codex/static_root/assets/VWindowItem-DNsRQx9l.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-CApphpty.5a41cbf0eefc.js +0 -1
- codex/static_root/assets/admin-CApphpty.5a41cbf0eefc.js.br +0 -0
- codex/static_root/assets/admin-CApphpty.5a41cbf0eefc.js.gz +0 -0
- codex/static_root/assets/admin-CApphpty.js +0 -1
- codex/static_root/assets/admin-CApphpty.js.br +0 -0
- codex/static_root/assets/admin-CApphpty.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/admin-drawer-panel-Dp8KD9D7.a79eda3055a7.js +0 -30
- codex/static_root/assets/admin-drawer-panel-Dp8KD9D7.a79eda3055a7.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-Dp8KD9D7.a79eda3055a7.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-Dp8KD9D7.js +0 -30
- codex/static_root/assets/admin-drawer-panel-Dp8KD9D7.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-Dp8KD9D7.js.gz +0 -0
- codex/static_root/assets/browser-C_PHQbyN.bb065e2ce21a.js +0 -1
- codex/static_root/assets/browser-C_PHQbyN.bb065e2ce21a.js.br +0 -0
- codex/static_root/assets/browser-C_PHQbyN.bb065e2ce21a.js.gz +0 -0
- codex/static_root/assets/browser-C_PHQbyN.js +0 -1
- codex/static_root/assets/browser-C_PHQbyN.js.br +0 -0
- codex/static_root/assets/browser-C_PHQbyN.js.gz +0 -0
- codex/static_root/assets/browser-DVI4LUNv.css +0 -1
- codex/static_root/assets/browser-DVI4LUNv.css.br +0 -0
- codex/static_root/assets/browser-DVI4LUNv.css.gz +0 -0
- codex/static_root/assets/browser-DVI4LUNv.fef2b997145a.css +0 -1
- codex/static_root/assets/browser-DVI4LUNv.fef2b997145a.css.br +0 -0
- codex/static_root/assets/browser-DVI4LUNv.fef2b997145a.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-BHTkpC6Z.2d5d5dd57ad3.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BHTkpC6Z.2d5d5dd57ad3.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-BHTkpC6Z.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BHTkpC6Z.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-DmXGDg4z.284812bd376d.js.br +0 -0
- codex/static_root/assets/confirm-dialog-DmXGDg4z.284812bd376d.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-DmXGDg4z.js.br +0 -0
- codex/static_root/assets/confirm-dialog-DmXGDg4z.js.gz +0 -0
- codex/static_root/assets/datetime-column-DKaH5S3z.5c6042016200.js.br +0 -0
- codex/static_root/assets/datetime-column-DKaH5S3z.5c6042016200.js.gz +0 -0
- codex/static_root/assets/datetime-column-DKaH5S3z.js.br +0 -0
- codex/static_root/assets/datetime-column-DKaH5S3z.js.gz +0 -0
- codex/static_root/assets/filter-DUVATQW3.e1e7aa6d0b18.js.br +0 -0
- codex/static_root/assets/filter-DUVATQW3.e1e7aa6d0b18.js.gz +0 -0
- codex/static_root/assets/filter-DUVATQW3.js.br +0 -0
- codex/static_root/assets/filter-DUVATQW3.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/flag-tab-CSKMJEn-.5d5c0604541b.js +0 -1
- codex/static_root/assets/flag-tab-CSKMJEn-.5d5c0604541b.js.br +0 -0
- codex/static_root/assets/flag-tab-CSKMJEn-.5d5c0604541b.js.gz +0 -0
- codex/static_root/assets/flag-tab-CSKMJEn-.js +0 -1
- codex/static_root/assets/flag-tab-CSKMJEn-.js.br +0 -0
- codex/static_root/assets/flag-tab-CSKMJEn-.js.gz +0 -0
- codex/static_root/assets/group-tab-D3CyU-Il.fbf9ce5ef593.js.br +0 -0
- codex/static_root/assets/group-tab-D3CyU-Il.fbf9ce5ef593.js.gz +0 -0
- codex/static_root/assets/group-tab-D3CyU-Il.js.br +0 -0
- codex/static_root/assets/group-tab-D3CyU-Il.js.gz +0 -0
- codex/static_root/assets/http-error-0ef6-Ajc.e2879bcd242f.js.br +0 -0
- codex/static_root/assets/http-error-0ef6-Ajc.e2879bcd242f.js.gz +0 -0
- codex/static_root/assets/http-error-0ef6-Ajc.js.br +0 -0
- codex/static_root/assets/http-error-0ef6-Ajc.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/library-tab-IdDfLn4k.70b55460b8e1.js +0 -1
- codex/static_root/assets/library-tab-IdDfLn4k.70b55460b8e1.js.br +0 -0
- codex/static_root/assets/library-tab-IdDfLn4k.70b55460b8e1.js.gz +0 -0
- codex/static_root/assets/library-tab-IdDfLn4k.js +0 -1
- codex/static_root/assets/library-tab-IdDfLn4k.js.br +0 -0
- codex/static_root/assets/library-tab-IdDfLn4k.js.gz +0 -0
- codex/static_root/assets/main-CuzJev9T.f58771cc37e2.js.br +0 -0
- codex/static_root/assets/main-CuzJev9T.f58771cc37e2.js.gz +0 -0
- codex/static_root/assets/main-CuzJev9T.js.br +0 -0
- codex/static_root/assets/main-CuzJev9T.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-CLr9RVHd.66d3b756d974.js +0 -1
- codex/static_root/assets/pagination-toolbar-CLr9RVHd.66d3b756d974.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-CLr9RVHd.66d3b756d974.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-CLr9RVHd.js +0 -1
- codex/static_root/assets/pagination-toolbar-CLr9RVHd.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-CLr9RVHd.js.gz +0 -0
- codex/static_root/assets/pdf-doc-BlU5mm5n.0431bcdf48d1.js.br +0 -0
- codex/static_root/assets/pdf-doc-BlU5mm5n.0431bcdf48d1.js.gz +0 -0
- codex/static_root/assets/pdf-doc-BlU5mm5n.js.br +0 -0
- codex/static_root/assets/pdf-doc-BlU5mm5n.js.gz +0 -0
- codex/static_root/assets/reader-BiKxuxj7.css.br +0 -0
- codex/static_root/assets/reader-BiKxuxj7.css.gz +0 -0
- codex/static_root/assets/reader-BiKxuxj7.dabe592f46f1.css.br +0 -0
- codex/static_root/assets/reader-BiKxuxj7.dabe592f46f1.css.gz +0 -0
- codex/static_root/assets/reader-s7jttB_F.f7b43b04961a.js.br +0 -0
- codex/static_root/assets/reader-s7jttB_F.f7b43b04961a.js.gz +0 -0
- codex/static_root/assets/reader-s7jttB_F.js.br +0 -0
- codex/static_root/assets/reader-s7jttB_F.js.gz +0 -0
- codex/static_root/assets/relation-chips-BiVsYCd9.27eca8616ba4.js +0 -1
- codex/static_root/assets/relation-chips-BiVsYCd9.27eca8616ba4.js.br +0 -0
- codex/static_root/assets/relation-chips-BiVsYCd9.27eca8616ba4.js.gz +0 -0
- codex/static_root/assets/relation-chips-BiVsYCd9.js +0 -1
- codex/static_root/assets/relation-chips-BiVsYCd9.js.br +0 -0
- codex/static_root/assets/relation-chips-BiVsYCd9.js.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/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.br +0 -0
- codex/static_root/assets/settings-drawer-BJOfMtqA.css.gz +0 -0
- codex/static_root/assets/settings-drawer-DbJuixzh.352aaaab5925.js.br +0 -0
- codex/static_root/assets/settings-drawer-DbJuixzh.352aaaab5925.js.gz +0 -0
- codex/static_root/assets/settings-drawer-DbJuixzh.js.br +0 -0
- codex/static_root/assets/settings-drawer-DbJuixzh.js.gz +0 -0
- codex/static_root/assets/stats-tab-BhRLh7XB.7be95b5021c3.js.br +0 -0
- codex/static_root/assets/stats-tab-BhRLh7XB.7be95b5021c3.js.gz +0 -0
- codex/static_root/assets/stats-tab-BhRLh7XB.js.br +0 -0
- codex/static_root/assets/stats-tab-BhRLh7XB.js.gz +0 -0
- codex/static_root/assets/task-tab-DLrd54z2.c574111658b9.js +0 -1
- codex/static_root/assets/task-tab-DLrd54z2.c574111658b9.js.br +0 -0
- codex/static_root/assets/task-tab-DLrd54z2.c574111658b9.js.gz +0 -0
- codex/static_root/assets/task-tab-DLrd54z2.js +0 -1
- codex/static_root/assets/task-tab-DLrd54z2.js.br +0 -0
- codex/static_root/assets/task-tab-DLrd54z2.js.gz +0 -0
- codex/static_root/assets/unauthorized-BgXQnNpn.f63b36d526b5.js.br +0 -0
- codex/static_root/assets/unauthorized-BgXQnNpn.f63b36d526b5.js.gz +0 -0
- codex/static_root/assets/unauthorized-BgXQnNpn.js.br +0 -0
- codex/static_root/assets/unauthorized-BgXQnNpn.js.gz +0 -0
- codex/static_root/assets/user-tab-cZoJDlb-.2a497e8b2b24.js.br +0 -0
- codex/static_root/assets/user-tab-cZoJDlb-.2a497e8b2b24.js.gz +0 -0
- codex/static_root/assets/user-tab-cZoJDlb-.js.br +0 -0
- codex/static_root/assets/user-tab-cZoJDlb-.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.3c2f342d5f5a.json +0 -642
- codex/static_root/manifest.3c2f342d5f5a.json.br +0 -0
- codex/static_root/manifest.3c2f342d5f5a.json.gz +0 -0
- {codex-1.6.0a4.dist-info → codex-1.6.0a6.dist-info}/LICENSE +0 -0
- {codex-1.6.0a4.dist-info → codex-1.6.0a6.dist-info}/WHEEL +0 -0
- {codex-1.6.0a4.dist-info → codex-1.6.0a6.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/change-password-dialog-BHTkpC6Z.js": "assets/change-password-dialog-BHTkpC6Z.2d5d5dd57ad3.js", "assets/VCheckbox-CN6Sn_k7.js": "assets/VCheckbox-CN6Sn_k7.9bf27129091c.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/user-tab-cZoJDlb-.js": "assets/user-tab-cZoJDlb-.2a497e8b2b24.js", "assets/main-CuzJev9T.js": "assets/main-CuzJev9T.f58771cc37e2.js", "assets/VCombobox-CtLUGYtD.js": "assets/VCombobox-CtLUGYtD.6e49097cea2c.js", "assets/datetime-column-DKaH5S3z.js": "assets/datetime-column-DKaH5S3z.5c6042016200.js", "assets/VSelect-B6s-x36h.js": "assets/VSelect-B6s-x36h.de1030c82785.js", "assets/VTable-DflzroDq.css": "assets/VTable-DflzroDq.160504d82195.css", "assets/confirm-dialog-DmXGDg4z.js": "assets/confirm-dialog-DmXGDg4z.284812bd376d.js", "assets/task-tab-DLrd54z2.js": "assets/task-tab-DLrd54z2.c574111658b9.js", "assets/VWindowItem-DNsRQx9l.js": "assets/VWindowItem-DNsRQx9l.c42f636c386e.js", "assets/VExpansionPanels-DsEXVcCv.css": "assets/VExpansionPanels-DsEXVcCv.20b475255e66.css", "assets/admin-drawer-panel-BF0dMvEE.css": "assets/admin-drawer-panel-BF0dMvEE.1514926c78e8.css", "assets/VCheckboxBtn-CN1RPZPQ.js": "assets/VCheckboxBtn-CN1RPZPQ.b763c6a7abaf.js", "assets/browser-DVI4LUNv.css": "assets/browser-DVI4LUNv.fef2b997145a.css", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/VTextField-dMTizQEN.js": "assets/VTextField-dMTizQEN.e93eefec0fdf.js", "assets/VSelect-ARDhJiQK.css": "assets/VSelect-ARDhJiQK.372c098fb475.css", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/flag-tab-BacZLlVi.css": "assets/flag-tab-BacZLlVi.8deba6a5370d.css", "assets/VSlideGroup-Dk_1upHt.css": "assets/VSlideGroup-Dk_1upHt.2c836070ec75.css", "assets/pagination-toolbar-CLr9RVHd.js": "assets/pagination-toolbar-CLr9RVHd.66d3b756d974.js", "assets/VDialog-DC3KGsMT.js": "assets/VDialog-DC3KGsMT.71e2a460e44b.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/browser-C_PHQbyN.js": "assets/browser-C_PHQbyN.bb065e2ce21a.js", "assets/relation-chips-BiVsYCd9.js": "assets/relation-chips-BiVsYCd9.27eca8616ba4.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/admin-drawer-panel-Dp8KD9D7.js": "assets/admin-drawer-panel-Dp8KD9D7.a79eda3055a7.js", "assets/settings-drawer-DbJuixzh.js": "assets/settings-drawer-DbJuixzh.352aaaab5925.js", "assets/group-tab-D3CyU-Il.js": "assets/group-tab-D3CyU-Il.fbf9ce5ef593.js", "assets/stats-tab-BhRLh7XB.js": "assets/stats-tab-BhRLh7XB.7be95b5021c3.js", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/unauthorized-DHV6Q1n-.css": "assets/unauthorized-DHV6Q1n-.b7847b2872a1.css", "assets/VExpansionPanels-DJQYXCn2.js": "assets/VExpansionPanels-DJQYXCn2.f0d471a1b80a.js", "assets/settings-drawer-BJOfMtqA.css": "assets/settings-drawer-BJOfMtqA.6471a50fc05b.css", "assets/VSelectionControl-zPp4DXWq.js": "assets/VSelectionControl-zPp4DXWq.635b7f5aa882.js", "assets/change-password-dialog-HvIvmmIE.css": "assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css", "assets/reader-BiKxuxj7.css": "assets/reader-BiKxuxj7.dabe592f46f1.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/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/admin-BbrOU9Y9.css": "assets/admin-BbrOU9Y9.29936748af9e.css", "assets/VSlideGroup-pK9Xompk.js": "assets/VSlideGroup-pK9Xompk.67014b86fc74.js", "assets/VRadioGroup-CgodTThy.js": "assets/VRadioGroup-CgodTThy.b20290d57146.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/unauthorized-BgXQnNpn.js": "assets/unauthorized-BgXQnNpn.f63b36d526b5.js", "assets/main-sK7HC5h4.css": "assets/main-sK7HC5h4.6f04ddfc5f1a.css", "assets/http-error-0ef6-Ajc.js": "assets/http-error-0ef6-Ajc.e2879bcd242f.js", "assets/flag-tab-CSKMJEn-.js": "assets/flag-tab-CSKMJEn-.5d5c0604541b.js", "assets/pagination-toolbar-B3wS4_7p.css": "assets/pagination-toolbar-B3wS4_7p.7695fafdefce.css", "assets/library-tab-IdDfLn4k.js": "assets/library-tab-IdDfLn4k.70b55460b8e1.js", "assets/pdf-doc-BlU5mm5n.js": "assets/pdf-doc-BlU5mm5n.0431bcdf48d1.js", "assets/VTable-CMi6sDtP.js": "assets/VTable-CMi6sDtP.8445f91d9023.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/http-error-DKulXuTl.css": "assets/http-error-DKulXuTl.95e42988d5d5.css", "assets/reader-s7jttB_F.js": "assets/reader-s7jttB_F.f7b43b04961a.js", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/filter-DUVATQW3.js": "assets/filter-DUVATQW3.e1e7aa6d0b18.js", "assets/admin-CApphpty.js": "assets/admin-CApphpty.5a41cbf0eefc.js", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.3c2f342d5f5a.json"}, "version": "1.1", "hash": "7ec57d0ea55a"}
|
|
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-DiixpkQL.js": "assets/VDialog-DiixpkQL.f84fd1fd1f84.js", "assets/confirm-dialog-ZAZ6P1Rc.js": "assets/confirm-dialog-ZAZ6P1Rc.515858dd21e8.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/VExpansionPanels-Db5mPFue.js": "assets/VExpansionPanels-Db5mPFue.56d0ad094a62.js", "assets/VTable-DflzroDq.css": "assets/VTable-DflzroDq.160504d82195.css", "assets/datetime-column-BT1MSP82.js": "assets/datetime-column-BT1MSP82.9617f6b94ebf.js", "assets/VExpansionPanels-DsEXVcCv.css": "assets/VExpansionPanels-DsEXVcCv.20b475255e66.css", "assets/unauthorized-28bmiwAU.js": "assets/unauthorized-28bmiwAU.c74825b5c16f.js", "assets/VSelect-BnoCfCLY.js": "assets/VSelect-BnoCfCLY.4d50fd11c77c.js", "assets/settings-drawer-CT73ieiV.js": "assets/settings-drawer-CT73ieiV.fac6f69e86ff.js", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/VWindowItem-CFhKCj49.js": "assets/VWindowItem-CFhKCj49.b2458002a937.js", "assets/relation-chips-Bsc-gUxE.css": "assets/relation-chips-Bsc-gUxE.98e65384c3c9.css", "assets/task-tab-JcG2vvgt.js": "assets/task-tab-JcG2vvgt.eed6e03db487.js", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/VSelectionControl-BSL0qeL9.js": "assets/VSelectionControl-BSL0qeL9.5b5835d286df.js", "assets/group-tab-DFma2R-E.js": "assets/group-tab-DFma2R-E.879c37b15bbd.js", "assets/VSlideGroup-Dk_1upHt.css": "assets/VSlideGroup-Dk_1upHt.2c836070ec75.css", "assets/user-tab-BOq4BMMc.js": "assets/user-tab-BOq4BMMc.b64ac15dd772.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/flag-tab-BNwbLfrN.css": "assets/flag-tab-BNwbLfrN.b755a99fff7e.css", "assets/main-Cavvqkyp.js": "assets/main-Cavvqkyp.a9c4df906406.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/flag-tab-Ci_XcDT0.js": "assets/flag-tab-Ci_XcDT0.a5ea640a08d6.js", "assets/admin-drawer-panel-C34Ze3-5.js": "assets/admin-drawer-panel-C34Ze3-5.113c50cdf2cc.js", "assets/filter-frSNsexx.js": "assets/filter-frSNsexx.eab1570bd32d.js", "assets/relation-chips-CAC5ytqH.js": "assets/relation-chips-CAC5ytqH.f205d920ffea.js", "assets/VSlideGroup-BQtz8h9p.js": "assets/VSlideGroup-BQtz8h9p.ff97dbf209e1.js", "assets/admin-BpGFsvOH.js": "assets/admin-BpGFsvOH.d7193c78d0dd.js", "assets/VTable-C0gAriFq.js": "assets/VTable-C0gAriFq.fa6e4b60d4ef.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/http-error-B3fQGxpt.js": "assets/http-error-B3fQGxpt.9efc29496e30.js", "assets/library-tab-V8DUGoHN.js": "assets/library-tab-V8DUGoHN.809c548ff347.js", "assets/change-password-dialog-HvIvmmIE.css": "assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css", "assets/VCheckboxBtn-m4IbdjEe.js": "assets/VCheckboxBtn-m4IbdjEe.f0c4a814ded8.js", "assets/browser-CRPvEdqv.js": "assets/browser-CRPvEdqv.f355a71f4380.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/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/datetime-column-Dg_RxTVM.css": "assets/datetime-column-Dg_RxTVM.1fa7c5cbead7.css", "assets/reader-C39uGGxn.js": "assets/reader-C39uGGxn.67b0f324cd5e.js", "assets/VCheckbox-BS5fdM4M.js": "assets/VCheckbox-BS5fdM4M.a5d446e4aeb3.js", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/pagination-toolbar-Dg9tH1Ju.js": "assets/pagination-toolbar-Dg9tH1Ju.b2eb1e0c6985.js", "assets/to-case-kUm8NPpW.js": "assets/to-case-kUm8NPpW.5b3369f511b8.js", "assets/stats-tab-TsyG3wH_.css": "assets/stats-tab-TsyG3wH_.b93c080356fc.css", "assets/VCombobox-jg7SI5mn.js": "assets/VCombobox-jg7SI5mn.af66f18b4c54.js", "assets/group-tab-CBKuS3Iv.css": "assets/group-tab-CBKuS3Iv.7e4746634782.css", "assets/VTextField-Da_Hs7ls.js": "assets/VTextField-Da_Hs7ls.c295f24c251e.js", "assets/main-sK7HC5h4.css": "assets/main-sK7HC5h4.6f04ddfc5f1a.css", "assets/pdf-doc-4PKLN-Z3.js": "assets/pdf-doc-4PKLN-Z3.62d8de4d1fd8.js", "assets/stats-tab-C6qAnV6-.js": "assets/stats-tab-C6qAnV6-.f08c46b5f141.js", "assets/VRadioGroup-DULWiMSI.js": "assets/VRadioGroup-DULWiMSI.4ae535e01d2b.js", "assets/admin-B8Bp2Uih.css": "assets/admin-B8Bp2Uih.82c98714bcf1.css", "assets/pagination-toolbar-ClZui9Zf.css": "assets/pagination-toolbar-ClZui9Zf.697d7ae11c21.css", "assets/settings-drawer-nZ9HvKSZ.css": "assets/settings-drawer-nZ9HvKSZ.01744e131806.css", "assets/admin-drawer-panel-BHdNPwzF.css": "assets/admin-drawer-panel-BHdNPwzF.bd2c1d6148bb.css", "assets/VSelect-MGVSeLgr.css": "assets/VSelect-MGVSeLgr.7cabd30bc5e4.css", "assets/browser-Zqc9cR6T.css": "assets/browser-Zqc9cR6T.b7d6ddeff130.css", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/http-error-DKulXuTl.css": "assets/http-error-DKulXuTl.95e42988d5d5.css", "assets/reader-N2Ei_y2K.css": "assets/reader-N2Ei_y2K.8c0cdc0d513f.css", "assets/change-password-dialog-JYM9aAR9.js": "assets/change-password-dialog-JYM9aAR9.f71d378f4fa6.js", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/VTextField-BssVoDhB.css": "assets/VTextField-BssVoDhB.4cc388b4aa3c.css", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.ad9da9714e46.json"}, "version": "1.1", "hash": "8e018bd6e7e4"}
|
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
|
@@ -104,7 +104,7 @@ class BrowserBaseView(
|
|
|
104
104
|
add_acl = not (cover and self.model == Folder) # type: ignore
|
|
105
105
|
object_filter = self.get_group_acl_filter(model) if add_acl else Q()
|
|
106
106
|
object_filter &= self.get_bookmark_filter(model)
|
|
107
|
-
object_filter &= self.get_comic_field_filter(
|
|
107
|
+
object_filter &= self.get_comic_field_filter(model)
|
|
108
108
|
return object_filter
|
|
109
109
|
|
|
110
110
|
def get_query_filters(self, model, choices=False):
|
|
@@ -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
|
@@ -24,7 +24,6 @@ from codex.models import (
|
|
|
24
24
|
Publisher,
|
|
25
25
|
Series,
|
|
26
26
|
StoryArc,
|
|
27
|
-
Timestamp,
|
|
28
27
|
Volume,
|
|
29
28
|
)
|
|
30
29
|
from codex.serializers.browser.page import BrowserPageSerializer
|
|
@@ -50,7 +49,6 @@ class BrowserView(BrowserBreadcrumbsView):
|
|
|
50
49
|
{
|
|
51
50
|
AdminFlag.FlagChoices.FOLDER_VIEW.value: "folder_view",
|
|
52
51
|
AdminFlag.FlagChoices.IMPORT_METADATA.value: "import_metadata",
|
|
53
|
-
AdminFlag.FlagChoices.DYNAMIC_GROUP_COVERS.value: "dynamic_group_covers",
|
|
54
52
|
}
|
|
55
53
|
)
|
|
56
54
|
|
|
@@ -370,12 +368,7 @@ class BrowserView(BrowserBreadcrumbsView):
|
|
|
370
368
|
title = self._get_browser_page_title()
|
|
371
369
|
# needs to happen after pagination
|
|
372
370
|
# runs obj list query twice :/
|
|
373
|
-
libraries_exist = Library.objects.exists()
|
|
374
|
-
covers_timestamp = int(
|
|
375
|
-
Timestamp.objects.get(
|
|
376
|
-
key=Timestamp.TimestampChoices.COVERS.value
|
|
377
|
-
).updated_at.timestamp()
|
|
378
|
-
)
|
|
371
|
+
libraries_exist = Library.objects.filter(covers_only=False).exists()
|
|
379
372
|
|
|
380
373
|
# construct final data structure
|
|
381
374
|
return MappingProxyType(
|
|
@@ -390,7 +383,6 @@ class BrowserView(BrowserBreadcrumbsView):
|
|
|
390
383
|
"total_count": total_count,
|
|
391
384
|
"admin_flags": self.admin_flags,
|
|
392
385
|
"libraries_exist": libraries_exist,
|
|
393
|
-
"covers_timestamp": covers_timestamp,
|
|
394
386
|
}
|
|
395
387
|
)
|
|
396
388
|
|
|
@@ -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,
|
|
@@ -204,14 +224,39 @@ class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
|
|
|
204
224
|
"""Annotate the query set for the coverpath for the sort."""
|
|
205
225
|
# Select comics for the children by an outer ref for annotation
|
|
206
226
|
# Order the descendant comics by the sort argumentst
|
|
227
|
+
cover_style = self.params.get("cover_style")
|
|
207
228
|
if model == Comic:
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
elif
|
|
229
|
+
default_cover_pk = F("pk")
|
|
230
|
+
default_cover_mtime = F("updated_at")
|
|
231
|
+
elif cover_style == "i":
|
|
232
|
+
default_cover_pk = None
|
|
233
|
+
default_cover_mtime = None
|
|
234
|
+
else:
|
|
211
235
|
# At this point it's only been filtered.
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
236
|
+
default_cover_pk = F(self.rel_prefix + "pk")
|
|
237
|
+
default_cover_mtime = F(self.rel_prefix + "updated_at")
|
|
238
|
+
|
|
239
|
+
if model in (Volume, Comic):
|
|
240
|
+
cover_custom = Value(False)
|
|
241
|
+
cover_pk = default_cover_pk
|
|
242
|
+
cover_mtime = default_cover_mtime
|
|
243
|
+
else:
|
|
244
|
+
cover_custom = F("custom_cover")
|
|
245
|
+
cover_pk = Case(
|
|
246
|
+
When(custom_cover__isnull=False, then=F("custom_cover__pk")),
|
|
247
|
+
default=default_cover_pk,
|
|
248
|
+
)
|
|
249
|
+
cover_mtime = Case(
|
|
250
|
+
When(custom_cover__isnull=False, then=F("custom_cover__updated_at")),
|
|
251
|
+
default=default_cover_mtime,
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
return qs.annotate(
|
|
255
|
+
cover_custom=cover_custom,
|
|
256
|
+
cover_pk=cover_pk,
|
|
257
|
+
cover_mtime=cover_mtime,
|
|
258
|
+
cover_pks=JsonGroupArray("cover_pk", distinct=True),
|
|
259
|
+
)
|
|
215
260
|
|
|
216
261
|
def _annotate_group(self, qs, model):
|
|
217
262
|
"""Annotate Group."""
|
|
@@ -316,14 +361,44 @@ class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
|
|
|
316
361
|
"""Annotations only for metadata."""
|
|
317
362
|
return qs.annotate(mtime=Max("updated_at"))
|
|
318
363
|
|
|
319
|
-
def _get_cover_pk_query(self, cover_pks):
|
|
364
|
+
def _get_cover_pk_query(self, cover_pks, group_ids):
|
|
320
365
|
"""Get Cover Pk queryset for comic queryset."""
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
366
|
+
cover_style = self.params.get("cover_style")
|
|
367
|
+
if cover_style == "d":
|
|
368
|
+
# DYNAMIC COVERS
|
|
369
|
+
comic_qs = Comic.objects.filter(pk__in=cover_pks)
|
|
370
|
+
comic_qs = self.annotate_search_score(
|
|
371
|
+
comic_qs, Comic, self.cover_search_score_pairs
|
|
372
|
+
)
|
|
373
|
+
comic_qs = self.annotate_order_aggregates(comic_qs, Comic)
|
|
374
|
+
comic_qs = self.add_order_by(comic_qs, Comic) # type: ignore
|
|
375
|
+
else: # "f"
|
|
376
|
+
# FIRST COVERS
|
|
377
|
+
# The only filter at all is the model relation.
|
|
378
|
+
group_rel = _REL_MAP[self.model] # type: ignore
|
|
379
|
+
comic_qs = Comic.objects.filter(**{f"{group_rel}__in": group_ids})
|
|
380
|
+
|
|
381
|
+
# Order generated irrespective of browser filters and order
|
|
382
|
+
if self.kwargs["group"] == "f":
|
|
383
|
+
order_key = "filename"
|
|
384
|
+
elif self.kwargs["group"] == "a":
|
|
385
|
+
order_key = "story_arc_number"
|
|
386
|
+
else:
|
|
387
|
+
order_key = "sort_name"
|
|
388
|
+
|
|
389
|
+
model_group = self.model_group # type: ignore
|
|
390
|
+
show = MappingProxyType(self.params["show"]) # type: ignore
|
|
391
|
+
model_group = self.kwargs["group"]
|
|
392
|
+
comic_qs, comic_sort_names = self.alias_sort_names(
|
|
393
|
+
comic_qs, Comic, cover_pks, model_group, show
|
|
394
|
+
)
|
|
395
|
+
comic_qs = self.add_order_by(
|
|
396
|
+
comic_qs,
|
|
397
|
+
Comic,
|
|
398
|
+
order_key=order_key,
|
|
399
|
+
do_reverse=False,
|
|
400
|
+
comic_sort_names=comic_sort_names,
|
|
401
|
+
)
|
|
327
402
|
comic_qs = comic_qs.group_by("id")
|
|
328
403
|
return comic_qs.only("pk", "updated_at")
|
|
329
404
|
|
|
@@ -331,22 +406,28 @@ class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
|
|
|
331
406
|
"""Python hack to re-cover groups collapsed with group_by."""
|
|
332
407
|
# This would be better in the main query but OuterRef can't access annotations.
|
|
333
408
|
# So cover_pks aggregates all covers from multi groups like ids does.
|
|
334
|
-
if self.is_model_comic or
|
|
409
|
+
if self.is_model_comic or self.params.get("cover_style") == "i":
|
|
335
410
|
return group_qs
|
|
411
|
+
|
|
336
412
|
recovered_group_list = []
|
|
337
413
|
for group in group_qs:
|
|
338
414
|
cover_pks = group.cover_pks
|
|
339
415
|
if len(cover_pks) == 1:
|
|
340
416
|
cover_pk = cover_pks[0]
|
|
341
|
-
|
|
417
|
+
cover_mtime = group.updated_at
|
|
342
418
|
else:
|
|
343
|
-
comic_qs = self._get_cover_pk_query(cover_pks)
|
|
419
|
+
comic_qs = self._get_cover_pk_query(cover_pks, group.ids)
|
|
344
420
|
# print(comic_qs.explain())
|
|
345
421
|
# print(comic_qs.query)
|
|
346
422
|
cover = comic_qs[0]
|
|
347
423
|
cover_pk = cover.pk
|
|
348
|
-
|
|
424
|
+
if len(group.ids) == 1:
|
|
425
|
+
cover_mtime = group.updated_at
|
|
426
|
+
else:
|
|
427
|
+
cover_mtime = group.__class__.objects.filter(
|
|
428
|
+
pk__in=group.ids
|
|
429
|
+
).aggregate(updated_at=Max("updated_at"))["updated_at"]
|
|
430
|
+
group.cover_mtime = cover_mtime
|
|
349
431
|
group.cover_pk = cover_pk
|
|
350
|
-
group.cover_mtime = cover_updated_at
|
|
351
432
|
recovered_group_list.append(group)
|
|
352
433
|
return recovered_group_list
|
|
@@ -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:
|
|
@@ -4,6 +4,7 @@ from types import MappingProxyType
|
|
|
4
4
|
|
|
5
5
|
from django.db.models import Q
|
|
6
6
|
|
|
7
|
+
from codex.models.comic import Comic
|
|
7
8
|
from codex.views.session import BrowserSessionViewBase
|
|
8
9
|
|
|
9
10
|
_FILTER_REL_MAP = MappingProxyType(
|
|
@@ -36,9 +37,10 @@ class ComicFieldFilter(BrowserSessionViewBase):
|
|
|
36
37
|
filter_query |= Q(**{f"{rel}__in": filter_list})
|
|
37
38
|
return filter_query
|
|
38
39
|
|
|
39
|
-
def get_comic_field_filter(self,
|
|
40
|
+
def get_comic_field_filter(self, model):
|
|
40
41
|
"""Filter the comics based on the form filters."""
|
|
41
42
|
comic_field_filter = Q()
|
|
43
|
+
rel_prefix = "" if model == Comic else self.rel_prefix # type: ignore
|
|
42
44
|
for attribute in self.FILTER_ATTRIBUTES:
|
|
43
45
|
comic_field_filter &= self._filter_by_comic_field(attribute, rel_prefix)
|
|
44
46
|
return comic_field_filter
|
|
@@ -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
|
}
|