codex 1.6.3__py3-none-any.whl → 1.6.5__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/librarian/importer/importer.py +1 -1
- codex/librarian/janitor/cleanup.py +2 -4
- codex/librarian/janitor/update.py +10 -9
- codex/librarian/search/merge.py +37 -40
- codex/librarian/search/remove.py +30 -26
- codex/librarian/search/update.py +47 -38
- codex/librarian/stats.py +177 -0
- codex/librarian/watchdog/events.py +2 -2
- codex/serializers/admin/stats.py +77 -65
- codex/serializers/fields.py +23 -0
- codex/settings/settings.py +3 -3
- codex/static_root/assets/{VCheckbox-CXQlndFT.c17c006a62e6.js → VCheckbox-OPrrn8D4.95d8259619aa.js} +1 -1
- codex/static_root/assets/VCheckbox-OPrrn8D4.95d8259619aa.js.br +0 -0
- codex/static_root/assets/VCheckbox-OPrrn8D4.95d8259619aa.js.gz +0 -0
- codex/static_root/assets/{VCheckbox-CXQlndFT.js → VCheckbox-OPrrn8D4.js} +1 -1
- codex/static_root/assets/VCheckbox-OPrrn8D4.js.br +0 -0
- codex/static_root/assets/VCheckbox-OPrrn8D4.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-DB72Bclg.ab414c6ae2b8.js → VCheckboxBtn-BLEc6BrH.e8ae3d2738e2.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-BLEc6BrH.e8ae3d2738e2.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-BLEc6BrH.e8ae3d2738e2.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-DB72Bclg.js → VCheckboxBtn-BLEc6BrH.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-BLEc6BrH.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-BLEc6BrH.js.gz +0 -0
- codex/static_root/assets/{VCombobox-BDcFPzYf.0b80447cd638.js → VCombobox-C18LIWGs.2a41fab61075.js} +1 -1
- codex/static_root/assets/VCombobox-C18LIWGs.2a41fab61075.js.br +0 -0
- codex/static_root/assets/VCombobox-C18LIWGs.2a41fab61075.js.gz +0 -0
- codex/static_root/assets/{VCombobox-BDcFPzYf.js → VCombobox-C18LIWGs.js} +1 -1
- codex/static_root/assets/VCombobox-C18LIWGs.js.br +0 -0
- codex/static_root/assets/VCombobox-C18LIWGs.js.gz +0 -0
- codex/static_root/assets/{VDialog-BB4zqrGw.2decc14ea597.js → VDialog-DPlcZ188.9398019bd69c.js} +1 -1
- codex/static_root/assets/VDialog-DPlcZ188.9398019bd69c.js.br +0 -0
- codex/static_root/assets/VDialog-DPlcZ188.9398019bd69c.js.gz +0 -0
- codex/static_root/assets/{VDialog-BB4zqrGw.js → VDialog-DPlcZ188.js} +1 -1
- codex/static_root/assets/VDialog-DPlcZ188.js.br +0 -0
- codex/static_root/assets/VDialog-DPlcZ188.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-SZc735F5.19004a0eba16.js → VExpansionPanels-BrAdxiR-.f5e7507958b2.js} +1 -1
- codex/static_root/assets/VExpansionPanels-BrAdxiR-.f5e7507958b2.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-BrAdxiR-.f5e7507958b2.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-SZc735F5.js → VExpansionPanels-BrAdxiR-.js} +1 -1
- codex/static_root/assets/VExpansionPanels-BrAdxiR-.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-BrAdxiR-.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-tFEuhFRq.774e14a4945a.js → VRadioGroup-BWf1qZO1.ee8a1b8d589d.js} +1 -1
- codex/static_root/assets/VRadioGroup-BWf1qZO1.ee8a1b8d589d.js.br +0 -0
- codex/static_root/assets/VRadioGroup-BWf1qZO1.ee8a1b8d589d.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-tFEuhFRq.js → VRadioGroup-BWf1qZO1.js} +1 -1
- codex/static_root/assets/VRadioGroup-BWf1qZO1.js.br +0 -0
- codex/static_root/assets/VRadioGroup-BWf1qZO1.js.gz +0 -0
- codex/static_root/assets/{VSelect-Dd5Zy8Uy.f225abf824ff.js → VSelect-BEOlJiRW.2d4996f0d6a3.js} +1 -1
- codex/static_root/assets/VSelect-BEOlJiRW.2d4996f0d6a3.js.br +0 -0
- codex/static_root/assets/VSelect-BEOlJiRW.2d4996f0d6a3.js.gz +0 -0
- codex/static_root/assets/{VSelect-Dd5Zy8Uy.js → VSelect-BEOlJiRW.js} +1 -1
- codex/static_root/assets/VSelect-BEOlJiRW.js.br +0 -0
- codex/static_root/assets/VSelect-BEOlJiRW.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-DImIQPJV.1f14d2113063.js → VSelectionControl-BpvvZpBd.d83b413a38d1.js} +1 -1
- codex/static_root/assets/VSelectionControl-BpvvZpBd.d83b413a38d1.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BpvvZpBd.d83b413a38d1.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-DImIQPJV.js → VSelectionControl-BpvvZpBd.js} +1 -1
- codex/static_root/assets/VSelectionControl-BpvvZpBd.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BpvvZpBd.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-CDaAHRAK.783800d70a8a.js → VSlideGroup-Bv0lRnhB.e0b8f680bcbf.js} +1 -1
- codex/static_root/assets/VSlideGroup-Bv0lRnhB.e0b8f680bcbf.js.br +0 -0
- codex/static_root/assets/VSlideGroup-Bv0lRnhB.e0b8f680bcbf.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-CDaAHRAK.js → VSlideGroup-Bv0lRnhB.js} +1 -1
- codex/static_root/assets/VSlideGroup-Bv0lRnhB.js.br +0 -0
- codex/static_root/assets/VSlideGroup-Bv0lRnhB.js.gz +0 -0
- codex/static_root/assets/{VTable-CkCZonsu.81e34381271f.js → VTable-Dw1ASmYk.4e3817348a64.js} +1 -1
- codex/static_root/assets/VTable-Dw1ASmYk.4e3817348a64.js.br +0 -0
- codex/static_root/assets/VTable-Dw1ASmYk.4e3817348a64.js.gz +0 -0
- codex/static_root/assets/{VTable-CkCZonsu.js → VTable-Dw1ASmYk.js} +1 -1
- codex/static_root/assets/VTable-Dw1ASmYk.js.br +0 -0
- codex/static_root/assets/VTable-Dw1ASmYk.js.gz +0 -0
- codex/static_root/assets/{VTextField-fNAzFu1M.00dec8623f18.js → VTextField-DhIkxARQ.e688815dc516.js} +1 -1
- codex/static_root/assets/VTextField-DhIkxARQ.e688815dc516.js.br +0 -0
- codex/static_root/assets/VTextField-DhIkxARQ.e688815dc516.js.gz +0 -0
- codex/static_root/assets/{VTextField-fNAzFu1M.js → VTextField-DhIkxARQ.js} +1 -1
- codex/static_root/assets/VTextField-DhIkxARQ.js.br +0 -0
- codex/static_root/assets/VTextField-DhIkxARQ.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-_YBMW1SU.0836924f8c12.js → VWindowItem-IDCZgODl.8c4527097642.js} +1 -1
- codex/static_root/assets/VWindowItem-IDCZgODl.8c4527097642.js.br +0 -0
- codex/static_root/assets/VWindowItem-IDCZgODl.8c4527097642.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-_YBMW1SU.js → VWindowItem-IDCZgODl.js} +1 -1
- codex/static_root/assets/VWindowItem-IDCZgODl.js.br +0 -0
- codex/static_root/assets/VWindowItem-IDCZgODl.js.gz +0 -0
- codex/static_root/assets/{admin-DYmGyJVg.262e6032ee86.js → admin-DQMEj7xy.f249ade8981c.js} +1 -1
- codex/static_root/assets/admin-DQMEj7xy.f249ade8981c.js.br +0 -0
- codex/static_root/assets/admin-DQMEj7xy.f249ade8981c.js.gz +0 -0
- codex/static_root/assets/{admin-DYmGyJVg.js → admin-DQMEj7xy.js} +1 -1
- codex/static_root/assets/admin-DQMEj7xy.js.br +0 -0
- codex/static_root/assets/admin-DQMEj7xy.js.gz +0 -0
- codex/static_root/assets/{admin-drawer-panel-c3f3H29x.fa2b12c75b06.js → admin-drawer-panel-Can9sQIk.7021726ce8b9.js} +20 -20
- codex/static_root/assets/admin-drawer-panel-Can9sQIk.7021726ce8b9.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-Can9sQIk.7021726ce8b9.js.gz +0 -0
- codex/static_root/assets/{admin-drawer-panel-c3f3H29x.js → admin-drawer-panel-Can9sQIk.js} +20 -20
- codex/static_root/assets/admin-drawer-panel-Can9sQIk.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-Can9sQIk.js.gz +0 -0
- codex/static_root/assets/{browser-Ck3zWCOk.d98c77747e6d.js → browser-BOPyA0wB.b69c491ad88e.js} +1 -1
- codex/static_root/assets/browser-BOPyA0wB.b69c491ad88e.js.br +0 -0
- codex/static_root/assets/browser-BOPyA0wB.b69c491ad88e.js.gz +0 -0
- codex/static_root/assets/{browser-Ck3zWCOk.js → browser-BOPyA0wB.js} +1 -1
- codex/static_root/assets/browser-BOPyA0wB.js.br +0 -0
- codex/static_root/assets/browser-BOPyA0wB.js.gz +0 -0
- codex/static_root/assets/{browser-DgawKPSA.c7cf59dc4b21.css → browser-Cy0OgQJC.css} +1 -1
- codex/static_root/assets/browser-Cy0OgQJC.css.br +0 -0
- codex/static_root/assets/browser-Cy0OgQJC.css.gz +0 -0
- codex/static_root/assets/{browser-DgawKPSA.css → browser-Cy0OgQJC.fabbd1aaffcf.css} +1 -1
- codex/static_root/assets/browser-Cy0OgQJC.fabbd1aaffcf.css.br +0 -0
- codex/static_root/assets/browser-Cy0OgQJC.fabbd1aaffcf.css.gz +0 -0
- codex/static_root/assets/{change-password-dialog-BbIO0YI5.2bb0a5dfb190.js → change-password-dialog-BKyyB0i6.81abe7a243de.js} +1 -1
- codex/static_root/assets/change-password-dialog-BKyyB0i6.81abe7a243de.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BKyyB0i6.81abe7a243de.js.gz +0 -0
- codex/static_root/assets/{change-password-dialog-BbIO0YI5.js → change-password-dialog-BKyyB0i6.js} +1 -1
- codex/static_root/assets/change-password-dialog-BKyyB0i6.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BKyyB0i6.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-BrzuoYAT.a0a1b6364708.js → confirm-dialog-CbDA0K1C.6fca78c3b9bf.js} +1 -1
- codex/static_root/assets/confirm-dialog-CbDA0K1C.6fca78c3b9bf.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CbDA0K1C.6fca78c3b9bf.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-BrzuoYAT.js → confirm-dialog-CbDA0K1C.js} +1 -1
- codex/static_root/assets/confirm-dialog-CbDA0K1C.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CbDA0K1C.js.gz +0 -0
- codex/static_root/assets/{datetime-column-D8-UeX_p.e33b1556805b.js → datetime-column-lzxYDDvK.055ffa7f271c.js} +1 -1
- codex/static_root/assets/datetime-column-lzxYDDvK.055ffa7f271c.js.br +0 -0
- codex/static_root/assets/datetime-column-lzxYDDvK.055ffa7f271c.js.gz +0 -0
- codex/static_root/assets/{datetime-column-D8-UeX_p.js → datetime-column-lzxYDDvK.js} +1 -1
- codex/static_root/assets/datetime-column-lzxYDDvK.js.br +0 -0
- codex/static_root/assets/datetime-column-lzxYDDvK.js.gz +0 -0
- codex/static_root/assets/{filter-XMAX5Nmg.c6ed87350f7d.js → filter-SD2wRta_.2db402d82ae5.js} +1 -1
- codex/static_root/assets/filter-SD2wRta_.2db402d82ae5.js.br +0 -0
- codex/static_root/assets/filter-SD2wRta_.2db402d82ae5.js.gz +0 -0
- codex/static_root/assets/{filter-XMAX5Nmg.js → filter-SD2wRta_.js} +1 -1
- codex/static_root/assets/filter-SD2wRta_.js.br +0 -0
- codex/static_root/assets/filter-SD2wRta_.js.gz +0 -0
- codex/static_root/assets/flag-tab-Caak9VvH.643528c944e7.js +1 -0
- codex/static_root/assets/flag-tab-Caak9VvH.643528c944e7.js.br +0 -0
- codex/static_root/assets/flag-tab-Caak9VvH.643528c944e7.js.gz +0 -0
- codex/static_root/assets/flag-tab-Caak9VvH.js +1 -0
- codex/static_root/assets/flag-tab-Caak9VvH.js.br +0 -0
- codex/static_root/assets/flag-tab-Caak9VvH.js.gz +0 -0
- codex/static_root/assets/flag-tab-DBqpLKi7.css +1 -0
- codex/static_root/assets/flag-tab-DBqpLKi7.css.br +0 -0
- codex/static_root/assets/flag-tab-DBqpLKi7.css.gz +0 -0
- codex/static_root/assets/flag-tab-DBqpLKi7.dcfef39f541e.css +1 -0
- codex/static_root/assets/flag-tab-DBqpLKi7.dcfef39f541e.css.br +0 -0
- codex/static_root/assets/flag-tab-DBqpLKi7.dcfef39f541e.css.gz +0 -0
- codex/static_root/assets/{group-tab-D9n5gZCA.634223001c44.js → group-tab-DI7cBTNB.8042c34ec394.js} +1 -1
- codex/static_root/assets/group-tab-DI7cBTNB.8042c34ec394.js.br +0 -0
- codex/static_root/assets/group-tab-DI7cBTNB.8042c34ec394.js.gz +0 -0
- codex/static_root/assets/{group-tab-D9n5gZCA.js → group-tab-DI7cBTNB.js} +1 -1
- codex/static_root/assets/group-tab-DI7cBTNB.js.br +0 -0
- codex/static_root/assets/group-tab-DI7cBTNB.js.gz +0 -0
- codex/static_root/assets/{http-error-C_EFLi0c.c7e906206b62.js → http-error-BpbtQXBu.5ac5d9dfb219.js} +1 -1
- codex/static_root/assets/http-error-BpbtQXBu.5ac5d9dfb219.js.br +0 -0
- codex/static_root/assets/http-error-BpbtQXBu.5ac5d9dfb219.js.gz +0 -0
- codex/static_root/assets/{http-error-C_EFLi0c.js → http-error-BpbtQXBu.js} +1 -1
- codex/static_root/assets/http-error-BpbtQXBu.js.br +0 -0
- codex/static_root/assets/http-error-BpbtQXBu.js.gz +0 -0
- codex/static_root/assets/{library-tab-fDxuhPBs.285b36d9cec0.js → library-tab-DFEha1Cd.e0c6cde24a27.js} +1 -1
- codex/static_root/assets/library-tab-DFEha1Cd.e0c6cde24a27.js.br +0 -0
- codex/static_root/assets/library-tab-DFEha1Cd.e0c6cde24a27.js.gz +0 -0
- codex/static_root/assets/{library-tab-fDxuhPBs.js → library-tab-DFEha1Cd.js} +1 -1
- codex/static_root/assets/library-tab-DFEha1Cd.js.br +0 -0
- codex/static_root/assets/library-tab-DFEha1Cd.js.gz +0 -0
- codex/static_root/assets/main-hKTXzzX1.6888db202b7a.js +6 -0
- codex/static_root/assets/main-hKTXzzX1.6888db202b7a.js.br +0 -0
- codex/static_root/assets/main-hKTXzzX1.6888db202b7a.js.gz +0 -0
- codex/static_root/assets/main-hKTXzzX1.js +6 -0
- codex/static_root/assets/main-hKTXzzX1.js.br +0 -0
- codex/static_root/assets/main-hKTXzzX1.js.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-BD6nzIKF.f3ca4874c203.js → pagination-toolbar-nUqE7Y6_.573598728e43.js} +1 -1
- codex/static_root/assets/pagination-toolbar-nUqE7Y6_.573598728e43.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-nUqE7Y6_.573598728e43.js.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-BD6nzIKF.js → pagination-toolbar-nUqE7Y6_.js} +1 -1
- codex/static_root/assets/pagination-toolbar-nUqE7Y6_.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-nUqE7Y6_.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-iF15lKRp.de9a9d394438.js → pdf-doc-LW8r9w5L.0fc8e96441a3.js} +1 -1
- codex/static_root/assets/pdf-doc-LW8r9w5L.0fc8e96441a3.js.br +0 -0
- codex/static_root/assets/pdf-doc-LW8r9w5L.0fc8e96441a3.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-iF15lKRp.js → pdf-doc-LW8r9w5L.js} +1 -1
- codex/static_root/assets/pdf-doc-LW8r9w5L.js.br +0 -0
- codex/static_root/assets/pdf-doc-LW8r9w5L.js.gz +0 -0
- codex/static_root/assets/{reader-5Ja_bAaT.2fe33a3891f6.js → reader-DfCdn4RV.e821068881fd.js} +2 -2
- codex/static_root/assets/reader-DfCdn4RV.e821068881fd.js.br +0 -0
- codex/static_root/assets/reader-DfCdn4RV.e821068881fd.js.gz +0 -0
- codex/static_root/assets/{reader-5Ja_bAaT.js → reader-DfCdn4RV.js} +2 -2
- codex/static_root/assets/reader-DfCdn4RV.js.br +0 -0
- codex/static_root/assets/reader-DfCdn4RV.js.gz +0 -0
- codex/static_root/assets/{relation-chips-CUWkvLNo.3d18d0c09d39.js → relation-chips-iwVvmmvT.9e8ef037d134.js} +1 -1
- codex/static_root/assets/relation-chips-iwVvmmvT.9e8ef037d134.js.br +0 -0
- codex/static_root/assets/relation-chips-iwVvmmvT.9e8ef037d134.js.gz +0 -0
- codex/static_root/assets/{relation-chips-CUWkvLNo.js → relation-chips-iwVvmmvT.js} +1 -1
- codex/static_root/assets/relation-chips-iwVvmmvT.js.br +0 -0
- codex/static_root/assets/relation-chips-iwVvmmvT.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-rn3JdMxA.js → settings-drawer-D_S8wFKC.d68db990933d.js} +2 -2
- codex/static_root/assets/settings-drawer-D_S8wFKC.d68db990933d.js.br +0 -0
- codex/static_root/assets/settings-drawer-D_S8wFKC.d68db990933d.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-rn3JdMxA.a9d7b45c2138.js → settings-drawer-D_S8wFKC.js} +2 -2
- codex/static_root/assets/settings-drawer-D_S8wFKC.js.br +0 -0
- codex/static_root/assets/settings-drawer-D_S8wFKC.js.gz +0 -0
- codex/static_root/assets/stats-tab-CI0u-X7Y.2d1b6a0d4139.css +1 -0
- codex/static_root/assets/stats-tab-CI0u-X7Y.2d1b6a0d4139.css.br +0 -0
- codex/static_root/assets/stats-tab-CI0u-X7Y.2d1b6a0d4139.css.gz +0 -0
- codex/static_root/assets/stats-tab-CI0u-X7Y.css +1 -0
- codex/static_root/assets/stats-tab-CI0u-X7Y.css.br +0 -0
- codex/static_root/assets/stats-tab-CI0u-X7Y.css.gz +0 -0
- codex/static_root/assets/stats-tab-DD5sxuw1.29a98d090716.js +1 -0
- codex/static_root/assets/stats-tab-DD5sxuw1.29a98d090716.js.br +0 -0
- codex/static_root/assets/stats-tab-DD5sxuw1.29a98d090716.js.gz +0 -0
- codex/static_root/assets/stats-tab-DD5sxuw1.js +1 -0
- codex/static_root/assets/stats-tab-DD5sxuw1.js.br +0 -0
- codex/static_root/assets/stats-tab-DD5sxuw1.js.gz +0 -0
- codex/static_root/assets/{task-tab-CbzDX0IR.7b43bdf9cf42.js → task-tab-DDrdraG5.ddc487971339.js} +1 -1
- codex/static_root/assets/task-tab-DDrdraG5.ddc487971339.js.br +0 -0
- codex/static_root/assets/task-tab-DDrdraG5.ddc487971339.js.gz +0 -0
- codex/static_root/assets/{task-tab-CbzDX0IR.js → task-tab-DDrdraG5.js} +1 -1
- codex/static_root/assets/task-tab-DDrdraG5.js.br +0 -0
- codex/static_root/assets/task-tab-DDrdraG5.js.gz +0 -0
- codex/static_root/assets/{unauthorized-CllrtnFV.2a18fab3dd41.js → unauthorized-BMsnj48f.512d881936ab.js} +1 -1
- codex/static_root/assets/unauthorized-BMsnj48f.512d881936ab.js.br +0 -0
- codex/static_root/assets/unauthorized-BMsnj48f.512d881936ab.js.gz +0 -0
- codex/static_root/assets/{unauthorized-CllrtnFV.js → unauthorized-BMsnj48f.js} +1 -1
- codex/static_root/assets/unauthorized-BMsnj48f.js.br +0 -0
- codex/static_root/assets/unauthorized-BMsnj48f.js.gz +0 -0
- codex/static_root/assets/{user-tab-FY1xALpi.05a88f51df4f.js → user-tab-DSq5ht4e.5b70e9642a13.js} +1 -1
- codex/static_root/assets/user-tab-DSq5ht4e.5b70e9642a13.js.br +0 -0
- codex/static_root/assets/user-tab-DSq5ht4e.5b70e9642a13.js.gz +0 -0
- codex/static_root/assets/{user-tab-FY1xALpi.js → user-tab-DSq5ht4e.js} +1 -1
- codex/static_root/assets/user-tab-DSq5ht4e.js.br +0 -0
- codex/static_root/assets/user-tab-DSq5ht4e.js.gz +0 -0
- codex/static_root/{manifest.166aa32817b1.json → manifest.342051b44ea0.json} +216 -216
- codex/static_root/manifest.342051b44ea0.json.br +0 -0
- codex/static_root/manifest.342051b44ea0.json.gz +0 -0
- codex/static_root/manifest.json +216 -216
- codex/static_root/manifest.json.br +0 -0
- codex/static_root/manifest.json.gz +0 -0
- codex/static_root/staticfiles.json +1 -1
- codex/urls/root.py +12 -2
- codex/views/admin/stats.py +38 -186
- codex/views/opds/v1/entry/entry.py +14 -18
- codex/views/opds/v1/feed.py +5 -1
- codex/views/opds/v1/links.py +1 -0
- codex/views/reader/arcs.py +5 -4
- {codex-1.6.3.dist-info → codex-1.6.5.dist-info}/METADATA +18 -7
- {codex-1.6.3.dist-info → codex-1.6.5.dist-info}/RECORD +245 -245
- codex/settings/logging.py +0 -20
- codex/static_root/assets/VCheckbox-CXQlndFT.c17c006a62e6.js.br +0 -0
- codex/static_root/assets/VCheckbox-CXQlndFT.c17c006a62e6.js.gz +0 -0
- codex/static_root/assets/VCheckbox-CXQlndFT.js.br +0 -0
- codex/static_root/assets/VCheckbox-CXQlndFT.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-DB72Bclg.ab414c6ae2b8.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-DB72Bclg.ab414c6ae2b8.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-DB72Bclg.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-DB72Bclg.js.gz +0 -0
- codex/static_root/assets/VCombobox-BDcFPzYf.0b80447cd638.js.br +0 -0
- codex/static_root/assets/VCombobox-BDcFPzYf.0b80447cd638.js.gz +0 -0
- codex/static_root/assets/VCombobox-BDcFPzYf.js.br +0 -0
- codex/static_root/assets/VCombobox-BDcFPzYf.js.gz +0 -0
- codex/static_root/assets/VDialog-BB4zqrGw.2decc14ea597.js.br +0 -0
- codex/static_root/assets/VDialog-BB4zqrGw.2decc14ea597.js.gz +0 -0
- codex/static_root/assets/VDialog-BB4zqrGw.js.br +0 -0
- codex/static_root/assets/VDialog-BB4zqrGw.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-SZc735F5.19004a0eba16.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-SZc735F5.19004a0eba16.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-SZc735F5.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-SZc735F5.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-tFEuhFRq.774e14a4945a.js.br +0 -0
- codex/static_root/assets/VRadioGroup-tFEuhFRq.774e14a4945a.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-tFEuhFRq.js.br +0 -0
- codex/static_root/assets/VRadioGroup-tFEuhFRq.js.gz +0 -0
- codex/static_root/assets/VSelect-Dd5Zy8Uy.f225abf824ff.js.br +0 -0
- codex/static_root/assets/VSelect-Dd5Zy8Uy.f225abf824ff.js.gz +0 -0
- codex/static_root/assets/VSelect-Dd5Zy8Uy.js.br +0 -0
- codex/static_root/assets/VSelect-Dd5Zy8Uy.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-DImIQPJV.1f14d2113063.js.br +0 -0
- codex/static_root/assets/VSelectionControl-DImIQPJV.1f14d2113063.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-DImIQPJV.js.br +0 -0
- codex/static_root/assets/VSelectionControl-DImIQPJV.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-CDaAHRAK.783800d70a8a.js.br +0 -0
- codex/static_root/assets/VSlideGroup-CDaAHRAK.783800d70a8a.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-CDaAHRAK.js.br +0 -0
- codex/static_root/assets/VSlideGroup-CDaAHRAK.js.gz +0 -0
- codex/static_root/assets/VTable-CkCZonsu.81e34381271f.js.br +0 -0
- codex/static_root/assets/VTable-CkCZonsu.81e34381271f.js.gz +0 -0
- codex/static_root/assets/VTable-CkCZonsu.js.br +0 -0
- codex/static_root/assets/VTable-CkCZonsu.js.gz +0 -0
- codex/static_root/assets/VTextField-fNAzFu1M.00dec8623f18.js.br +0 -0
- codex/static_root/assets/VTextField-fNAzFu1M.00dec8623f18.js.gz +0 -0
- codex/static_root/assets/VTextField-fNAzFu1M.js.br +0 -0
- codex/static_root/assets/VTextField-fNAzFu1M.js.gz +0 -0
- codex/static_root/assets/VWindowItem-_YBMW1SU.0836924f8c12.js.br +0 -0
- codex/static_root/assets/VWindowItem-_YBMW1SU.0836924f8c12.js.gz +0 -0
- codex/static_root/assets/VWindowItem-_YBMW1SU.js.br +0 -0
- codex/static_root/assets/VWindowItem-_YBMW1SU.js.gz +0 -0
- codex/static_root/assets/admin-DYmGyJVg.262e6032ee86.js.br +0 -0
- codex/static_root/assets/admin-DYmGyJVg.262e6032ee86.js.gz +0 -0
- codex/static_root/assets/admin-DYmGyJVg.js.br +0 -0
- codex/static_root/assets/admin-DYmGyJVg.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-c3f3H29x.fa2b12c75b06.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-c3f3H29x.fa2b12c75b06.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-c3f3H29x.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-c3f3H29x.js.gz +0 -0
- codex/static_root/assets/browser-Ck3zWCOk.d98c77747e6d.js.br +0 -0
- codex/static_root/assets/browser-Ck3zWCOk.d98c77747e6d.js.gz +0 -0
- codex/static_root/assets/browser-Ck3zWCOk.js.br +0 -0
- codex/static_root/assets/browser-Ck3zWCOk.js.gz +0 -0
- codex/static_root/assets/browser-DgawKPSA.c7cf59dc4b21.css.br +0 -0
- codex/static_root/assets/browser-DgawKPSA.c7cf59dc4b21.css.gz +0 -0
- codex/static_root/assets/browser-DgawKPSA.css.br +0 -0
- codex/static_root/assets/browser-DgawKPSA.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-BbIO0YI5.2bb0a5dfb190.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BbIO0YI5.2bb0a5dfb190.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-BbIO0YI5.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BbIO0YI5.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-BrzuoYAT.a0a1b6364708.js.br +0 -0
- codex/static_root/assets/confirm-dialog-BrzuoYAT.a0a1b6364708.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-BrzuoYAT.js.br +0 -0
- codex/static_root/assets/confirm-dialog-BrzuoYAT.js.gz +0 -0
- codex/static_root/assets/datetime-column-D8-UeX_p.e33b1556805b.js.br +0 -0
- codex/static_root/assets/datetime-column-D8-UeX_p.e33b1556805b.js.gz +0 -0
- codex/static_root/assets/datetime-column-D8-UeX_p.js.br +0 -0
- codex/static_root/assets/datetime-column-D8-UeX_p.js.gz +0 -0
- codex/static_root/assets/filter-XMAX5Nmg.c6ed87350f7d.js.br +0 -0
- codex/static_root/assets/filter-XMAX5Nmg.c6ed87350f7d.js.gz +0 -0
- codex/static_root/assets/filter-XMAX5Nmg.js.br +0 -0
- codex/static_root/assets/filter-XMAX5Nmg.js.gz +0 -0
- codex/static_root/assets/flag-tab-BLEUVMot.c14936c90346.js +0 -1
- codex/static_root/assets/flag-tab-BLEUVMot.c14936c90346.js.br +0 -0
- codex/static_root/assets/flag-tab-BLEUVMot.c14936c90346.js.gz +0 -0
- codex/static_root/assets/flag-tab-BLEUVMot.js +0 -1
- codex/static_root/assets/flag-tab-BLEUVMot.js.br +0 -0
- codex/static_root/assets/flag-tab-BLEUVMot.js.gz +0 -0
- codex/static_root/assets/flag-tab-BNwbLfrN.b755a99fff7e.css +0 -1
- 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 +0 -1
- 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/group-tab-D9n5gZCA.634223001c44.js.br +0 -0
- codex/static_root/assets/group-tab-D9n5gZCA.634223001c44.js.gz +0 -0
- codex/static_root/assets/group-tab-D9n5gZCA.js.br +0 -0
- codex/static_root/assets/group-tab-D9n5gZCA.js.gz +0 -0
- codex/static_root/assets/http-error-C_EFLi0c.c7e906206b62.js.br +0 -0
- codex/static_root/assets/http-error-C_EFLi0c.c7e906206b62.js.gz +0 -0
- codex/static_root/assets/http-error-C_EFLi0c.js.br +0 -0
- codex/static_root/assets/http-error-C_EFLi0c.js.gz +0 -0
- codex/static_root/assets/library-tab-fDxuhPBs.285b36d9cec0.js.br +0 -0
- codex/static_root/assets/library-tab-fDxuhPBs.285b36d9cec0.js.gz +0 -0
- codex/static_root/assets/library-tab-fDxuhPBs.js.br +0 -0
- codex/static_root/assets/library-tab-fDxuhPBs.js.gz +0 -0
- codex/static_root/assets/main-B3MfqYNN.30d1310fc082.js +0 -6
- codex/static_root/assets/main-B3MfqYNN.30d1310fc082.js.br +0 -0
- codex/static_root/assets/main-B3MfqYNN.30d1310fc082.js.gz +0 -0
- codex/static_root/assets/main-B3MfqYNN.js +0 -6
- codex/static_root/assets/main-B3MfqYNN.js.br +0 -0
- codex/static_root/assets/main-B3MfqYNN.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BD6nzIKF.f3ca4874c203.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-BD6nzIKF.f3ca4874c203.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BD6nzIKF.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-BD6nzIKF.js.gz +0 -0
- codex/static_root/assets/pdf-doc-iF15lKRp.de9a9d394438.js.br +0 -0
- codex/static_root/assets/pdf-doc-iF15lKRp.de9a9d394438.js.gz +0 -0
- codex/static_root/assets/pdf-doc-iF15lKRp.js.br +0 -0
- codex/static_root/assets/pdf-doc-iF15lKRp.js.gz +0 -0
- codex/static_root/assets/reader-5Ja_bAaT.2fe33a3891f6.js.br +0 -0
- codex/static_root/assets/reader-5Ja_bAaT.2fe33a3891f6.js.gz +0 -0
- codex/static_root/assets/reader-5Ja_bAaT.js.br +0 -0
- codex/static_root/assets/reader-5Ja_bAaT.js.gz +0 -0
- codex/static_root/assets/relation-chips-CUWkvLNo.3d18d0c09d39.js.br +0 -0
- codex/static_root/assets/relation-chips-CUWkvLNo.3d18d0c09d39.js.gz +0 -0
- codex/static_root/assets/relation-chips-CUWkvLNo.js.br +0 -0
- codex/static_root/assets/relation-chips-CUWkvLNo.js.gz +0 -0
- codex/static_root/assets/settings-drawer-rn3JdMxA.a9d7b45c2138.js.br +0 -0
- codex/static_root/assets/settings-drawer-rn3JdMxA.a9d7b45c2138.js.gz +0 -0
- codex/static_root/assets/settings-drawer-rn3JdMxA.js.br +0 -0
- codex/static_root/assets/settings-drawer-rn3JdMxA.js.gz +0 -0
- codex/static_root/assets/stats-tab-B6L-YFRA.1c90593f7b5c.css +0 -1
- codex/static_root/assets/stats-tab-B6L-YFRA.1c90593f7b5c.css.br +0 -0
- codex/static_root/assets/stats-tab-B6L-YFRA.1c90593f7b5c.css.gz +0 -0
- codex/static_root/assets/stats-tab-B6L-YFRA.css +0 -1
- codex/static_root/assets/stats-tab-B6L-YFRA.css.br +0 -0
- codex/static_root/assets/stats-tab-B6L-YFRA.css.gz +0 -0
- codex/static_root/assets/stats-tab-zts2Xsmg.9fb959ccf4da.js +0 -1
- codex/static_root/assets/stats-tab-zts2Xsmg.9fb959ccf4da.js.br +0 -0
- codex/static_root/assets/stats-tab-zts2Xsmg.9fb959ccf4da.js.gz +0 -0
- codex/static_root/assets/stats-tab-zts2Xsmg.js +0 -1
- codex/static_root/assets/stats-tab-zts2Xsmg.js.br +0 -0
- codex/static_root/assets/stats-tab-zts2Xsmg.js.gz +0 -0
- codex/static_root/assets/task-tab-CbzDX0IR.7b43bdf9cf42.js.br +0 -0
- codex/static_root/assets/task-tab-CbzDX0IR.7b43bdf9cf42.js.gz +0 -0
- codex/static_root/assets/task-tab-CbzDX0IR.js.br +0 -0
- codex/static_root/assets/task-tab-CbzDX0IR.js.gz +0 -0
- codex/static_root/assets/unauthorized-CllrtnFV.2a18fab3dd41.js.br +0 -0
- codex/static_root/assets/unauthorized-CllrtnFV.2a18fab3dd41.js.gz +0 -0
- codex/static_root/assets/unauthorized-CllrtnFV.js.br +0 -0
- codex/static_root/assets/unauthorized-CllrtnFV.js.gz +0 -0
- codex/static_root/assets/user-tab-FY1xALpi.05a88f51df4f.js.br +0 -0
- codex/static_root/assets/user-tab-FY1xALpi.05a88f51df4f.js.gz +0 -0
- codex/static_root/assets/user-tab-FY1xALpi.js.br +0 -0
- codex/static_root/assets/user-tab-FY1xALpi.js.gz +0 -0
- codex/static_root/manifest.166aa32817b1.json.br +0 -0
- codex/static_root/manifest.166aa32817b1.json.gz +0 -0
- {codex-1.6.3.dist-info → codex-1.6.5.dist-info}/LICENSE +0 -0
- {codex-1.6.3.dist-info → codex-1.6.5.dist-info}/WHEEL +0 -0
- {codex-1.6.3.dist-info → codex-1.6.5.dist-info}/entry_points.txt +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"paths": {"rest_framework/docs/js/api.js": "rest_framework/docs/js/api.18a5ba8a1bd8.js", "rest_framework/docs/js/jquery.json-view.min.js": "rest_framework/docs/js/jquery.json-view.min.b7c2d6981377.js", "rest_framework/docs/js/highlight.pack.js": "rest_framework/docs/js/highlight.pack.479b5f21dcba.js", "rest_framework/docs/img/favicon.ico": "rest_framework/docs/img/favicon.5195b4d0f3eb.ico", "rest_framework/docs/img/grid.png": "rest_framework/docs/img/grid.a4b938cf382b.png", "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/js/ajax-form.js": "rest_framework/js/ajax-form.4e1cdcb7acab.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/prettify-min.js": "rest_framework/js/prettify-min.709bfcc456c6.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/default.js": "rest_framework/js/default.5b08897dbdc3.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "rest_framework/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/load-ajax-form.js": "rest_framework/js/load-ajax-form.8cdb3a9f3466.js", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "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/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "rest_framework/fonts/fontawesome-webfont.svg": "rest_framework/fonts/fontawesome-webfont.83e37a11f9d7.svg", "rest_framework/fonts/glyphicons-halflings-regular.woff": "rest_framework/fonts/glyphicons-halflings-regular.fa2772327f55.woff", "rest_framework/fonts/glyphicons-halflings-regular.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "rest_framework/img/glyphicons-halflings-white.png": "rest_framework/img/glyphicons-halflings-white.9bbc6e960299.png", "rest_framework/img/glyphicons-halflings.png": "rest_framework/img/glyphicons-halflings.90233c9067e9.png", "rest_framework/img/grid.png": "rest_framework/img/grid.a4b938cf382b.png", "rest_framework/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "rest_framework/css/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/bootstrap.min.css": "rest_framework/css/bootstrap.min.f17d4516b026.css", "rest_framework/css/prettify.css": "rest_framework/css/prettify.a987f72342ee.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/font-awesome-4.0.3.css": "rest_framework/css/font-awesome-4.0.3.c1e1ea213abf.css", "rest_framework/css/bootstrap-theme.min.css.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "img/publisher.svg": "img/publisher.82d378fcd601.svg", "img/logo-32.webp": "img/logo-32.5688944495bf.webp", "img/logo.svg": "img/logo.0f5344a028ca.svg", "img/story-arc.svg": "img/story-arc.ca10014355ef.svg", "img/missing-cover-165.webp": "img/missing-cover-165.0743171f2148.webp", "img/series.svg": "img/series.ec8a889b8f95.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.c58d966aa64e.webp", "img/missing-cover.svg": "img/missing-cover.ddb038cc2c56.svg", "img/folder.svg": "img/folder.f28936a3701d.svg", "img/volume.svg": "img/volume.814e4c79461a.svg", "img/logo-maskable.svg": "img/logo-maskable.8f7de7f1c6a8.svg", "img/imprint.svg": "img/imprint.7c2adebb76d6.svg", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "js/choices.json": "js/choices.2f6b0359e1ef.json", "js/choices-admin.json": "js/choices-admin.3521e2a863df.json", "assets/group-tab-CBKuS3Iv.css": "assets/group-tab-CBKuS3Iv.7e4746634782.css", "assets/http-error-DKulXuTl.css": "assets/http-error-DKulXuTl.95e42988d5d5.css", "assets/VSelect-ARDhJiQK.css": "assets/VSelect-ARDhJiQK.372c098fb475.css", "assets/flag-tab-BNwbLfrN.css": "assets/flag-tab-BNwbLfrN.b755a99fff7e.css", "assets/VTable-CkCZonsu.js": "assets/VTable-CkCZonsu.81e34381271f.js", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/filter-XMAX5Nmg.js": "assets/filter-XMAX5Nmg.c6ed87350f7d.js", "assets/VWindowItem-_YBMW1SU.js": "assets/VWindowItem-_YBMW1SU.0836924f8c12.js", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/settings-drawer-rn3JdMxA.js": "assets/settings-drawer-rn3JdMxA.a9d7b45c2138.js", "assets/library-tab-fDxuhPBs.js": "assets/library-tab-fDxuhPBs.285b36d9cec0.js", "assets/VTextField-fNAzFu1M.js": "assets/VTextField-fNAzFu1M.00dec8623f18.js", "assets/admin-drawer-panel-c3f3H29x.js": "assets/admin-drawer-panel-c3f3H29x.fa2b12c75b06.js", "assets/VSelectionControl-DImIQPJV.js": "assets/VSelectionControl-DImIQPJV.1f14d2113063.js", "assets/VRadioGroup-tFEuhFRq.js": "assets/VRadioGroup-tFEuhFRq.774e14a4945a.js", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/VSlideGroup-Dk_1upHt.css": "assets/VSlideGroup-Dk_1upHt.2c836070ec75.css", "assets/relation-chips-CUWkvLNo.js": "assets/relation-chips-CUWkvLNo.3d18d0c09d39.js", "assets/admin-drawer-panel-mne3FIj6.css": "assets/admin-drawer-panel-mne3FIj6.561b3f75fe65.css", "assets/VTable-DflzroDq.css": "assets/VTable-DflzroDq.160504d82195.css", "assets/settings-drawer-nZ9HvKSZ.css": "assets/settings-drawer-nZ9HvKSZ.01744e131806.css", "assets/VDialog-lQ13FnRR.css": "assets/VDialog-lQ13FnRR.1c801ad756b2.css", "assets/relation-chips-BGitp3yx.css": "assets/relation-chips-BGitp3yx.b3e7d178a615.css", "assets/VCombobox-BDcFPzYf.js": "assets/VCombobox-BDcFPzYf.0b80447cd638.js", "assets/main-Ztp855PW.css": "assets/main-Ztp855PW.d46d718fac45.css", "assets/change-password-dialog-BbIO0YI5.js": "assets/change-password-dialog-BbIO0YI5.2bb0a5dfb190.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/admin-D4sw3N4T.css": "assets/admin-D4sw3N4T.b590f88a62cf.css", "assets/unauthorized-CllrtnFV.js": "assets/unauthorized-CllrtnFV.2a18fab3dd41.js", "assets/reader-YbzUiD0T.css": "assets/reader-YbzUiD0T.efb15835b39d.css", "assets/change-password-dialog-0u6IJA87.css": "assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/main-B3MfqYNN.js": "assets/main-B3MfqYNN.30d1310fc082.js", "assets/pagination-toolbar-BD6nzIKF.js": "assets/pagination-toolbar-BD6nzIKF.f3ca4874c203.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/VDialog-BB4zqrGw.js": "assets/VDialog-BB4zqrGw.2decc14ea597.js", "assets/pagination-toolbar-BA9ifTed.css": "assets/pagination-toolbar-BA9ifTed.b4865334ee08.css", "assets/library-tab-BygwYPnO.css": "assets/library-tab-BygwYPnO.94e92aa60bf2.css", "assets/reader-5Ja_bAaT.js": "assets/reader-5Ja_bAaT.2fe33a3891f6.js", "assets/stats-tab-B6L-YFRA.css": "assets/stats-tab-B6L-YFRA.1c90593f7b5c.css", "assets/user-tab-FY1xALpi.js": "assets/user-tab-FY1xALpi.05a88f51df4f.js", "assets/stats-tab-zts2Xsmg.js": "assets/stats-tab-zts2Xsmg.9fb959ccf4da.js", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/datetime-column-D8-UeX_p.js": "assets/datetime-column-D8-UeX_p.e33b1556805b.js", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/confirm-dialog-BrzuoYAT.js": "assets/confirm-dialog-BrzuoYAT.a0a1b6364708.js", "assets/browser-DgawKPSA.css": "assets/browser-DgawKPSA.c7cf59dc4b21.css", "assets/VCheckbox-CXQlndFT.js": "assets/VCheckbox-CXQlndFT.c17c006a62e6.js", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/VExpansionPanels-SZc735F5.js": "assets/VExpansionPanels-SZc735F5.19004a0eba16.js", "assets/pdf-doc-iF15lKRp.js": "assets/pdf-doc-iF15lKRp.de9a9d394438.js", "assets/task-tab-CbzDX0IR.js": "assets/task-tab-CbzDX0IR.7b43bdf9cf42.js", "assets/datetime-column-DeCthByU.css": "assets/datetime-column-DeCthByU.1f3bf499e063.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/admin-DYmGyJVg.js": "assets/admin-DYmGyJVg.262e6032ee86.js", "assets/flag-tab-BLEUVMot.js": "assets/flag-tab-BLEUVMot.c14936c90346.js", "assets/unauthorized-DWDO1s6-.css": "assets/unauthorized-DWDO1s6-.d34daac27dcf.css", "assets/VSlideGroup-CDaAHRAK.js": "assets/VSlideGroup-CDaAHRAK.783800d70a8a.js", "assets/VSelect-Dd5Zy8Uy.js": "assets/VSelect-Dd5Zy8Uy.f225abf824ff.js", "assets/http-error-C_EFLi0c.js": "assets/http-error-C_EFLi0c.c7e906206b62.js", "assets/group-tab-D9n5gZCA.js": "assets/group-tab-D9n5gZCA.634223001c44.js", "assets/VExpansionPanels-DsEXVcCv.css": "assets/VExpansionPanels-DsEXVcCv.20b475255e66.css", "assets/VCheckboxBtn-DB72Bclg.js": "assets/VCheckboxBtn-DB72Bclg.ab414c6ae2b8.js", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/VTextField-BssVoDhB.css": "assets/VTextField-BssVoDhB.4cc388b4aa3c.css", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/browser-Ck3zWCOk.js": "assets/browser-Ck3zWCOk.d98c77747e6d.js", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.166aa32817b1.json"}, "version": "1.1", "hash": "704d3fcae5ee"}
|
|
1
|
+
{"paths": {"rest_framework/docs/js/api.js": "rest_framework/docs/js/api.18a5ba8a1bd8.js", "rest_framework/docs/js/jquery.json-view.min.js": "rest_framework/docs/js/jquery.json-view.min.b7c2d6981377.js", "rest_framework/docs/js/highlight.pack.js": "rest_framework/docs/js/highlight.pack.479b5f21dcba.js", "rest_framework/docs/img/favicon.ico": "rest_framework/docs/img/favicon.5195b4d0f3eb.ico", "rest_framework/docs/img/grid.png": "rest_framework/docs/img/grid.a4b938cf382b.png", "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/js/ajax-form.js": "rest_framework/js/ajax-form.4e1cdcb7acab.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/prettify-min.js": "rest_framework/js/prettify-min.709bfcc456c6.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/default.js": "rest_framework/js/default.5b08897dbdc3.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "rest_framework/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/load-ajax-form.js": "rest_framework/js/load-ajax-form.8cdb3a9f3466.js", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "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/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "rest_framework/fonts/fontawesome-webfont.svg": "rest_framework/fonts/fontawesome-webfont.83e37a11f9d7.svg", "rest_framework/fonts/glyphicons-halflings-regular.woff": "rest_framework/fonts/glyphicons-halflings-regular.fa2772327f55.woff", "rest_framework/fonts/glyphicons-halflings-regular.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "rest_framework/img/glyphicons-halflings-white.png": "rest_framework/img/glyphicons-halflings-white.9bbc6e960299.png", "rest_framework/img/glyphicons-halflings.png": "rest_framework/img/glyphicons-halflings.90233c9067e9.png", "rest_framework/img/grid.png": "rest_framework/img/grid.a4b938cf382b.png", "rest_framework/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "rest_framework/css/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/bootstrap.min.css": "rest_framework/css/bootstrap.min.f17d4516b026.css", "rest_framework/css/prettify.css": "rest_framework/css/prettify.a987f72342ee.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/font-awesome-4.0.3.css": "rest_framework/css/font-awesome-4.0.3.c1e1ea213abf.css", "rest_framework/css/bootstrap-theme.min.css.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "img/publisher.svg": "img/publisher.82d378fcd601.svg", "img/logo-32.webp": "img/logo-32.5688944495bf.webp", "img/logo.svg": "img/logo.0f5344a028ca.svg", "img/story-arc.svg": "img/story-arc.ca10014355ef.svg", "img/missing-cover-165.webp": "img/missing-cover-165.0743171f2148.webp", "img/series.svg": "img/series.ec8a889b8f95.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.c58d966aa64e.webp", "img/missing-cover.svg": "img/missing-cover.ddb038cc2c56.svg", "img/folder.svg": "img/folder.f28936a3701d.svg", "img/volume.svg": "img/volume.814e4c79461a.svg", "img/logo-maskable.svg": "img/logo-maskable.8f7de7f1c6a8.svg", "img/imprint.svg": "img/imprint.7c2adebb76d6.svg", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "js/choices.json": "js/choices.2f6b0359e1ef.json", "js/choices-admin.json": "js/choices-admin.3521e2a863df.json", "assets/group-tab-CBKuS3Iv.css": "assets/group-tab-CBKuS3Iv.7e4746634782.css", "assets/http-error-DKulXuTl.css": "assets/http-error-DKulXuTl.95e42988d5d5.css", "assets/VSelect-ARDhJiQK.css": "assets/VSelect-ARDhJiQK.372c098fb475.css", "assets/filter-SD2wRta_.js": "assets/filter-SD2wRta_.2db402d82ae5.js", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/settings-drawer-D_S8wFKC.js": "assets/settings-drawer-D_S8wFKC.d68db990933d.js", "assets/VCheckboxBtn-BLEc6BrH.js": "assets/VCheckboxBtn-BLEc6BrH.e8ae3d2738e2.js", "assets/VCombobox-C18LIWGs.js": "assets/VCombobox-C18LIWGs.2a41fab61075.js", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/VSlideGroup-Dk_1upHt.css": "assets/VSlideGroup-Dk_1upHt.2c836070ec75.css", "assets/admin-drawer-panel-mne3FIj6.css": "assets/admin-drawer-panel-mne3FIj6.561b3f75fe65.css", "assets/VTable-DflzroDq.css": "assets/VTable-DflzroDq.160504d82195.css", "assets/settings-drawer-nZ9HvKSZ.css": "assets/settings-drawer-nZ9HvKSZ.01744e131806.css", "assets/VDialog-lQ13FnRR.css": "assets/VDialog-lQ13FnRR.1c801ad756b2.css", "assets/VWindowItem-IDCZgODl.js": "assets/VWindowItem-IDCZgODl.8c4527097642.js", "assets/user-tab-DSq5ht4e.js": "assets/user-tab-DSq5ht4e.5b70e9642a13.js", "assets/relation-chips-BGitp3yx.css": "assets/relation-chips-BGitp3yx.b3e7d178a615.css", "assets/main-Ztp855PW.css": "assets/main-Ztp855PW.d46d718fac45.css", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/admin-drawer-panel-Can9sQIk.js": "assets/admin-drawer-panel-Can9sQIk.7021726ce8b9.js", "assets/VTextField-DhIkxARQ.js": "assets/VTextField-DhIkxARQ.e688815dc516.js", "assets/admin-D4sw3N4T.css": "assets/admin-D4sw3N4T.b590f88a62cf.css", "assets/stats-tab-DD5sxuw1.js": "assets/stats-tab-DD5sxuw1.29a98d090716.js", "assets/group-tab-DI7cBTNB.js": "assets/group-tab-DI7cBTNB.8042c34ec394.js", "assets/VSelectionControl-BpvvZpBd.js": "assets/VSelectionControl-BpvvZpBd.d83b413a38d1.js", "assets/flag-tab-Caak9VvH.js": "assets/flag-tab-Caak9VvH.643528c944e7.js", "assets/admin-DQMEj7xy.js": "assets/admin-DQMEj7xy.f249ade8981c.js", "assets/http-error-BpbtQXBu.js": "assets/http-error-BpbtQXBu.5ac5d9dfb219.js", "assets/datetime-column-lzxYDDvK.js": "assets/datetime-column-lzxYDDvK.055ffa7f271c.js", "assets/reader-YbzUiD0T.css": "assets/reader-YbzUiD0T.efb15835b39d.css", "assets/change-password-dialog-0u6IJA87.css": "assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css", "assets/unauthorized-BMsnj48f.js": "assets/unauthorized-BMsnj48f.512d881936ab.js", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/VTable-Dw1ASmYk.js": "assets/VTable-Dw1ASmYk.4e3817348a64.js", "assets/relation-chips-iwVvmmvT.js": "assets/relation-chips-iwVvmmvT.9e8ef037d134.js", "assets/pagination-toolbar-BA9ifTed.css": "assets/pagination-toolbar-BA9ifTed.b4865334ee08.css", "assets/library-tab-BygwYPnO.css": "assets/library-tab-BygwYPnO.94e92aa60bf2.css", "assets/reader-DfCdn4RV.js": "assets/reader-DfCdn4RV.e821068881fd.js", "assets/VCheckbox-OPrrn8D4.js": "assets/VCheckbox-OPrrn8D4.95d8259619aa.js", "assets/VSelect-BEOlJiRW.js": "assets/VSelect-BEOlJiRW.2d4996f0d6a3.js", "assets/confirm-dialog-CbDA0K1C.js": "assets/confirm-dialog-CbDA0K1C.6fca78c3b9bf.js", "assets/library-tab-DFEha1Cd.js": "assets/library-tab-DFEha1Cd.e0c6cde24a27.js", "assets/browser-Cy0OgQJC.css": "assets/browser-Cy0OgQJC.fabbd1aaffcf.css", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/flag-tab-DBqpLKi7.css": "assets/flag-tab-DBqpLKi7.dcfef39f541e.css", "assets/VExpansionPanels-BrAdxiR-.js": "assets/VExpansionPanels-BrAdxiR-.f5e7507958b2.js", "assets/main-hKTXzzX1.js": "assets/main-hKTXzzX1.6888db202b7a.js", "assets/pagination-toolbar-nUqE7Y6_.js": "assets/pagination-toolbar-nUqE7Y6_.573598728e43.js", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/task-tab-DDrdraG5.js": "assets/task-tab-DDrdraG5.ddc487971339.js", "assets/change-password-dialog-BKyyB0i6.js": "assets/change-password-dialog-BKyyB0i6.81abe7a243de.js", "assets/VSlideGroup-Bv0lRnhB.js": "assets/VSlideGroup-Bv0lRnhB.e0b8f680bcbf.js", "assets/datetime-column-DeCthByU.css": "assets/datetime-column-DeCthByU.1f3bf499e063.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/unauthorized-DWDO1s6-.css": "assets/unauthorized-DWDO1s6-.d34daac27dcf.css", "assets/VRadioGroup-BWf1qZO1.js": "assets/VRadioGroup-BWf1qZO1.ee8a1b8d589d.js", "assets/stats-tab-CI0u-X7Y.css": "assets/stats-tab-CI0u-X7Y.2d1b6a0d4139.css", "assets/VDialog-DPlcZ188.js": "assets/VDialog-DPlcZ188.9398019bd69c.js", "assets/pdf-doc-LW8r9w5L.js": "assets/pdf-doc-LW8r9w5L.0fc8e96441a3.js", "assets/VExpansionPanels-DsEXVcCv.css": "assets/VExpansionPanels-DsEXVcCv.20b475255e66.css", "assets/browser-BOPyA0wB.js": "assets/browser-BOPyA0wB.b69c491ad88e.js", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/VTextField-BssVoDhB.css": "assets/VTextField-BssVoDhB.4cc388b4aa3c.css", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.342051b44ea0.json"}, "version": "1.1", "hash": "83a705fd3113"}
|
codex/urls/root.py
CHANGED
|
@@ -7,7 +7,7 @@ from django.contrib.staticfiles.storage import staticfiles_storage
|
|
|
7
7
|
from django.urls import include, path, register_converter, set_script_prefix
|
|
8
8
|
from django.views.generic.base import RedirectView
|
|
9
9
|
|
|
10
|
-
from codex.settings.settings import ROOT_PATH
|
|
10
|
+
from codex.settings.settings import DEBUG, ROOT_PATH
|
|
11
11
|
from codex.urls.converters import GroupConverter, IntListConverter
|
|
12
12
|
|
|
13
13
|
register_converter(GroupConverter, "group")
|
|
@@ -17,7 +17,17 @@ if ROOT_PATH:
|
|
|
17
17
|
# Django 5 bug https://code.djangoproject.com/ticket/35169#comment:11
|
|
18
18
|
set_script_prefix(ROOT_PATH)
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
urlpatterns = []
|
|
22
|
+
if DEBUG:
|
|
23
|
+
# Pyright doesn't follow logic so will try to find these types.
|
|
24
|
+
from schema_graph.views import Schema # type: ignore
|
|
25
|
+
|
|
26
|
+
urlpatterns += [
|
|
27
|
+
path("schema/", Schema.as_view()), # type: ignore
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
urlpatterns += [
|
|
21
31
|
path(
|
|
22
32
|
"favicon.ico",
|
|
23
33
|
RedirectView.as_view(url=staticfiles_storage.url("img/logo-32.webp")),
|
codex/views/admin/stats.py
CHANGED
|
@@ -1,218 +1,70 @@
|
|
|
1
|
-
"""Admin
|
|
1
|
+
"""Admin Stats View."""
|
|
2
2
|
|
|
3
|
-
from multiprocessing import cpu_count
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from platform import machine, python_version, release, system
|
|
6
|
-
from types import MappingProxyType
|
|
7
3
|
from typing import ClassVar
|
|
8
4
|
|
|
9
|
-
from caseconverter import snakecase
|
|
10
|
-
from django.contrib.sessions.models import Session
|
|
11
|
-
from django.db.models import Count
|
|
12
5
|
from drf_spectacular.utils import extend_schema
|
|
13
6
|
from rest_framework.response import Response
|
|
7
|
+
from rest_framework.serializers import empty
|
|
14
8
|
|
|
9
|
+
from codex.librarian.stats import CodexStats
|
|
15
10
|
from codex.logger.logging import get_logger
|
|
16
|
-
from codex.models import
|
|
17
|
-
Comic,
|
|
18
|
-
Library,
|
|
19
|
-
Timestamp,
|
|
20
|
-
)
|
|
11
|
+
from codex.models.admin import Timestamp
|
|
21
12
|
from codex.permissions import HasAPIKeyOrIsAdminUser
|
|
22
13
|
from codex.serializers.admin.stats import (
|
|
23
14
|
AdminStatsRequestSerializer,
|
|
24
|
-
|
|
15
|
+
StatsSerializer,
|
|
25
16
|
)
|
|
26
|
-
from codex.version import VERSION
|
|
27
17
|
from codex.views.admin.auth import AdminGenericAPIView
|
|
28
|
-
from codex.views.const import CONFIG_MODELS, METADATA_MODELS, STATS_GROUP_MODELS
|
|
29
|
-
from codex.views.session import SessionView
|
|
30
18
|
|
|
31
19
|
LOG = get_logger(__name__)
|
|
32
|
-
_KEY_MODELS_MAP = MappingProxyType(
|
|
33
|
-
{
|
|
34
|
-
"config": CONFIG_MODELS,
|
|
35
|
-
"groups": STATS_GROUP_MODELS,
|
|
36
|
-
"metadata": METADATA_MODELS,
|
|
37
|
-
}
|
|
38
|
-
)
|
|
39
|
-
_DOCKERENV_PATH = Path("/.dockerenv")
|
|
40
|
-
_CGROUP_PATH = Path("/proc/self/cgroup")
|
|
41
|
-
_USER_STATS = MappingProxyType(
|
|
42
|
-
{
|
|
43
|
-
SessionView.BROWSER_SESSION_KEY: ("top_group", "order_by", "dynamic_covers"),
|
|
44
|
-
SessionView.READER_SESSION_KEY: (
|
|
45
|
-
"finish_on_last_page",
|
|
46
|
-
"fit_to",
|
|
47
|
-
"reading_direction",
|
|
48
|
-
),
|
|
49
|
-
}
|
|
50
|
-
)
|
|
51
20
|
|
|
52
21
|
|
|
53
22
|
class AdminStatsView(AdminGenericAPIView):
|
|
54
23
|
"""Admin Flag Viewset."""
|
|
55
24
|
|
|
56
25
|
permission_classes: ClassVar[list] = [HasAPIKeyOrIsAdminUser] # type: ignore
|
|
57
|
-
serializer_class =
|
|
26
|
+
serializer_class = StatsSerializer
|
|
58
27
|
input_serializer_class = AdminStatsRequestSerializer
|
|
59
28
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
""
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
models.append(model)
|
|
87
|
-
else:
|
|
88
|
-
models = all_models
|
|
89
|
-
return models
|
|
90
|
-
|
|
91
|
-
def _get_model_counts(self, key):
|
|
92
|
-
"""Get database counts of each model group."""
|
|
93
|
-
models = self._get_models(key)
|
|
94
|
-
obj = {}
|
|
95
|
-
for model in models:
|
|
96
|
-
vnp = model._meta.verbose_name_plural
|
|
97
|
-
if vnp:
|
|
98
|
-
title = vnp.title()
|
|
99
|
-
else:
|
|
100
|
-
LOG.warning(f"No verbose plural name for {model.__name__}")
|
|
101
|
-
title = model.__name__
|
|
102
|
-
|
|
103
|
-
vnp_name = snakecase(title)
|
|
104
|
-
vnp_name += "_count"
|
|
105
|
-
qs = model.objects
|
|
106
|
-
if model == Library:
|
|
107
|
-
qs = qs.filter(covers_only=False)
|
|
108
|
-
obj[vnp_name] = qs.count()
|
|
109
|
-
return obj
|
|
110
|
-
|
|
111
|
-
@staticmethod
|
|
112
|
-
def _aggregate_session_key(session, session_key, session_subkeys, user_stats):
|
|
113
|
-
session_dict = session.get(session_key, {})
|
|
114
|
-
for key in session_subkeys:
|
|
115
|
-
value = session_dict.get(key)
|
|
116
|
-
if value is None:
|
|
117
|
-
continue
|
|
118
|
-
if key not in user_stats:
|
|
119
|
-
user_stats[key] = {}
|
|
120
|
-
if value not in user_stats[key]:
|
|
121
|
-
user_stats[key][value] = 0
|
|
122
|
-
user_stats[key][value] += 1
|
|
123
|
-
|
|
124
|
-
@classmethod
|
|
125
|
-
def _get_session_stats(cls):
|
|
126
|
-
"""Return the number of anonymous sessions."""
|
|
127
|
-
sessions = Session.objects.all()
|
|
128
|
-
anon_session_count = 0
|
|
129
|
-
user_stats = {}
|
|
130
|
-
for encoded_session in sessions:
|
|
131
|
-
session = encoded_session.get_decoded()
|
|
132
|
-
if not session.get("_auth_user_id"):
|
|
133
|
-
anon_session_count += 1
|
|
134
|
-
for session_key, subkeys in _USER_STATS.items():
|
|
135
|
-
cls._aggregate_session_key(session, session_key, subkeys, user_stats)
|
|
136
|
-
|
|
137
|
-
return user_stats, anon_session_count
|
|
138
|
-
|
|
139
|
-
def _get_platform(self, obj):
|
|
140
|
-
"""Add dict of platform information to object."""
|
|
141
|
-
platform = {
|
|
142
|
-
"docker": self._is_docker(),
|
|
143
|
-
"machine": machine(),
|
|
144
|
-
"cores": cpu_count(),
|
|
145
|
-
"system": system(),
|
|
146
|
-
"system_release": release(),
|
|
147
|
-
"python": python_version(),
|
|
148
|
-
"codex": VERSION,
|
|
149
|
-
}
|
|
150
|
-
obj["platform"] = platform
|
|
151
|
-
|
|
152
|
-
def _get_config(self, obj):
|
|
153
|
-
"""Add dict of config informaation to object."""
|
|
154
|
-
config = self._get_model_counts("config")
|
|
155
|
-
request_counts = self._get_request_counts("config")
|
|
156
|
-
sessions, config["anonymous_users_count"] = self._get_session_stats()
|
|
157
|
-
if not request_counts or "apikey" in request_counts:
|
|
158
|
-
config["api_key"] = Timestamp.objects.get(
|
|
159
|
-
key=Timestamp.TimestampChoices.API_KEY.value
|
|
160
|
-
).version
|
|
161
|
-
config["registered_users_count"] = config.pop("users_count", 0)
|
|
162
|
-
config["user_groups_count"] = config.pop("groups_count", 0)
|
|
163
|
-
obj["config"] = config
|
|
164
|
-
obj["sessions"] = sessions
|
|
165
|
-
|
|
166
|
-
def _get_file_types(self):
|
|
167
|
-
"""Query for file types."""
|
|
168
|
-
file_types = {}
|
|
169
|
-
qs = (
|
|
170
|
-
Comic.objects.values("file_type")
|
|
171
|
-
.annotate(count=Count("file_type"))
|
|
172
|
-
.order_by()
|
|
173
|
-
)
|
|
174
|
-
for query_group in qs:
|
|
175
|
-
value = query_group["file_type"]
|
|
176
|
-
name = value.lower() if value else "unknown"
|
|
177
|
-
field = f"{name}_count"
|
|
178
|
-
file_types[field] = query_group["count"]
|
|
179
|
-
return file_types
|
|
180
|
-
|
|
181
|
-
def _get_groups(self, obj):
|
|
182
|
-
"""Add dict of groups information to object."""
|
|
183
|
-
if not self.params or "groups" in self.params:
|
|
184
|
-
groups = self._get_model_counts("groups")
|
|
185
|
-
obj["groups"] = groups
|
|
186
|
-
|
|
187
|
-
if not self.params or "fileTypes" in self.params:
|
|
188
|
-
file_types = self._get_file_types()
|
|
189
|
-
obj["file_types"] = file_types
|
|
190
|
-
|
|
191
|
-
def _get_metadata(self, obj):
|
|
192
|
-
"""Add dict of metadata counts to object."""
|
|
193
|
-
metadata = self._get_model_counts("metadata")
|
|
194
|
-
obj["metadata"] = metadata
|
|
29
|
+
def _parse_params(self):
|
|
30
|
+
"""Parse and input params."""
|
|
31
|
+
data = self.request.GET
|
|
32
|
+
|
|
33
|
+
input_serializer = self.input_serializer_class(data=data)
|
|
34
|
+
input_serializer.is_valid(raise_exception=True)
|
|
35
|
+
params = {}
|
|
36
|
+
if input_serializer.validated_data and not isinstance(
|
|
37
|
+
input_serializer.validated_data, empty
|
|
38
|
+
):
|
|
39
|
+
for key, value in input_serializer.validated_data.items():
|
|
40
|
+
if value:
|
|
41
|
+
params[key] = value
|
|
42
|
+
return params
|
|
43
|
+
|
|
44
|
+
def _add_api_key(self, obj):
|
|
45
|
+
"""Add the api key to the config object if specified."""
|
|
46
|
+
request_counts = self.params.get("config", {})
|
|
47
|
+
if request_counts and ("apikey" not in request_counts):
|
|
48
|
+
return
|
|
49
|
+
api_key = Timestamp.objects.get(
|
|
50
|
+
key=Timestamp.TimestampChoices.API_KEY.value
|
|
51
|
+
).version
|
|
52
|
+
if "config" not in obj:
|
|
53
|
+
obj["config"] = {}
|
|
54
|
+
obj["config"]["api_key"] = api_key
|
|
195
55
|
|
|
196
56
|
def get_object(self):
|
|
197
|
-
"""
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if not self.params or "config" in self.params:
|
|
202
|
-
self._get_config(obj)
|
|
203
|
-
if not self.params or "groups" in self.params:
|
|
204
|
-
self._get_groups(obj)
|
|
205
|
-
if not self.params or "metadata" in self.params:
|
|
206
|
-
self._get_metadata(obj)
|
|
57
|
+
"""Get the stats object with an api key."""
|
|
58
|
+
getter = CodexStats(self.params)
|
|
59
|
+
obj = getter.get()
|
|
60
|
+
self._add_api_key(obj)
|
|
207
61
|
return obj
|
|
208
62
|
|
|
209
63
|
@extend_schema(parameters=[input_serializer_class])
|
|
210
64
|
def get(self, *_args, **_kwargs):
|
|
211
65
|
"""Get the stats object and serialize it."""
|
|
212
|
-
|
|
213
|
-
input_serializer.is_valid()
|
|
214
|
-
self.params = frozenset(input_serializer.validated_data.get("params", {})) # type: ignore
|
|
215
|
-
|
|
66
|
+
self.params = self._parse_params()
|
|
216
67
|
obj = self.get_object()
|
|
68
|
+
|
|
217
69
|
serializer = self.get_serializer(obj)
|
|
218
70
|
return Response(serializer.data)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"""OPDS v1 Entry."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
+
from contextlib import suppress
|
|
4
5
|
from datetime import datetime, timezone
|
|
5
6
|
from urllib.parse import urlencode
|
|
6
7
|
|
|
8
|
+
from dateutil import parser
|
|
7
9
|
from django.urls import reverse
|
|
8
10
|
|
|
9
11
|
from codex.logger.logging import get_logger
|
|
@@ -24,11 +26,6 @@ LOG = get_logger(__name__)
|
|
|
24
26
|
class OPDS1Entry(OPDS1EntryLinksMixin):
|
|
25
27
|
"""An OPDS entry object."""
|
|
26
28
|
|
|
27
|
-
_DATE_FORMAT_BASE = "%Y-%m-%dT%H:%M:%S"
|
|
28
|
-
_DATE_FORMAT_MS = _DATE_FORMAT_BASE + ".%f%z"
|
|
29
|
-
_DATE_FORMAT = _DATE_FORMAT_BASE + "%z"
|
|
30
|
-
_DATE_FORMATS = (_DATE_FORMAT_MS, _DATE_FORMAT)
|
|
31
|
-
|
|
32
29
|
@property
|
|
33
30
|
def id_tag(self):
|
|
34
31
|
"""GUID is a nav url."""
|
|
@@ -69,9 +66,12 @@ class OPDS1Entry(OPDS1EntryLinksMixin):
|
|
|
69
66
|
@property
|
|
70
67
|
def issued(self):
|
|
71
68
|
"""Return the published date."""
|
|
69
|
+
date = ""
|
|
72
70
|
if self.obj.group == "c":
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
with suppress(Exception):
|
|
72
|
+
date = self.obj.date.isoformat()
|
|
73
|
+
|
|
74
|
+
return date
|
|
75
75
|
|
|
76
76
|
@property
|
|
77
77
|
def publisher(self):
|
|
@@ -81,17 +81,13 @@ class OPDS1Entry(OPDS1EntryLinksMixin):
|
|
|
81
81
|
def _get_datefield(self, key):
|
|
82
82
|
result = None
|
|
83
83
|
if not self.fake and (value := getattr(self.obj, key, None)):
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
result = value.astimezone(timezone.utc).strftime(date_format)
|
|
92
|
-
break
|
|
93
|
-
except ValueError:
|
|
94
|
-
pass
|
|
84
|
+
try:
|
|
85
|
+
if isinstance(value, str):
|
|
86
|
+
result = parser.parse(value)
|
|
87
|
+
if isinstance(value, datetime):
|
|
88
|
+
result = value.astimezone(timezone.utc).isoformat()
|
|
89
|
+
except ValueError:
|
|
90
|
+
pass
|
|
95
91
|
return result
|
|
96
92
|
|
|
97
93
|
@property
|
codex/views/opds/v1/feed.py
CHANGED
|
@@ -96,10 +96,14 @@ class OPDS1FeedView(OPDS1LinksView, OPDSTemplateView):
|
|
|
96
96
|
@property
|
|
97
97
|
def updated(self):
|
|
98
98
|
"""Use mtime for updated."""
|
|
99
|
+
datestr = ""
|
|
99
100
|
try:
|
|
100
|
-
|
|
101
|
+
mtime = self.obj.get("mtime")
|
|
102
|
+
if mtime:
|
|
103
|
+
datestr = mtime.isoformat() # type: ignore
|
|
101
104
|
except Exception:
|
|
102
105
|
LOG.exception("Getting OPDS v1 updated")
|
|
106
|
+
return datestr
|
|
103
107
|
|
|
104
108
|
@property
|
|
105
109
|
def items_per_page(self):
|
codex/views/opds/v1/links.py
CHANGED
|
@@ -168,6 +168,7 @@ class OPDS1LinksView(OPDS1FacetsView):
|
|
|
168
168
|
reverse("opds:authentication:v1"),
|
|
169
169
|
MimeType.AUTHENTICATION,
|
|
170
170
|
),
|
|
171
|
+
OPDS1Link(Rel.START, reverse("opds:v1:start"), MimeType.NAV),
|
|
171
172
|
OPDS1Link(
|
|
172
173
|
"search", reverse("opds:v1:opensearch_v1"), MimeType.OPENSEARCH
|
|
173
174
|
),
|
codex/views/reader/arcs.py
CHANGED
|
@@ -22,10 +22,10 @@ class ReaderArcsView(ReaderBooksView):
|
|
|
22
22
|
def _get_group_arc(self, book, attr, browser_arc_group, arcs, max_mtime): # noqa: PLR0913
|
|
23
23
|
"""Append the volume arc."""
|
|
24
24
|
if browser_arc_group == attr[0]:
|
|
25
|
-
return
|
|
25
|
+
return max_mtime
|
|
26
26
|
group = getattr(book, attr, None)
|
|
27
27
|
if not group:
|
|
28
|
-
return
|
|
28
|
+
return max_mtime
|
|
29
29
|
|
|
30
30
|
_, arc_pks = self.get_group_pks_from_breadcrumbs([group])
|
|
31
31
|
if group.pk not in arc_pks:
|
|
@@ -48,7 +48,7 @@ class ReaderArcsView(ReaderBooksView):
|
|
|
48
48
|
.on
|
|
49
49
|
)
|
|
50
50
|
if not efv_flag or browser_arc_group == FOLDER_GROUP:
|
|
51
|
-
return
|
|
51
|
+
return max_mtime
|
|
52
52
|
|
|
53
53
|
folder = book.parent_folder
|
|
54
54
|
arcs.append(
|
|
@@ -88,7 +88,8 @@ class ReaderArcsView(ReaderBooksView):
|
|
|
88
88
|
|
|
89
89
|
if browser_arc := self.params.get("browser_arc", {}):
|
|
90
90
|
arcs.append(browser_arc)
|
|
91
|
-
|
|
91
|
+
browser_arc_mtime = browser_arc.get("mtime")
|
|
92
|
+
max_mtime = max_none(max_mtime, browser_arc_mtime)
|
|
92
93
|
|
|
93
94
|
browser_arc_group = browser_arc.get("group", "")
|
|
94
95
|
max_mtime = self._get_group_arc(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codex
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.5
|
|
4
4
|
Summary: A comic archive web server.
|
|
5
5
|
Home-page: https://github.com/ajslater/codex
|
|
6
6
|
License: GPL-3.0-only
|
|
@@ -29,7 +29,7 @@ Requires-Dist: ansicolors (>=1.1,<2.0)
|
|
|
29
29
|
Requires-Dist: bidict (>=0.23.1,<0.24.0)
|
|
30
30
|
Requires-Dist: case-converter (>=1.1.0,<2.0.0)
|
|
31
31
|
Requires-Dist: channels (>=4.0.0,<5.0.0)
|
|
32
|
-
Requires-Dist: comicbox[pdf] (>=1.1.
|
|
32
|
+
Requires-Dist: comicbox[pdf] (>=1.1.10,<2.0.0)
|
|
33
33
|
Requires-Dist: django (>=5.0.6,<6.0.0)
|
|
34
34
|
Requires-Dist: django-cachalot (>=2.6.2,<3.0.0)
|
|
35
35
|
Requires-Dist: django-cors-headers (>=4.0,<5.0)
|
|
@@ -42,7 +42,7 @@ Requires-Dist: fnvhash (>=0.1,<0.2)
|
|
|
42
42
|
Requires-Dist: humanfriendly (>=10.0,<11.0)
|
|
43
43
|
Requires-Dist: humanize (>=4.0.0,<5.0.0)
|
|
44
44
|
Requires-Dist: hypercorn[h3] (>=0.17.3,<0.18.0)
|
|
45
|
-
Requires-Dist: psutil (>=
|
|
45
|
+
Requires-Dist: psutil (>=6.0.0,<7.0.0)
|
|
46
46
|
Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
|
|
47
47
|
Requires-Dist: requests (>=2.24,<3.0)
|
|
48
48
|
Requires-Dist: setuptools (>=70.0.0,<71.0.0)
|
|
@@ -71,6 +71,7 @@ border-radius: 128px;
|
|
|
71
71
|
## <a name="features">✨ Features</a>
|
|
72
72
|
|
|
73
73
|
- Codex is a web server.
|
|
74
|
+
- GPLv3 Licenced.
|
|
74
75
|
- Full text search of metadata and bookmarks.
|
|
75
76
|
- Filter and sort on all comic metadata and unread status per user.
|
|
76
77
|
- Browse a tree of Publishers, Imprints, Series, Volumes, or your own folder
|
|
@@ -95,8 +96,8 @@ border-radius: 128px;
|
|
|
95
96
|
|
|
96
97
|
## <a name="demonstration">👀 Demonstration</a>
|
|
97
98
|
|
|
98
|
-
You may browse a [live demo server](https://codex.
|
|
99
|
-
Codex.
|
|
99
|
+
You may browse a [live demo server](https://demo.codex-reader.app/) to get a
|
|
100
|
+
feel for Codex.
|
|
100
101
|
|
|
101
102
|
## <a name="news">📜 News</a>
|
|
102
103
|
|
|
@@ -134,12 +135,22 @@ brew install jpeg libffi libyaml libzip openssl python unrar webp
|
|
|
134
135
|
|
|
135
136
|
###### <a href="#debian">Debian</a>
|
|
136
137
|
|
|
137
|
-
...and Ubuntu, Mint, MX and others.
|
|
138
|
+
...and Ubuntu, Mint, MX and others (and WSL).
|
|
138
139
|
|
|
139
140
|
<!-- eslint-skip -->
|
|
140
141
|
|
|
141
142
|
```sh
|
|
142
|
-
apt install build-essential libimagequant0
|
|
143
|
+
apt install build-essential libimagequant0 libjpeg-turbo8 libopenjp2-7 libssl libyaml-0-2 libtiff6 libwebp7 python3-dev python3-pip mupdf unrar zlib1g
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Versions of packages like libjpeg, libssl, libtiff may differ between flavors
|
|
147
|
+
and versions of Debian. If the version above is not available, try searching for
|
|
148
|
+
one that is with apt-cache or aptitude.
|
|
149
|
+
|
|
150
|
+
<!-- eslint-skip -->
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
apt-cache search libjpeg-turbo
|
|
143
154
|
```
|
|
144
155
|
|
|
145
156
|
###### Alpine
|