codex 1.6.1__py3-none-any.whl → 1.6.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of codex might be problematic. Click here for more details.
- codex/exceptions.py +42 -16
- codex/librarian/search/update.py +1 -1
- codex/serializers/admin/__init__.py +1 -0
- codex/serializers/admin/flags.py +15 -0
- codex/serializers/admin/groups.py +38 -0
- codex/serializers/admin/libraries.py +90 -0
- codex/serializers/admin/stats.py +114 -0
- codex/serializers/admin/tasks.py +16 -0
- codex/serializers/admin/users.py +40 -0
- codex/serializers/fields.py +7 -0
- codex/serializers/reader.py +8 -3
- codex/static_root/assets/VCheckbox-CXQlndFT.c17c006a62e6.js +1 -0
- 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 +1 -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 +1 -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 +1 -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-pHa6iBaZ.ff88fede19d6.js → VCombobox-BDcFPzYf.0b80447cd638.js} +1 -1
- 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-pHa6iBaZ.js → VCombobox-BDcFPzYf.js} +1 -1
- 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 +1 -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 +1 -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 +1 -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 +1 -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 +1 -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 +1 -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 +1 -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 +1 -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-D4e-QshF.js → VSelectionControl-DImIQPJV.1f14d2113063.js} +1 -1
- 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-D4e-QshF.38721ba52d00.js → VSelectionControl-DImIQPJV.js} +1 -1
- 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-BQv5m0ZY.2adc55157521.js → VSlideGroup-CDaAHRAK.783800d70a8a.js} +1 -1
- 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-BQv5m0ZY.js → VSlideGroup-CDaAHRAK.js} +1 -1
- 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-BPFJigN3.2b5f59873063.js → VTable-CkCZonsu.81e34381271f.js} +1 -1
- 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-BPFJigN3.js → VTable-CkCZonsu.js} +1 -1
- 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 +1 -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 +1 -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-C1xK_Fwc.6a80dfed4beb.js → VWindowItem-_YBMW1SU.0836924f8c12.js} +1 -1
- 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-C1xK_Fwc.js → VWindowItem-_YBMW1SU.js} +1 -1
- 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-B8Bp2Uih.82c98714bcf1.css → admin-D4sw3N4T.b590f88a62cf.css} +1 -1
- codex/static_root/assets/admin-D4sw3N4T.b590f88a62cf.css.br +0 -0
- codex/static_root/assets/admin-D4sw3N4T.b590f88a62cf.css.gz +0 -0
- codex/static_root/assets/{admin-B8Bp2Uih.css → admin-D4sw3N4T.css} +1 -1
- codex/static_root/assets/admin-D4sw3N4T.css.br +0 -0
- codex/static_root/assets/admin-D4sw3N4T.css.gz +0 -0
- codex/static_root/assets/admin-DYmGyJVg.262e6032ee86.js +1 -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 +1 -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 +56 -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 +56 -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 +1 -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 +1 -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-DP9eEJ0M.276e8636f8fc.css → browser-DgawKPSA.c7cf59dc4b21.css} +1 -1
- 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-DP9eEJ0M.css → browser-DgawKPSA.css} +1 -1
- 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 +1 -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 +1 -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 +1 -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 +1 -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-CYmuurug.0f5658d9b9e2.js → datetime-column-D8-UeX_p.e33b1556805b.js} +1 -1
- 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-CYmuurug.js → datetime-column-D8-UeX_p.js} +1 -1
- 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-D0YNadTH.e6ee9bc95c0f.js → filter-XMAX5Nmg.c6ed87350f7d.js} +1 -1
- 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-D0YNadTH.js → filter-XMAX5Nmg.js} +1 -1
- 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 +1 -0
- 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 +1 -0
- 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/group-tab-D9n5gZCA.634223001c44.js +1 -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 +1 -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 +1 -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 +1 -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-BN0SfPcH.913e236f625e.css → library-tab-BygwYPnO.94e92aa60bf2.css} +1 -1
- codex/static_root/assets/library-tab-BygwYPnO.94e92aa60bf2.css.br +0 -0
- codex/static_root/assets/library-tab-BygwYPnO.94e92aa60bf2.css.gz +0 -0
- codex/static_root/assets/{library-tab-BN0SfPcH.css → library-tab-BygwYPnO.css} +1 -1
- codex/static_root/assets/library-tab-BygwYPnO.css.br +0 -0
- codex/static_root/assets/library-tab-BygwYPnO.css.gz +0 -0
- codex/static_root/assets/library-tab-fDxuhPBs.285b36d9cec0.js +1 -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 +1 -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 +6 -0
- 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 +6 -0
- 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 +1 -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 +1 -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-MjpbXXnS.85038ab4cb8e.js → pdf-doc-iF15lKRp.de9a9d394438.js} +1 -1
- 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-MjpbXXnS.js → pdf-doc-iF15lKRp.js} +1 -1
- 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 +2 -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 +2 -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/{reader-DOQuhDYO.css → reader-YbzUiD0T.css} +1 -1
- codex/static_root/assets/reader-YbzUiD0T.css.br +0 -0
- codex/static_root/assets/reader-YbzUiD0T.css.gz +0 -0
- codex/static_root/assets/{reader-DOQuhDYO.df559ad29ab3.css → reader-YbzUiD0T.efb15835b39d.css} +1 -1
- codex/static_root/assets/reader-YbzUiD0T.efb15835b39d.css.br +0 -0
- codex/static_root/assets/reader-YbzUiD0T.efb15835b39d.css.gz +0 -0
- codex/static_root/assets/{relation-chips-Bsc-gUxE.98e65384c3c9.css → relation-chips-BGitp3yx.b3e7d178a615.css} +1 -1
- codex/static_root/assets/relation-chips-BGitp3yx.b3e7d178a615.css.br +0 -0
- codex/static_root/assets/relation-chips-BGitp3yx.b3e7d178a615.css.gz +0 -0
- codex/static_root/assets/{relation-chips-Bsc-gUxE.css → relation-chips-BGitp3yx.css} +1 -1
- codex/static_root/assets/relation-chips-BGitp3yx.css.br +0 -0
- codex/static_root/assets/relation-chips-BGitp3yx.css.gz +0 -0
- codex/static_root/assets/relation-chips-CUWkvLNo.3d18d0c09d39.js +1 -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 +1 -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 +2 -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 +2 -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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -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 +1 -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 +1 -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 +1 -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 +1 -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 +1 -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.c852d4a311e1.json → manifest.166aa32817b1.json} +229 -241
- codex/static_root/manifest.166aa32817b1.json.br +0 -0
- codex/static_root/manifest.166aa32817b1.json.gz +0 -0
- codex/static_root/manifest.json +229 -241
- codex/static_root/manifest.json.br +0 -0
- codex/static_root/manifest.json.gz +0 -0
- codex/static_root/staticfiles.json +1 -1
- codex/views/admin/api_key.py +1 -1
- codex/views/admin/flag.py +1 -1
- codex/views/admin/group.py +1 -1
- codex/views/admin/library.py +1 -1
- codex/views/admin/stats.py +41 -7
- codex/views/admin/tasks.py +1 -1
- codex/views/admin/user.py +1 -1
- codex/views/browser/annotations.py +7 -4
- codex/views/browser/browser.py +8 -5
- codex/views/browser/cover.py +0 -2
- codex/views/browser/filters/field.py +15 -6
- codex/views/browser/metadata.py +6 -9
- codex/views/browser/paginate.py +61 -11
- codex/views/browser/validate.py +7 -5
- codex/views/opds/binary.py +1 -3
- codex/views/opds/const.py +10 -0
- codex/views/opds/util.py +10 -0
- codex/views/opds/v1/feed.py +5 -23
- codex/views/reader/arcs.py +64 -53
- codex/views/reader/books.py +38 -38
- codex/views/reader/init.py +7 -5
- codex/views/reader/reader.py +0 -2
- {codex-1.6.1.dist-info → codex-1.6.3.dist-info}/METADATA +1 -1
- {codex-1.6.1.dist-info → codex-1.6.3.dist-info}/RECORD +279 -275
- codex/serializers/admin.py +0 -268
- codex/static_root/assets/VCheckbox-fu1ny9Cc.7f2b43d1ce47.js +0 -1
- codex/static_root/assets/VCheckbox-fu1ny9Cc.7f2b43d1ce47.js.br +0 -0
- codex/static_root/assets/VCheckbox-fu1ny9Cc.7f2b43d1ce47.js.gz +0 -0
- codex/static_root/assets/VCheckbox-fu1ny9Cc.js +0 -1
- codex/static_root/assets/VCheckbox-fu1ny9Cc.js.br +0 -0
- codex/static_root/assets/VCheckbox-fu1ny9Cc.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-ssJU_z8r.7469708eff4e.js +0 -1
- codex/static_root/assets/VCheckboxBtn-ssJU_z8r.7469708eff4e.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-ssJU_z8r.7469708eff4e.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-ssJU_z8r.js +0 -1
- codex/static_root/assets/VCheckboxBtn-ssJU_z8r.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-ssJU_z8r.js.gz +0 -0
- codex/static_root/assets/VCombobox-pHa6iBaZ.ff88fede19d6.js.br +0 -0
- codex/static_root/assets/VCombobox-pHa6iBaZ.ff88fede19d6.js.gz +0 -0
- codex/static_root/assets/VCombobox-pHa6iBaZ.js.br +0 -0
- codex/static_root/assets/VCombobox-pHa6iBaZ.js.gz +0 -0
- codex/static_root/assets/VDialog-PmbYIKIh.c0fb4c6eb906.js +0 -1
- codex/static_root/assets/VDialog-PmbYIKIh.c0fb4c6eb906.js.br +0 -0
- codex/static_root/assets/VDialog-PmbYIKIh.c0fb4c6eb906.js.gz +0 -0
- codex/static_root/assets/VDialog-PmbYIKIh.js +0 -1
- codex/static_root/assets/VDialog-PmbYIKIh.js.br +0 -0
- codex/static_root/assets/VDialog-PmbYIKIh.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DhRGJRFB.d1fb2c18424b.js +0 -1
- codex/static_root/assets/VExpansionPanels-DhRGJRFB.d1fb2c18424b.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-DhRGJRFB.d1fb2c18424b.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DhRGJRFB.js +0 -1
- codex/static_root/assets/VExpansionPanels-DhRGJRFB.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-DhRGJRFB.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-ClT4cR8E.1aa488b49221.js +0 -1
- codex/static_root/assets/VRadioGroup-ClT4cR8E.1aa488b49221.js.br +0 -0
- codex/static_root/assets/VRadioGroup-ClT4cR8E.1aa488b49221.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-ClT4cR8E.js +0 -1
- codex/static_root/assets/VRadioGroup-ClT4cR8E.js.br +0 -0
- codex/static_root/assets/VRadioGroup-ClT4cR8E.js.gz +0 -0
- codex/static_root/assets/VSelect-BBy4FHPj.7421f9feb46b.js +0 -1
- codex/static_root/assets/VSelect-BBy4FHPj.7421f9feb46b.js.br +0 -0
- codex/static_root/assets/VSelect-BBy4FHPj.7421f9feb46b.js.gz +0 -0
- codex/static_root/assets/VSelect-BBy4FHPj.js +0 -1
- codex/static_root/assets/VSelect-BBy4FHPj.js.br +0 -0
- codex/static_root/assets/VSelect-BBy4FHPj.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-D4e-QshF.38721ba52d00.js.br +0 -0
- codex/static_root/assets/VSelectionControl-D4e-QshF.38721ba52d00.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-D4e-QshF.js.br +0 -0
- codex/static_root/assets/VSelectionControl-D4e-QshF.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-BQv5m0ZY.2adc55157521.js.br +0 -0
- codex/static_root/assets/VSlideGroup-BQv5m0ZY.2adc55157521.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-BQv5m0ZY.js.br +0 -0
- codex/static_root/assets/VSlideGroup-BQv5m0ZY.js.gz +0 -0
- codex/static_root/assets/VTable-BPFJigN3.2b5f59873063.js.br +0 -0
- codex/static_root/assets/VTable-BPFJigN3.2b5f59873063.js.gz +0 -0
- codex/static_root/assets/VTable-BPFJigN3.js.br +0 -0
- codex/static_root/assets/VTable-BPFJigN3.js.gz +0 -0
- codex/static_root/assets/VTextField-DuT-8VmG.04e65c2610a4.js +0 -1
- codex/static_root/assets/VTextField-DuT-8VmG.04e65c2610a4.js.br +0 -0
- codex/static_root/assets/VTextField-DuT-8VmG.04e65c2610a4.js.gz +0 -0
- codex/static_root/assets/VTextField-DuT-8VmG.js +0 -1
- codex/static_root/assets/VTextField-DuT-8VmG.js.br +0 -0
- codex/static_root/assets/VTextField-DuT-8VmG.js.gz +0 -0
- codex/static_root/assets/VWindowItem-C1xK_Fwc.6a80dfed4beb.js.br +0 -0
- codex/static_root/assets/VWindowItem-C1xK_Fwc.6a80dfed4beb.js.gz +0 -0
- codex/static_root/assets/VWindowItem-C1xK_Fwc.js.br +0 -0
- codex/static_root/assets/VWindowItem-C1xK_Fwc.js.gz +0 -0
- 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-B8Bp2Uih.css.br +0 -0
- codex/static_root/assets/admin-B8Bp2Uih.css.gz +0 -0
- codex/static_root/assets/admin-DAexM4mM.2fa224507884.js +0 -1
- codex/static_root/assets/admin-DAexM4mM.2fa224507884.js.br +0 -0
- codex/static_root/assets/admin-DAexM4mM.2fa224507884.js.gz +0 -0
- codex/static_root/assets/admin-DAexM4mM.js +0 -1
- codex/static_root/assets/admin-DAexM4mM.js.br +0 -0
- codex/static_root/assets/admin-DAexM4mM.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-SpPhIMP4.b9a6113090c9.js +0 -30
- codex/static_root/assets/admin-drawer-panel-SpPhIMP4.b9a6113090c9.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-SpPhIMP4.b9a6113090c9.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-SpPhIMP4.js +0 -30
- codex/static_root/assets/admin-drawer-panel-SpPhIMP4.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-SpPhIMP4.js.gz +0 -0
- codex/static_root/assets/browser-CWfL6gLS.92842e328420.js +0 -1
- codex/static_root/assets/browser-CWfL6gLS.92842e328420.js.br +0 -0
- codex/static_root/assets/browser-CWfL6gLS.92842e328420.js.gz +0 -0
- codex/static_root/assets/browser-CWfL6gLS.js +0 -1
- codex/static_root/assets/browser-CWfL6gLS.js.br +0 -0
- codex/static_root/assets/browser-CWfL6gLS.js.gz +0 -0
- codex/static_root/assets/browser-DP9eEJ0M.276e8636f8fc.css.br +0 -0
- codex/static_root/assets/browser-DP9eEJ0M.276e8636f8fc.css.gz +0 -0
- codex/static_root/assets/browser-DP9eEJ0M.css.br +0 -0
- codex/static_root/assets/browser-DP9eEJ0M.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-BJHFtdXE.0a718e633507.js +0 -1
- codex/static_root/assets/change-password-dialog-BJHFtdXE.0a718e633507.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BJHFtdXE.0a718e633507.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-BJHFtdXE.js +0 -1
- codex/static_root/assets/change-password-dialog-BJHFtdXE.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BJHFtdXE.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-BEiVusri.e3d017feba41.js +0 -1
- codex/static_root/assets/confirm-dialog-BEiVusri.e3d017feba41.js.br +0 -0
- codex/static_root/assets/confirm-dialog-BEiVusri.e3d017feba41.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-BEiVusri.js +0 -1
- codex/static_root/assets/confirm-dialog-BEiVusri.js.br +0 -0
- codex/static_root/assets/confirm-dialog-BEiVusri.js.gz +0 -0
- codex/static_root/assets/datetime-column-CYmuurug.0f5658d9b9e2.js.br +0 -0
- codex/static_root/assets/datetime-column-CYmuurug.0f5658d9b9e2.js.gz +0 -0
- codex/static_root/assets/datetime-column-CYmuurug.js.br +0 -0
- codex/static_root/assets/datetime-column-CYmuurug.js.gz +0 -0
- codex/static_root/assets/filter-D0YNadTH.e6ee9bc95c0f.js.br +0 -0
- codex/static_root/assets/filter-D0YNadTH.e6ee9bc95c0f.js.gz +0 -0
- codex/static_root/assets/filter-D0YNadTH.js.br +0 -0
- codex/static_root/assets/filter-D0YNadTH.js.gz +0 -0
- codex/static_root/assets/flag-tab-CAsMFvQO.9cc9cd124ee9.js +0 -1
- codex/static_root/assets/flag-tab-CAsMFvQO.9cc9cd124ee9.js.br +0 -0
- codex/static_root/assets/flag-tab-CAsMFvQO.9cc9cd124ee9.js.gz +0 -0
- codex/static_root/assets/flag-tab-CAsMFvQO.js +0 -1
- codex/static_root/assets/flag-tab-CAsMFvQO.js.br +0 -0
- codex/static_root/assets/flag-tab-CAsMFvQO.js.gz +0 -0
- codex/static_root/assets/group-tab-Cr0hebSY.22e6025c588f.js +0 -1
- codex/static_root/assets/group-tab-Cr0hebSY.22e6025c588f.js.br +0 -0
- codex/static_root/assets/group-tab-Cr0hebSY.22e6025c588f.js.gz +0 -0
- codex/static_root/assets/group-tab-Cr0hebSY.js +0 -1
- codex/static_root/assets/group-tab-Cr0hebSY.js.br +0 -0
- codex/static_root/assets/group-tab-Cr0hebSY.js.gz +0 -0
- codex/static_root/assets/http-error-BkvLxw68.a5f561d36571.js +0 -1
- codex/static_root/assets/http-error-BkvLxw68.a5f561d36571.js.br +0 -0
- codex/static_root/assets/http-error-BkvLxw68.a5f561d36571.js.gz +0 -0
- codex/static_root/assets/http-error-BkvLxw68.js +0 -1
- codex/static_root/assets/http-error-BkvLxw68.js.br +0 -0
- codex/static_root/assets/http-error-BkvLxw68.js.gz +0 -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.br +0 -0
- codex/static_root/assets/library-tab-BN0SfPcH.css.gz +0 -0
- codex/static_root/assets/library-tab-r6YdFmlk.d136e20e3501.js +0 -1
- codex/static_root/assets/library-tab-r6YdFmlk.d136e20e3501.js.br +0 -0
- codex/static_root/assets/library-tab-r6YdFmlk.d136e20e3501.js.gz +0 -0
- codex/static_root/assets/library-tab-r6YdFmlk.js +0 -1
- codex/static_root/assets/library-tab-r6YdFmlk.js.br +0 -0
- codex/static_root/assets/library-tab-r6YdFmlk.js.gz +0 -0
- codex/static_root/assets/main-BMxHA4IB.19ea7128bc87.js +0 -32
- codex/static_root/assets/main-BMxHA4IB.19ea7128bc87.js.br +0 -0
- codex/static_root/assets/main-BMxHA4IB.19ea7128bc87.js.gz +0 -0
- codex/static_root/assets/main-BMxHA4IB.js +0 -32
- codex/static_root/assets/main-BMxHA4IB.js.br +0 -0
- codex/static_root/assets/main-BMxHA4IB.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BO02XyZj.b1574d505e3c.js +0 -1
- codex/static_root/assets/pagination-toolbar-BO02XyZj.b1574d505e3c.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-BO02XyZj.b1574d505e3c.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BO02XyZj.js +0 -1
- codex/static_root/assets/pagination-toolbar-BO02XyZj.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-BO02XyZj.js.gz +0 -0
- codex/static_root/assets/pdf-doc-MjpbXXnS.85038ab4cb8e.js.br +0 -0
- codex/static_root/assets/pdf-doc-MjpbXXnS.85038ab4cb8e.js.gz +0 -0
- codex/static_root/assets/pdf-doc-MjpbXXnS.js.br +0 -0
- codex/static_root/assets/pdf-doc-MjpbXXnS.js.gz +0 -0
- codex/static_root/assets/reader-AMeiJSE6.556392e64785.js +0 -2
- codex/static_root/assets/reader-AMeiJSE6.556392e64785.js.br +0 -0
- codex/static_root/assets/reader-AMeiJSE6.556392e64785.js.gz +0 -0
- codex/static_root/assets/reader-AMeiJSE6.js +0 -2
- codex/static_root/assets/reader-AMeiJSE6.js.br +0 -0
- codex/static_root/assets/reader-AMeiJSE6.js.gz +0 -0
- codex/static_root/assets/reader-DOQuhDYO.css.br +0 -0
- codex/static_root/assets/reader-DOQuhDYO.css.gz +0 -0
- codex/static_root/assets/reader-DOQuhDYO.df559ad29ab3.css.br +0 -0
- codex/static_root/assets/reader-DOQuhDYO.df559ad29ab3.css.gz +0 -0
- 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-Bsc-gUxE.css.br +0 -0
- codex/static_root/assets/relation-chips-Bsc-gUxE.css.gz +0 -0
- codex/static_root/assets/relation-chips-DKzjmNPq.de2203c11719.js +0 -1
- codex/static_root/assets/relation-chips-DKzjmNPq.de2203c11719.js.br +0 -0
- codex/static_root/assets/relation-chips-DKzjmNPq.de2203c11719.js.gz +0 -0
- codex/static_root/assets/relation-chips-DKzjmNPq.js +0 -1
- codex/static_root/assets/relation-chips-DKzjmNPq.js.br +0 -0
- codex/static_root/assets/relation-chips-DKzjmNPq.js.gz +0 -0
- codex/static_root/assets/settings-drawer-DuR_I-os.d1754da85f24.js +0 -2
- codex/static_root/assets/settings-drawer-DuR_I-os.d1754da85f24.js.br +0 -0
- codex/static_root/assets/settings-drawer-DuR_I-os.d1754da85f24.js.gz +0 -0
- codex/static_root/assets/settings-drawer-DuR_I-os.js +0 -2
- codex/static_root/assets/settings-drawer-DuR_I-os.js.br +0 -0
- codex/static_root/assets/settings-drawer-DuR_I-os.js.gz +0 -0
- codex/static_root/assets/stats-tab-B4yKuY0c.a5728396494b.css +0 -1
- codex/static_root/assets/stats-tab-B4yKuY0c.a5728396494b.css.br +0 -0
- codex/static_root/assets/stats-tab-B4yKuY0c.a5728396494b.css.gz +0 -0
- codex/static_root/assets/stats-tab-B4yKuY0c.css +0 -1
- codex/static_root/assets/stats-tab-B4yKuY0c.css.br +0 -0
- codex/static_root/assets/stats-tab-B4yKuY0c.css.gz +0 -0
- codex/static_root/assets/stats-tab-CgBniikR.ce1c6941c844.js +0 -1
- codex/static_root/assets/stats-tab-CgBniikR.ce1c6941c844.js.br +0 -0
- codex/static_root/assets/stats-tab-CgBniikR.ce1c6941c844.js.gz +0 -0
- codex/static_root/assets/stats-tab-CgBniikR.js +0 -1
- codex/static_root/assets/stats-tab-CgBniikR.js.br +0 -0
- codex/static_root/assets/stats-tab-CgBniikR.js.gz +0 -0
- codex/static_root/assets/task-tab-JjKaS7pI.c01782978325.js +0 -1
- codex/static_root/assets/task-tab-JjKaS7pI.c01782978325.js.br +0 -0
- codex/static_root/assets/task-tab-JjKaS7pI.c01782978325.js.gz +0 -0
- codex/static_root/assets/task-tab-JjKaS7pI.js +0 -1
- codex/static_root/assets/task-tab-JjKaS7pI.js.br +0 -0
- codex/static_root/assets/task-tab-JjKaS7pI.js.gz +0 -0
- codex/static_root/assets/to-case-CMMdeNjM.64cd6ddff339.js +0 -1
- codex/static_root/assets/to-case-CMMdeNjM.js +0 -1
- codex/static_root/assets/unauthorized-Cz-M4lP9.d11776d78241.js +0 -1
- codex/static_root/assets/unauthorized-Cz-M4lP9.d11776d78241.js.br +0 -0
- codex/static_root/assets/unauthorized-Cz-M4lP9.d11776d78241.js.gz +0 -0
- codex/static_root/assets/unauthorized-Cz-M4lP9.js +0 -1
- codex/static_root/assets/unauthorized-Cz-M4lP9.js.br +0 -0
- codex/static_root/assets/unauthorized-Cz-M4lP9.js.gz +0 -0
- codex/static_root/assets/user-tab-HnLW9C3q.7f44c7f960c2.js +0 -1
- codex/static_root/assets/user-tab-HnLW9C3q.7f44c7f960c2.js.br +0 -0
- codex/static_root/assets/user-tab-HnLW9C3q.7f44c7f960c2.js.gz +0 -0
- codex/static_root/assets/user-tab-HnLW9C3q.js +0 -1
- codex/static_root/assets/user-tab-HnLW9C3q.js.br +0 -0
- codex/static_root/assets/user-tab-HnLW9C3q.js.gz +0 -0
- codex/static_root/manifest.c852d4a311e1.json.br +0 -0
- codex/static_root/manifest.c852d4a311e1.json.gz +0 -0
- {codex-1.6.1.dist-info → codex-1.6.3.dist-info}/LICENSE +0 -0
- {codex-1.6.1.dist-info → codex-1.6.3.dist-info}/WHEEL +0 -0
- {codex-1.6.1.dist-info → codex-1.6.3.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/relation-chips-Bsc-gUxE.css": "assets/relation-chips-Bsc-gUxE.98e65384c3c9.css", "assets/group-tab-CBKuS3Iv.css": "assets/group-tab-CBKuS3Iv.7e4746634782.css", "assets/user-tab-HnLW9C3q.js": "assets/user-tab-HnLW9C3q.7f44c7f960c2.js", "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/http-error-BkvLxw68.js": "assets/http-error-BkvLxw68.a5f561d36571.js", "assets/browser-DP9eEJ0M.css": "assets/browser-DP9eEJ0M.276e8636f8fc.css", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/VRadioGroup-ClT4cR8E.js": "assets/VRadioGroup-ClT4cR8E.1aa488b49221.js", "assets/VTextField-DuT-8VmG.js": "assets/VTextField-DuT-8VmG.04e65c2610a4.js", "assets/browser-CWfL6gLS.js": "assets/browser-CWfL6gLS.92842e328420.js", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/VCheckboxBtn-ssJU_z8r.js": "assets/VCheckboxBtn-ssJU_z8r.7469708eff4e.js", "assets/datetime-column-CYmuurug.js": "assets/datetime-column-CYmuurug.0f5658d9b9e2.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/reader-AMeiJSE6.js": "assets/reader-AMeiJSE6.556392e64785.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/main-BMxHA4IB.js": "assets/main-BMxHA4IB.19ea7128bc87.js", "assets/VDialog-lQ13FnRR.css": "assets/VDialog-lQ13FnRR.1c801ad756b2.css", "assets/stats-tab-CgBniikR.js": "assets/stats-tab-CgBniikR.ce1c6941c844.js", "assets/pagination-toolbar-BO02XyZj.js": "assets/pagination-toolbar-BO02XyZj.b1574d505e3c.js", "assets/main-Ztp855PW.css": "assets/main-Ztp855PW.d46d718fac45.css", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/confirm-dialog-BEiVusri.js": "assets/confirm-dialog-BEiVusri.e3d017feba41.js", "assets/change-password-dialog-0u6IJA87.css": "assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css", "assets/change-password-dialog-BJHFtdXE.js": "assets/change-password-dialog-BJHFtdXE.0a718e633507.js", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/VTable-BPFJigN3.js": "assets/VTable-BPFJigN3.2b5f59873063.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/filter-D0YNadTH.js": "assets/filter-D0YNadTH.e6ee9bc95c0f.js", "assets/admin-DAexM4mM.js": "assets/admin-DAexM4mM.2fa224507884.js", "assets/VCheckbox-fu1ny9Cc.js": "assets/VCheckbox-fu1ny9Cc.7f2b43d1ce47.js", "assets/pagination-toolbar-BA9ifTed.css": "assets/pagination-toolbar-BA9ifTed.b4865334ee08.css", "assets/VSelect-BBy4FHPj.js": "assets/VSelect-BBy4FHPj.7421f9feb46b.js", "assets/task-tab-JjKaS7pI.js": "assets/task-tab-JjKaS7pI.c01782978325.js", "assets/unauthorized-Cz-M4lP9.js": "assets/unauthorized-Cz-M4lP9.d11776d78241.js", "assets/VWindowItem-C1xK_Fwc.js": "assets/VWindowItem-C1xK_Fwc.6a80dfed4beb.js", "assets/VExpansionPanels-DhRGJRFB.js": "assets/VExpansionPanels-DhRGJRFB.d1fb2c18424b.js", "assets/library-tab-BN0SfPcH.css": "assets/library-tab-BN0SfPcH.913e236f625e.css", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/relation-chips-DKzjmNPq.js": "assets/relation-chips-DKzjmNPq.de2203c11719.js", "assets/to-case-CMMdeNjM.js": "assets/to-case-CMMdeNjM.64cd6ddff339.js", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/admin-drawer-panel-SpPhIMP4.js": "assets/admin-drawer-panel-SpPhIMP4.b9a6113090c9.js", "assets/flag-tab-CAsMFvQO.js": "assets/flag-tab-CAsMFvQO.9cc9cd124ee9.js", "assets/VDialog-PmbYIKIh.js": "assets/VDialog-PmbYIKIh.c0fb4c6eb906.js", "assets/VCombobox-pHa6iBaZ.js": "assets/VCombobox-pHa6iBaZ.ff88fede19d6.js", "assets/library-tab-r6YdFmlk.js": "assets/library-tab-r6YdFmlk.d136e20e3501.js", "assets/admin-B8Bp2Uih.css": "assets/admin-B8Bp2Uih.82c98714bcf1.css", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/stats-tab-B4yKuY0c.css": "assets/stats-tab-B4yKuY0c.a5728396494b.css", "assets/VSelectionControl-D4e-QshF.js": "assets/VSelectionControl-D4e-QshF.38721ba52d00.js", "assets/datetime-column-DeCthByU.css": "assets/datetime-column-DeCthByU.1f3bf499e063.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/pdf-doc-MjpbXXnS.js": "assets/pdf-doc-MjpbXXnS.85038ab4cb8e.js", "assets/reader-DOQuhDYO.css": "assets/reader-DOQuhDYO.df559ad29ab3.css", "assets/unauthorized-DWDO1s6-.css": "assets/unauthorized-DWDO1s6-.d34daac27dcf.css", "assets/group-tab-Cr0hebSY.js": "assets/group-tab-Cr0hebSY.22e6025c588f.js", "assets/VSlideGroup-BQv5m0ZY.js": "assets/VSlideGroup-BQv5m0ZY.2adc55157521.js", "assets/settings-drawer-DuR_I-os.js": "assets/settings-drawer-DuR_I-os.d1754da85f24.js", "assets/VExpansionPanels-DsEXVcCv.css": "assets/VExpansionPanels-DsEXVcCv.20b475255e66.css", "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.c852d4a311e1.json"}, "version": "1.1", "hash": "b64703c6e7f3"}
|
|
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"}
|
codex/views/admin/api_key.py
CHANGED
|
@@ -4,7 +4,7 @@ from drf_spectacular.utils import extend_schema
|
|
|
4
4
|
from rest_framework.response import Response
|
|
5
5
|
|
|
6
6
|
from codex.models import Timestamp
|
|
7
|
-
from codex.serializers.admin import APIKeySerializer
|
|
7
|
+
from codex.serializers.admin.stats import APIKeySerializer
|
|
8
8
|
from codex.views.admin.auth import AdminGenericAPIView
|
|
9
9
|
|
|
10
10
|
|
codex/views/admin/flag.py
CHANGED
|
@@ -5,7 +5,7 @@ from codex.librarian.notifier.tasks import LIBRARY_CHANGED_TASK
|
|
|
5
5
|
from codex.logger.logging import get_logger
|
|
6
6
|
from codex.models import AdminFlag
|
|
7
7
|
from codex.registration import patch_registration_setting
|
|
8
|
-
from codex.serializers.admin import AdminFlagSerializer
|
|
8
|
+
from codex.serializers.admin.flags import AdminFlagSerializer
|
|
9
9
|
from codex.views.admin.auth import AdminModelViewSet
|
|
10
10
|
|
|
11
11
|
LOG = get_logger(__name__)
|
codex/views/admin/group.py
CHANGED
|
@@ -6,7 +6,7 @@ from django.core.cache import cache
|
|
|
6
6
|
from codex.librarian.mp_queue import LIBRARIAN_QUEUE
|
|
7
7
|
from codex.librarian.notifier.tasks import LIBRARY_CHANGED_TASK
|
|
8
8
|
from codex.logger.logging import get_logger
|
|
9
|
-
from codex.serializers.admin import GroupSerializer
|
|
9
|
+
from codex.serializers.admin.groups import GroupSerializer
|
|
10
10
|
from codex.views.admin.auth import AdminModelViewSet
|
|
11
11
|
|
|
12
12
|
LOG = get_logger(__name__)
|
codex/views/admin/library.py
CHANGED
|
@@ -18,7 +18,7 @@ from codex.librarian.watchdog.tasks import (
|
|
|
18
18
|
)
|
|
19
19
|
from codex.logger.logging import get_logger
|
|
20
20
|
from codex.models import FailedImport, Folder, Library
|
|
21
|
-
from codex.serializers.admin import (
|
|
21
|
+
from codex.serializers.admin.libraries import (
|
|
22
22
|
AdminFolderListSerializer,
|
|
23
23
|
AdminFolderSerializer,
|
|
24
24
|
FailedImportSerializer,
|
codex/views/admin/stats.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Admin Flag View."""
|
|
2
2
|
|
|
3
|
+
from multiprocessing import cpu_count
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from platform import machine, python_version, release, system
|
|
5
6
|
from types import MappingProxyType
|
|
@@ -18,10 +19,14 @@ from codex.models import (
|
|
|
18
19
|
Timestamp,
|
|
19
20
|
)
|
|
20
21
|
from codex.permissions import HasAPIKeyOrIsAdminUser
|
|
21
|
-
from codex.serializers.admin import
|
|
22
|
+
from codex.serializers.admin.stats import (
|
|
23
|
+
AdminStatsRequestSerializer,
|
|
24
|
+
AdminStatsSerializer,
|
|
25
|
+
)
|
|
22
26
|
from codex.version import VERSION
|
|
23
27
|
from codex.views.admin.auth import AdminGenericAPIView
|
|
24
28
|
from codex.views.const import CONFIG_MODELS, METADATA_MODELS, STATS_GROUP_MODELS
|
|
29
|
+
from codex.views.session import SessionView
|
|
25
30
|
|
|
26
31
|
LOG = get_logger(__name__)
|
|
27
32
|
_KEY_MODELS_MAP = MappingProxyType(
|
|
@@ -33,6 +38,16 @@ _KEY_MODELS_MAP = MappingProxyType(
|
|
|
33
38
|
)
|
|
34
39
|
_DOCKERENV_PATH = Path("/.dockerenv")
|
|
35
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
|
+
)
|
|
36
51
|
|
|
37
52
|
|
|
38
53
|
class AdminStatsView(AdminGenericAPIView):
|
|
@@ -94,22 +109,39 @@ class AdminStatsView(AdminGenericAPIView):
|
|
|
94
109
|
return obj
|
|
95
110
|
|
|
96
111
|
@staticmethod
|
|
97
|
-
def
|
|
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):
|
|
98
126
|
"""Return the number of anonymous sessions."""
|
|
99
127
|
sessions = Session.objects.all()
|
|
100
|
-
|
|
128
|
+
anon_session_count = 0
|
|
129
|
+
user_stats = {}
|
|
101
130
|
for encoded_session in sessions:
|
|
102
131
|
session = encoded_session.get_decoded()
|
|
103
132
|
if not session.get("_auth_user_id"):
|
|
104
|
-
|
|
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)
|
|
105
136
|
|
|
106
|
-
return
|
|
137
|
+
return user_stats, anon_session_count
|
|
107
138
|
|
|
108
139
|
def _get_platform(self, obj):
|
|
109
140
|
"""Add dict of platform information to object."""
|
|
110
141
|
platform = {
|
|
111
142
|
"docker": self._is_docker(),
|
|
112
143
|
"machine": machine(),
|
|
144
|
+
"cores": cpu_count(),
|
|
113
145
|
"system": system(),
|
|
114
146
|
"system_release": release(),
|
|
115
147
|
"python": python_version(),
|
|
@@ -121,13 +153,15 @@ class AdminStatsView(AdminGenericAPIView):
|
|
|
121
153
|
"""Add dict of config informaation to object."""
|
|
122
154
|
config = self._get_model_counts("config")
|
|
123
155
|
request_counts = self._get_request_counts("config")
|
|
124
|
-
|
|
125
|
-
config["sessions_anon_count"] = self._get_anon_sessions()
|
|
156
|
+
sessions, config["anonymous_users_count"] = self._get_session_stats()
|
|
126
157
|
if not request_counts or "apikey" in request_counts:
|
|
127
158
|
config["api_key"] = Timestamp.objects.get(
|
|
128
159
|
key=Timestamp.TimestampChoices.API_KEY.value
|
|
129
160
|
).version
|
|
161
|
+
config["registered_users_count"] = config.pop("users_count", 0)
|
|
162
|
+
config["user_groups_count"] = config.pop("groups_count", 0)
|
|
130
163
|
obj["config"] = config
|
|
164
|
+
obj["sessions"] = sessions
|
|
131
165
|
|
|
132
166
|
def _get_file_types(self):
|
|
133
167
|
"""Query for file types."""
|
codex/views/admin/tasks.py
CHANGED
|
@@ -44,7 +44,7 @@ from codex.librarian.watchdog.tasks import (
|
|
|
44
44
|
)
|
|
45
45
|
from codex.logger.logging import get_logger
|
|
46
46
|
from codex.models import LibrarianStatus
|
|
47
|
-
from codex.serializers.admin import AdminLibrarianTaskSerializer
|
|
47
|
+
from codex.serializers.admin.tasks import AdminLibrarianTaskSerializer
|
|
48
48
|
from codex.serializers.mixins import OKSerializer
|
|
49
49
|
from codex.serializers.models.admin import LibrarianStatusSerializer
|
|
50
50
|
from codex.views.admin.auth import AdminAPIView, AdminReadOnlyModelViewSet
|
codex/views/admin/user.py
CHANGED
|
@@ -10,7 +10,7 @@ from rest_framework.status import HTTP_202_ACCEPTED, HTTP_400_BAD_REQUEST
|
|
|
10
10
|
from codex.librarian.mp_queue import LIBRARIAN_QUEUE
|
|
11
11
|
from codex.librarian.notifier.tasks import LIBRARY_CHANGED_TASK
|
|
12
12
|
from codex.logger.logging import get_logger
|
|
13
|
-
from codex.serializers.admin import UserChangePasswordSerializer, UserSerializer
|
|
13
|
+
from codex.serializers.admin.users import UserChangePasswordSerializer, UserSerializer
|
|
14
14
|
from codex.views.admin.auth import AdminGenericAPIView, AdminModelViewSet
|
|
15
15
|
|
|
16
16
|
LOG = get_logger(__name__)
|
|
@@ -27,6 +27,7 @@ from codex.models import (
|
|
|
27
27
|
Volume,
|
|
28
28
|
)
|
|
29
29
|
from codex.models.functions import JsonGroupArray
|
|
30
|
+
from codex.models.groups import Imprint, Publisher, Series
|
|
30
31
|
from codex.views.browser.order_by import (
|
|
31
32
|
BrowserOrderByView,
|
|
32
33
|
)
|
|
@@ -60,8 +61,8 @@ _ANNOTATED_ORDER_FIELDS = frozenset(
|
|
|
60
61
|
"story_arc_number",
|
|
61
62
|
}
|
|
62
63
|
)
|
|
63
|
-
|
|
64
|
-
{
|
|
64
|
+
_GROUP_BY: MappingProxyType[type[BrowserGroupModel], str] = MappingProxyType(
|
|
65
|
+
{Publisher: "sort_name", Imprint: "sort_name", Series: "sort_name", Volume: "name"}
|
|
65
66
|
)
|
|
66
67
|
|
|
67
68
|
LOG = get_logger(__name__)
|
|
@@ -77,11 +78,13 @@ class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
|
|
|
77
78
|
self.comic_sort_names = ()
|
|
78
79
|
self.bm_annotataion_data: dict[BrowserGroupModel, tuple[str, dict]] = {}
|
|
79
80
|
|
|
80
|
-
def
|
|
81
|
+
def add_group_by(self, qs, model=None):
|
|
81
82
|
"""Get the group by for the model."""
|
|
82
83
|
if model is None:
|
|
83
84
|
model = self.model
|
|
84
|
-
|
|
85
|
+
if group_by := _GROUP_BY.get(model): # type: ignore
|
|
86
|
+
qs = qs.group_by(group_by)
|
|
87
|
+
return qs
|
|
85
88
|
|
|
86
89
|
def _alias_sort_names(self, qs, model):
|
|
87
90
|
"""Annotate sort_name."""
|
codex/views/browser/browser.py
CHANGED
|
@@ -81,7 +81,10 @@ class BrowserView(BrowserTitleView):
|
|
|
81
81
|
self.group_query = self.group_class.objects.none()
|
|
82
82
|
else:
|
|
83
83
|
reason = f"{group}__in={pks} does not exist!"
|
|
84
|
-
|
|
84
|
+
settings_mask = {"breadcrumbs": []}
|
|
85
|
+
self.raise_redirect(
|
|
86
|
+
reason, route_mask={"group": group}, settings_mask=settings_mask
|
|
87
|
+
)
|
|
85
88
|
elif self.group_class:
|
|
86
89
|
self.group_query = self.group_class.objects.none()
|
|
87
90
|
else:
|
|
@@ -115,8 +118,9 @@ class BrowserView(BrowserTitleView):
|
|
|
115
118
|
def _get_common_queryset(self, model):
|
|
116
119
|
"""Create queryset common to group & books."""
|
|
117
120
|
qs = self.get_filtered_queryset(model)
|
|
118
|
-
|
|
119
|
-
count =
|
|
121
|
+
count_qs = self.add_group_by(qs, model)
|
|
122
|
+
count = count_qs.count()
|
|
123
|
+
|
|
120
124
|
if count:
|
|
121
125
|
qs = self.annotate_order_aggregates(qs, model)
|
|
122
126
|
qs = self.add_order_by(qs, model)
|
|
@@ -137,8 +141,7 @@ class BrowserView(BrowserTitleView):
|
|
|
137
141
|
count = 0
|
|
138
142
|
else:
|
|
139
143
|
qs, count = self._get_common_queryset(self.model)
|
|
140
|
-
|
|
141
|
-
qs = qs.group_by(group_by)
|
|
144
|
+
qs = self.add_group_by(qs)
|
|
142
145
|
return qs, count
|
|
143
146
|
|
|
144
147
|
def _get_book_queryset(self):
|
codex/views/browser/cover.py
CHANGED
|
@@ -102,8 +102,6 @@ class CoverView(BrowserAnnotationsView):
|
|
|
102
102
|
comic_qs = self.annotate_order_aggregates(comic_qs, Comic)
|
|
103
103
|
comic_qs = self.add_order_by(comic_qs, Comic)
|
|
104
104
|
comic_qs = comic_qs.only("pk")
|
|
105
|
-
group_by = self.get_group_by(Comic)
|
|
106
|
-
comic_qs.group_by(group_by)
|
|
107
105
|
comic = comic_qs.first()
|
|
108
106
|
cover_pk = comic.pk if comic else 0
|
|
109
107
|
return cover_pk, False
|
|
@@ -18,9 +18,9 @@ _FILTER_REL_MAP = MappingProxyType(
|
|
|
18
18
|
class ComicFieldFilterView(GroupFilterView):
|
|
19
19
|
"""Comic field filters."""
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
@staticmethod
|
|
22
|
+
def _filter_by_comic_field(field, rel_prefix, filter_list):
|
|
22
23
|
"""Filter by a comic any2many attribute."""
|
|
23
|
-
filter_list = self.params["filters"].get(field) # type: ignore
|
|
24
24
|
filter_query = Q()
|
|
25
25
|
if not filter_list:
|
|
26
26
|
return filter_query
|
|
@@ -36,10 +36,19 @@ class ComicFieldFilterView(GroupFilterView):
|
|
|
36
36
|
filter_query |= Q(**{f"{rel}__in": filter_list})
|
|
37
37
|
return filter_query
|
|
38
38
|
|
|
39
|
+
@classmethod
|
|
40
|
+
def get_all_comic_field_filters(cls, rel_prefix, filters):
|
|
41
|
+
"""Get all comicfiled filters for rel_prefix."""
|
|
42
|
+
comic_field_filter = Q()
|
|
43
|
+
for field in cls.FILTER_ATTRIBUTES:
|
|
44
|
+
filter_list = filters.get(field, [])
|
|
45
|
+
comic_field_filter &= cls._filter_by_comic_field(
|
|
46
|
+
field, rel_prefix, filter_list
|
|
47
|
+
)
|
|
48
|
+
return comic_field_filter
|
|
49
|
+
|
|
39
50
|
def get_comic_field_filter(self, model):
|
|
40
51
|
"""Filter the comics based on the form filters."""
|
|
41
|
-
comic_field_filter = Q()
|
|
42
52
|
rel_prefix = self.get_rel_prefix(model)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return comic_field_filter
|
|
53
|
+
filters = self.params["filters"] # type: ignore
|
|
54
|
+
return self.get_all_comic_field_filters(rel_prefix, filters)
|
codex/views/browser/metadata.py
CHANGED
|
@@ -116,13 +116,11 @@ class MetadataView(BrowserAnnotationsView):
|
|
|
116
116
|
else:
|
|
117
117
|
# group_by makes the filter work, but prevents its
|
|
118
118
|
# use as a subquery in the big query.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
.values_list(full_field + related_suffix, flat=True)
|
|
125
|
-
)
|
|
119
|
+
sq = filtered_qs.alias(
|
|
120
|
+
filter_count=Count(full_field, distinct=True)
|
|
121
|
+
).filter(filter_count=1)
|
|
122
|
+
sq = self.add_group_by(sq)
|
|
123
|
+
sq = sq.values_list(full_field + related_suffix, flat=True)
|
|
126
124
|
try:
|
|
127
125
|
val = sq[0]
|
|
128
126
|
except IndexError:
|
|
@@ -307,8 +305,7 @@ class MetadataView(BrowserAnnotationsView):
|
|
|
307
305
|
qs = self.annotate_order_aggregates(qs, self.model)
|
|
308
306
|
qs = self.annotate_card_aggregates(qs, self.model)
|
|
309
307
|
qs = self._annotate_values_and_fks(qs, filtered_qs)
|
|
310
|
-
|
|
311
|
-
qs = qs.group_by(group_by)
|
|
308
|
+
qs = self.add_group_by(qs)
|
|
312
309
|
|
|
313
310
|
try:
|
|
314
311
|
obj = qs[0]
|
codex/views/browser/paginate.py
CHANGED
|
@@ -13,6 +13,7 @@ from codex.views.browser.annotations import BrowserAnnotationsView
|
|
|
13
13
|
from codex.views.const import (
|
|
14
14
|
MAX_OBJ_PER_PAGE,
|
|
15
15
|
)
|
|
16
|
+
from codex.views.util import Route
|
|
16
17
|
|
|
17
18
|
LOG = get_logger(__name__)
|
|
18
19
|
|
|
@@ -20,30 +21,79 @@ LOG = get_logger(__name__)
|
|
|
20
21
|
class BrowserPaginateView(BrowserAnnotationsView):
|
|
21
22
|
"""Browser pagination."""
|
|
22
23
|
|
|
24
|
+
def _get_back_one_page_route(self, num_pages):
|
|
25
|
+
"""Get max page if oob or 1."""
|
|
26
|
+
LOG.debug("Redirect back one page.")
|
|
27
|
+
group = self.kwargs.get("group")
|
|
28
|
+
pks = self.kwargs.get("pks")
|
|
29
|
+
page = self.kwargs.get("page", 1)
|
|
30
|
+
new_page = num_pages if num_pages and page > num_pages else 1
|
|
31
|
+
pks = pks if pks else "0"
|
|
32
|
+
return {"group": group, "pks": pks, "page": new_page}
|
|
33
|
+
|
|
34
|
+
def _get_up_breadcrumbs(self):
|
|
35
|
+
"""Walk up the breadcrumbs to get the next level up."""
|
|
36
|
+
breadcrumbs = self.params.get("breadcrumbs", [])
|
|
37
|
+
new_breadcrumbs = []
|
|
38
|
+
level = False
|
|
39
|
+
group = self.kwargs.get("group")
|
|
40
|
+
pks = self.kwargs.get("pks")
|
|
41
|
+
page = self.kwargs.get("page", 1)
|
|
42
|
+
current_route = Route(group=group, pks=pks, page=page)
|
|
43
|
+
for crumb in reversed(breadcrumbs):
|
|
44
|
+
if not level:
|
|
45
|
+
crumb_route = Route(**crumb)
|
|
46
|
+
level = current_route & crumb_route
|
|
47
|
+
continue
|
|
48
|
+
new_breadcrumbs = [crumb, *new_breadcrumbs]
|
|
49
|
+
|
|
50
|
+
if not new_breadcrumbs:
|
|
51
|
+
if group not in ("f", "a"):
|
|
52
|
+
group = "r"
|
|
53
|
+
top_route = {"group": group, "pks": (), "page": 1}
|
|
54
|
+
new_breadcrumbs = [top_route]
|
|
55
|
+
return new_breadcrumbs
|
|
56
|
+
|
|
57
|
+
def _get_up_page_redirect(self):
|
|
58
|
+
"""Walk up the breadcrumbs."""
|
|
59
|
+
try:
|
|
60
|
+
up_breadcrumbs = self._get_up_breadcrumbs()
|
|
61
|
+
route_mask = up_breadcrumbs[-1]
|
|
62
|
+
settings_mask = {"breadcrumbs": up_breadcrumbs}
|
|
63
|
+
LOG.debug("Redirect up a level.")
|
|
64
|
+
except IndexError:
|
|
65
|
+
group = self.kwargs.get("group")
|
|
66
|
+
pks = "0"
|
|
67
|
+
new_page = 1
|
|
68
|
+
route_mask = {"group": group, "pks": pks, "page": new_page}
|
|
69
|
+
settings_mask = {"breadcrumbs": [route_mask]}
|
|
70
|
+
LOG.debug("Redirect to all at current group.")
|
|
71
|
+
return route_mask, settings_mask
|
|
72
|
+
|
|
23
73
|
def _check_page_in_bounds(self, total_count):
|
|
24
74
|
"""Redirect page out of bounds."""
|
|
25
75
|
pks = self.kwargs.get("pks")
|
|
26
76
|
page = self.kwargs.get("page", 1)
|
|
27
77
|
num_pages = ceil(total_count / MAX_OBJ_PER_PAGE)
|
|
28
|
-
if
|
|
78
|
+
if page == 1 or (page >= 1 and page <= num_pages):
|
|
29
79
|
# Don't redirect if on the root page for the group.
|
|
30
80
|
# Or page within valid range.
|
|
31
81
|
return num_pages
|
|
32
82
|
|
|
33
|
-
# Adjust route mask for redirect
|
|
34
83
|
group = self.kwargs.get("group")
|
|
84
|
+
reason = f"{group=} {pks=} {page=} does not exist."
|
|
85
|
+
|
|
86
|
+
# Adjust route mask for redirect
|
|
35
87
|
if num_pages and page > 1:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
pks = pks if pks else "0"
|
|
88
|
+
route_mask = self._get_back_one_page_route(num_pages)
|
|
89
|
+
settings_mask = None
|
|
39
90
|
else:
|
|
40
|
-
#
|
|
41
|
-
|
|
42
|
-
new_page = 1
|
|
91
|
+
# This now only occurs when page < 1
|
|
92
|
+
route_mask, settings_mask = self._get_up_page_redirect()
|
|
43
93
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
94
|
+
return self.raise_redirect(
|
|
95
|
+
reason, route_mask=route_mask, settings_mask=settings_mask
|
|
96
|
+
)
|
|
47
97
|
|
|
48
98
|
def _paginate_section(self, model, qs, page):
|
|
49
99
|
"""Paginate a group or Comic section."""
|
codex/views/browser/validate.py
CHANGED
|
@@ -15,7 +15,6 @@ from codex.views.const import (
|
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
LOG = get_logger(__name__)
|
|
18
|
-
_NO_TOP_GROUP_VALIDATE = frozenset({"metadata"})
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
class BrowserValidateView(BrowserBaseView):
|
|
@@ -56,8 +55,6 @@ class BrowserValidateView(BrowserBaseView):
|
|
|
56
55
|
return valid_top_groups
|
|
57
56
|
|
|
58
57
|
def _validate_top_group(self, valid_top_groups):
|
|
59
|
-
# if self.TARGET in _NO_TOP_GROUP_VALIDATE:
|
|
60
|
-
# return
|
|
61
58
|
nav_group = self.kwargs.get("group")
|
|
62
59
|
top_group = self.params.get("top_group")
|
|
63
60
|
if top_group not in valid_top_groups:
|
|
@@ -72,7 +69,8 @@ class BrowserValidateView(BrowserBaseView):
|
|
|
72
69
|
pks = self.kwargs.get("pks", ())
|
|
73
70
|
page = self.kwargs["page"]
|
|
74
71
|
route = {"group": nav_group, "pks": pks, "page": page}
|
|
75
|
-
|
|
72
|
+
breadcrumbs = []
|
|
73
|
+
settings_mask = {"top_group": valid_top_group, "breadcrumbs": breadcrumbs}
|
|
76
74
|
self.raise_redirect(reason, route, settings_mask)
|
|
77
75
|
|
|
78
76
|
def set_valid_browse_nav_groups(self, valid_top_groups):
|
|
@@ -109,7 +107,11 @@ class BrowserValidateView(BrowserBaseView):
|
|
|
109
107
|
if not self.admin_flags["folder_view"]:
|
|
110
108
|
reason = "folder view disabled"
|
|
111
109
|
valid_top_groups = self._get_valid_browse_top_groups()
|
|
112
|
-
|
|
110
|
+
breadcrumbs = []
|
|
111
|
+
settings_mask = {
|
|
112
|
+
"top_group": valid_top_groups[0],
|
|
113
|
+
"breadcrumbs": breadcrumbs,
|
|
114
|
+
}
|
|
113
115
|
self.raise_redirect(reason, settings_mask=settings_mask)
|
|
114
116
|
|
|
115
117
|
valid_top_groups = (FOLDER_GROUP,)
|
codex/views/opds/binary.py
CHANGED
|
@@ -6,11 +6,9 @@ from codex.views.opds.auth import OPDSAuthMixin
|
|
|
6
6
|
from codex.views.reader.page import ReaderPageView
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class OPDSCoverView(CoverView):
|
|
9
|
+
class OPDSCoverView(OPDSAuthMixin, CoverView):
|
|
10
10
|
"""Cover View with Basic Auth."""
|
|
11
11
|
|
|
12
|
-
# Panels sometimes doesn't send auth with cover requests.
|
|
13
|
-
|
|
14
12
|
|
|
15
13
|
class OPDSDownloadView(OPDSAuthMixin, DownloadView):
|
|
16
14
|
"""Download View with Basic Auth."""
|
codex/views/opds/const.py
CHANGED
|
@@ -84,3 +84,13 @@ class MimeType:
|
|
|
84
84
|
|
|
85
85
|
|
|
86
86
|
OPDS_M2M_MODELS = (Character, Genre, Location, SeriesGroup, StoryArc, Tag, Team)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class UserAgentNames:
|
|
90
|
+
"""Control whether to hack in facets with nav links."""
|
|
91
|
+
|
|
92
|
+
CLIENT_REORDERS = frozenset({"Chunky"})
|
|
93
|
+
FACET_SUPPORT = frozenset({"yar"}) # kybooks
|
|
94
|
+
SIMPLE_DOWNLOAD_MIME_TYPES = frozenset({"PocketBook Reader"})
|
|
95
|
+
# Other known valid names:
|
|
96
|
+
# "Chunky"
|
codex/views/opds/util.py
CHANGED
|
@@ -93,3 +93,13 @@ def full_redirect_view(url_name):
|
|
|
93
93
|
return response
|
|
94
94
|
|
|
95
95
|
return func
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def get_user_agent_name(request):
|
|
99
|
+
"""Get the first part of the user agent."""
|
|
100
|
+
user_agent_name = ""
|
|
101
|
+
if (user_agent := request.headers.get("User-Agent")) and (
|
|
102
|
+
user_agent_parts := user_agent.split("/", 1)
|
|
103
|
+
):
|
|
104
|
+
user_agent_name = user_agent_parts[0]
|
|
105
|
+
return user_agent_name
|
codex/views/opds/v1/feed.py
CHANGED
|
@@ -17,7 +17,8 @@ from codex.serializers.opds.v1 import (
|
|
|
17
17
|
)
|
|
18
18
|
from codex.views.const import FALSY, MAX_OBJ_PER_PAGE
|
|
19
19
|
from codex.views.opds.auth import OPDSTemplateView
|
|
20
|
-
from codex.views.opds.const import BLANK_TITLE, MimeType
|
|
20
|
+
from codex.views.opds.const import BLANK_TITLE, MimeType, UserAgentNames
|
|
21
|
+
from codex.views.opds.util import get_user_agent_name
|
|
21
22
|
from codex.views.opds.v1.entry.data import OPDS1EntryData
|
|
22
23
|
from codex.views.opds.v1.entry.entry import OPDS1Entry
|
|
23
24
|
from codex.views.opds.v1.links import (
|
|
@@ -41,16 +42,6 @@ class OpdsNs:
|
|
|
41
42
|
ACQUISITION = "http://opds-spec.org/2010/acquisition"
|
|
42
43
|
|
|
43
44
|
|
|
44
|
-
class UserAgentNames:
|
|
45
|
-
"""Control whether to hack in facets with nav links."""
|
|
46
|
-
|
|
47
|
-
CLIENT_REORDERS = frozenset({"Chunky"})
|
|
48
|
-
FACET_SUPPORT = frozenset({"yar"}) # kybooks
|
|
49
|
-
SIMPLE_DOWNLOAD_MIME_TYPES = frozenset({"PocketBook Reader"})
|
|
50
|
-
# Other known valid names:
|
|
51
|
-
# "Panels", "Chunky"
|
|
52
|
-
|
|
53
|
-
|
|
54
45
|
class OPDS1FeedView(OPDS1LinksView, OPDSTemplateView):
|
|
55
46
|
"""OPDS 1 Feed."""
|
|
56
47
|
|
|
@@ -218,19 +209,10 @@ class OPDS1FeedView(OPDS1LinksView, OPDSTemplateView):
|
|
|
218
209
|
|
|
219
210
|
def _set_user_agent_variables(self):
|
|
220
211
|
"""Set User Agent variables."""
|
|
221
|
-
|
|
222
|
-
if not user_agent:
|
|
223
|
-
return
|
|
224
|
-
user_agent_parts = user_agent.split("/", 1)
|
|
225
|
-
if user_agent_parts:
|
|
226
|
-
user_agent_name = user_agent_parts[0]
|
|
227
|
-
else:
|
|
228
|
-
return
|
|
212
|
+
user_agent_name = get_user_agent_name(self.request)
|
|
229
213
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if user_agent_name in UserAgentNames.CLIENT_REORDERS:
|
|
233
|
-
self.skip_order_facets = True
|
|
214
|
+
self.user_facets = user_agent_name in UserAgentNames.FACET_SUPPORT
|
|
215
|
+
self.skip_order_facets = user_agent_name in UserAgentNames.CLIENT_REORDERS
|
|
234
216
|
if user_agent_name in UserAgentNames.SIMPLE_DOWNLOAD_MIME_TYPES:
|
|
235
217
|
self.mime_type_map = MimeType.SIMPLE_FILE_TYPE_MAP
|
|
236
218
|
|