codex 1.6.0__py3-none-any.whl → 1.6.0a1__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 +18 -22
- codex/integrity.py +3 -66
- codex/librarian/covers/coverd.py +2 -2
- codex/librarian/covers/create.py +29 -50
- codex/librarian/covers/path.py +6 -8
- codex/librarian/covers/purge.py +18 -28
- codex/librarian/covers/tasks.py +2 -3
- codex/librarian/importer/{aggregate.py → aggregate_metadata.py} +88 -58
- codex/librarian/importer/{extract.py → clean_metadata.py} +4 -33
- codex/librarian/importer/const.py +13 -46
- codex/librarian/importer/create_comics.py +17 -101
- codex/librarian/importer/create_fks.py +134 -99
- codex/librarian/importer/deleted.py +28 -103
- codex/librarian/importer/failed_imports.py +64 -42
- codex/librarian/importer/importerd.py +290 -71
- codex/librarian/importer/link_comics.py +26 -26
- codex/librarian/importer/moved.py +81 -128
- codex/librarian/importer/query_fks.py +122 -142
- codex/librarian/importer/status.py +39 -8
- codex/librarian/importer/tasks.py +9 -26
- codex/librarian/importer/update_comics.py +89 -0
- codex/librarian/janitor/cleanup.py +2 -26
- codex/librarian/janitor/failed_imports.py +1 -1
- codex/librarian/janitor/janitor.py +1 -13
- codex/librarian/janitor/janitord.py +1 -1
- codex/librarian/janitor/status.py +0 -1
- codex/librarian/janitor/tasks.py +0 -5
- codex/librarian/librariand.py +5 -9
- codex/librarian/notifier/notifierd.py +1 -1
- codex/librarian/notifier/tasks.py +4 -4
- codex/librarian/search/update.py +1 -1
- codex/librarian/watchdog/db_snapshot.py +6 -9
- codex/librarian/watchdog/emitter.py +0 -3
- codex/librarian/watchdog/event_batcherd.py +3 -19
- codex/librarian/watchdog/events.py +36 -176
- codex/librarian/watchdog/observers.py +3 -13
- codex/middleware.py +2 -1
- codex/migrations/0027_sort_name.py +149 -0
- codex/models/admin.py +2 -0
- codex/models/base.py +0 -3
- codex/models/comic.py +9 -13
- codex/models/{util.py → const.py} +2 -15
- codex/models/groups.py +14 -28
- codex/models/library.py +3 -11
- codex/models/paths.py +14 -61
- codex/permissions.py +1 -1
- codex/search/query.py +2 -25
- codex/search/writing.py +1 -1
- codex/serializers/admin.py +44 -53
- codex/serializers/browser/choices.py +42 -37
- codex/serializers/browser/filters.py +131 -32
- codex/serializers/browser/metadata.py +1 -45
- codex/serializers/browser/mixins.py +4 -37
- codex/serializers/browser/page.py +6 -3
- codex/serializers/browser/settings.py +11 -42
- codex/serializers/choices.py +1 -14
- codex/serializers/models/pycountry.py +51 -11
- codex/serializers/opds/v2.py +16 -10
- codex/serializers/opds/v2_unused.py +3 -5
- codex/serializers/reader.py +7 -21
- codex/serializers/redirect.py +2 -3
- codex/serializers/route.py +7 -16
- codex/settings/settings.py +8 -23
- codex/startup.py +3 -77
- codex/static_root/assets/VCheckbox-u_aWQJA7.a0db8a7bd681.js +1 -0
- codex/static_root/assets/VCheckbox-u_aWQJA7.a0db8a7bd681.js.br +0 -0
- codex/static_root/assets/VCheckbox-u_aWQJA7.a0db8a7bd681.js.gz +0 -0
- codex/static_root/assets/VCheckbox-u_aWQJA7.js +1 -0
- codex/static_root/assets/VCheckbox-u_aWQJA7.js.br +0 -0
- codex/static_root/assets/VCheckbox-u_aWQJA7.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-DxNOKONG.5ab34c4c47aa.js → VCheckboxBtn-yCN3TB6A.29d48d14ab3b.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-yCN3TB6A.29d48d14ab3b.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-yCN3TB6A.29d48d14ab3b.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-DxNOKONG.js → VCheckboxBtn-yCN3TB6A.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-yCN3TB6A.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-yCN3TB6A.js.gz +0 -0
- codex/static_root/assets/VCombobox-dsIKbjps.d3c8da1d75b3.js +1 -0
- codex/static_root/assets/VCombobox-dsIKbjps.d3c8da1d75b3.js.br +0 -0
- codex/static_root/assets/VCombobox-dsIKbjps.d3c8da1d75b3.js.gz +0 -0
- codex/static_root/assets/VCombobox-dsIKbjps.js +1 -0
- codex/static_root/assets/VCombobox-dsIKbjps.js.br +0 -0
- codex/static_root/assets/VCombobox-dsIKbjps.js.gz +0 -0
- codex/static_root/assets/VDialog-BNHg8txZ.21bed7754d3a.js +1 -0
- codex/static_root/assets/VDialog-BNHg8txZ.21bed7754d3a.js.br +0 -0
- codex/static_root/assets/VDialog-BNHg8txZ.21bed7754d3a.js.gz +0 -0
- codex/static_root/assets/VDialog-BNHg8txZ.js +1 -0
- codex/static_root/assets/VDialog-BNHg8txZ.js.br +0 -0
- codex/static_root/assets/VDialog-BNHg8txZ.js.gz +0 -0
- codex/static_root/assets/{VDialog-lQ13FnRR.1c801ad756b2.css → VDialog-C5Nxd_zP.css} +1 -1
- codex/static_root/assets/VDialog-C5Nxd_zP.css.br +0 -0
- codex/static_root/assets/VDialog-C5Nxd_zP.css.gz +0 -0
- codex/static_root/assets/{VDialog-lQ13FnRR.css → VDialog-C5Nxd_zP.d327f505ef0e.css} +1 -1
- codex/static_root/assets/VDialog-C5Nxd_zP.d327f505ef0e.css.br +0 -0
- codex/static_root/assets/VDialog-C5Nxd_zP.d327f505ef0e.css.gz +0 -0
- codex/static_root/assets/VExpansionPanels-CX4W4vZK.8e90fe0b34f4.js +1 -0
- codex/static_root/assets/VExpansionPanels-CX4W4vZK.8e90fe0b34f4.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-CX4W4vZK.8e90fe0b34f4.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-CX4W4vZK.js +1 -0
- codex/static_root/assets/VExpansionPanels-CX4W4vZK.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-CX4W4vZK.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-jCr3CAsk.685daccd04d8.js +1 -0
- codex/static_root/assets/VRadioGroup-jCr3CAsk.685daccd04d8.js.br +0 -0
- codex/static_root/assets/VRadioGroup-jCr3CAsk.685daccd04d8.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-jCr3CAsk.js +1 -0
- codex/static_root/assets/VRadioGroup-jCr3CAsk.js.br +0 -0
- codex/static_root/assets/VRadioGroup-jCr3CAsk.js.gz +0 -0
- codex/static_root/assets/VSelect--XHNpxvB.ff050ef0d6de.js +1 -0
- codex/static_root/assets/VSelect--XHNpxvB.ff050ef0d6de.js.br +0 -0
- codex/static_root/assets/VSelect--XHNpxvB.ff050ef0d6de.js.gz +0 -0
- codex/static_root/assets/VSelect--XHNpxvB.js +1 -0
- codex/static_root/assets/VSelect--XHNpxvB.js.br +0 -0
- codex/static_root/assets/VSelect--XHNpxvB.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-CVIKc_ra.0b2cc426e8b8.js +1 -0
- codex/static_root/assets/VSelectionControl-CVIKc_ra.0b2cc426e8b8.js.br +0 -0
- codex/static_root/assets/VSelectionControl-CVIKc_ra.0b2cc426e8b8.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-CVIKc_ra.js +1 -0
- codex/static_root/assets/VSelectionControl-CVIKc_ra.js.br +0 -0
- codex/static_root/assets/VSelectionControl-CVIKc_ra.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-CZw5_eNv.7ae5182e5988.js +1 -0
- codex/static_root/assets/VSlideGroup-CZw5_eNv.7ae5182e5988.js.br +0 -0
- codex/static_root/assets/VSlideGroup-CZw5_eNv.7ae5182e5988.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-CZw5_eNv.js +1 -0
- codex/static_root/assets/VSlideGroup-CZw5_eNv.js.br +0 -0
- codex/static_root/assets/VSlideGroup-CZw5_eNv.js.gz +0 -0
- codex/static_root/assets/{VTable-2RHFqfg6.f0f2106b158b.js → VTable-hGJDFK5t.d2f84d68747b.js} +1 -1
- codex/static_root/assets/VTable-hGJDFK5t.d2f84d68747b.js.br +0 -0
- codex/static_root/assets/VTable-hGJDFK5t.d2f84d68747b.js.gz +0 -0
- codex/static_root/assets/{VTable-2RHFqfg6.js → VTable-hGJDFK5t.js} +1 -1
- codex/static_root/assets/VTable-hGJDFK5t.js.br +0 -0
- codex/static_root/assets/VTable-hGJDFK5t.js.gz +0 -0
- codex/static_root/assets/VTextField-C8y3lyz9.eb58405614ad.js +1 -0
- codex/static_root/assets/VTextField-C8y3lyz9.eb58405614ad.js.br +0 -0
- codex/static_root/assets/VTextField-C8y3lyz9.eb58405614ad.js.gz +0 -0
- codex/static_root/assets/VTextField-C8y3lyz9.js +1 -0
- codex/static_root/assets/VTextField-C8y3lyz9.js.br +0 -0
- codex/static_root/assets/VTextField-C8y3lyz9.js.gz +0 -0
- codex/static_root/assets/VTextField-DuIIp-VY.580110ad24dc.css +1 -0
- codex/static_root/assets/VTextField-DuIIp-VY.580110ad24dc.css.br +0 -0
- codex/static_root/assets/VTextField-DuIIp-VY.580110ad24dc.css.gz +0 -0
- codex/static_root/assets/VTextField-DuIIp-VY.css +1 -0
- codex/static_root/assets/VTextField-DuIIp-VY.css.br +0 -0
- codex/static_root/assets/VTextField-DuIIp-VY.css.gz +0 -0
- codex/static_root/assets/VWindowItem-BHpZIa_r.2b3c5f9594e6.js +1 -0
- codex/static_root/assets/VWindowItem-BHpZIa_r.2b3c5f9594e6.js.br +0 -0
- codex/static_root/assets/VWindowItem-BHpZIa_r.2b3c5f9594e6.js.gz +0 -0
- codex/static_root/assets/VWindowItem-BHpZIa_r.js +1 -0
- codex/static_root/assets/VWindowItem-BHpZIa_r.js.br +0 -0
- codex/static_root/assets/VWindowItem-BHpZIa_r.js.gz +0 -0
- codex/static_root/assets/{admin-B8Bp2Uih.82c98714bcf1.css → admin-BbrOU9Y9.29936748af9e.css} +1 -1
- codex/static_root/assets/admin-BbrOU9Y9.29936748af9e.css.br +0 -0
- codex/static_root/assets/admin-BbrOU9Y9.29936748af9e.css.gz +0 -0
- codex/static_root/assets/{admin-B8Bp2Uih.css → admin-BbrOU9Y9.css} +1 -1
- codex/static_root/assets/admin-BbrOU9Y9.css.br +0 -0
- codex/static_root/assets/admin-BbrOU9Y9.css.gz +0 -0
- codex/static_root/assets/admin-Bvd-SvGS.412e5b1b7ed1.js +1 -0
- codex/static_root/assets/admin-Bvd-SvGS.412e5b1b7ed1.js.br +0 -0
- codex/static_root/assets/admin-Bvd-SvGS.412e5b1b7ed1.js.gz +0 -0
- codex/static_root/assets/admin-Bvd-SvGS.js +1 -0
- codex/static_root/assets/admin-Bvd-SvGS.js.br +0 -0
- codex/static_root/assets/admin-Bvd-SvGS.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.1514926c78e8.css +1 -0
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.1514926c78e8.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.1514926c78e8.css.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.css +1 -0
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BF0dMvEE.css.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-D2OV5rDa.059e3bde9568.js +30 -0
- codex/static_root/assets/admin-drawer-panel-D2OV5rDa.059e3bde9568.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-D2OV5rDa.059e3bde9568.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-D2OV5rDa.js +30 -0
- codex/static_root/assets/admin-drawer-panel-D2OV5rDa.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-D2OV5rDa.js.gz +0 -0
- codex/static_root/assets/browser-CZeVqRNy.ccfca9a05bfe.css +1 -0
- codex/static_root/assets/browser-CZeVqRNy.ccfca9a05bfe.css.br +0 -0
- codex/static_root/assets/browser-CZeVqRNy.ccfca9a05bfe.css.gz +0 -0
- codex/static_root/assets/browser-CZeVqRNy.css +1 -0
- codex/static_root/assets/browser-CZeVqRNy.css.br +0 -0
- codex/static_root/assets/browser-CZeVqRNy.css.gz +0 -0
- codex/static_root/assets/browser-rc5ObkeN.0c1f38d229ac.js +1 -0
- codex/static_root/assets/browser-rc5ObkeN.0c1f38d229ac.js.br +0 -0
- codex/static_root/assets/browser-rc5ObkeN.0c1f38d229ac.js.gz +0 -0
- codex/static_root/assets/browser-rc5ObkeN.js +1 -0
- codex/static_root/assets/browser-rc5ObkeN.js.br +0 -0
- codex/static_root/assets/browser-rc5ObkeN.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-CRHk2tjq.d4d4b5945cd4.js +1 -0
- codex/static_root/assets/change-password-dialog-CRHk2tjq.d4d4b5945cd4.js.br +0 -0
- codex/static_root/assets/change-password-dialog-CRHk2tjq.d4d4b5945cd4.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-CRHk2tjq.js +1 -0
- codex/static_root/assets/change-password-dialog-CRHk2tjq.js.br +0 -0
- codex/static_root/assets/change-password-dialog-CRHk2tjq.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css +1 -0
- codex/static_root/assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css.br +0 -0
- codex/static_root/assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-HvIvmmIE.css +1 -0
- codex/static_root/assets/change-password-dialog-HvIvmmIE.css.br +0 -0
- codex/static_root/assets/change-password-dialog-HvIvmmIE.css.gz +0 -0
- codex/static_root/assets/confirm-dialog-DnHKM44R.d57a0196ac5a.js +1 -0
- codex/static_root/assets/confirm-dialog-DnHKM44R.d57a0196ac5a.js.br +0 -0
- codex/static_root/assets/confirm-dialog-DnHKM44R.d57a0196ac5a.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-DnHKM44R.js +1 -0
- codex/static_root/assets/confirm-dialog-DnHKM44R.js.br +0 -0
- codex/static_root/assets/confirm-dialog-DnHKM44R.js.gz +0 -0
- codex/static_root/assets/datetime-column-BEqDvdeI.44b65455a2c3.js +1 -0
- codex/static_root/assets/datetime-column-BEqDvdeI.44b65455a2c3.js.br +0 -0
- codex/static_root/assets/datetime-column-BEqDvdeI.44b65455a2c3.js.gz +0 -0
- codex/static_root/assets/datetime-column-BEqDvdeI.js +1 -0
- codex/static_root/assets/datetime-column-BEqDvdeI.js.br +0 -0
- codex/static_root/assets/datetime-column-BEqDvdeI.js.gz +0 -0
- codex/static_root/assets/datetime-column-Dg_RxTVM.1fa7c5cbead7.css +1 -0
- codex/static_root/assets/datetime-column-Dg_RxTVM.1fa7c5cbead7.css.br +0 -0
- codex/static_root/assets/datetime-column-Dg_RxTVM.css +1 -0
- codex/static_root/assets/datetime-column-Dg_RxTVM.css.br +0 -0
- codex/static_root/assets/filter-_wYL6jQC.dbc7d7e7b855.js +1 -0
- codex/static_root/assets/filter-_wYL6jQC.dbc7d7e7b855.js.br +0 -0
- codex/static_root/assets/filter-_wYL6jQC.dbc7d7e7b855.js.gz +0 -0
- codex/static_root/assets/filter-_wYL6jQC.js +1 -0
- codex/static_root/assets/filter-_wYL6jQC.js.br +0 -0
- codex/static_root/assets/filter-_wYL6jQC.js.gz +0 -0
- codex/static_root/assets/flag-tab-BacZLlVi.8deba6a5370d.css +1 -0
- codex/static_root/assets/flag-tab-BacZLlVi.8deba6a5370d.css.br +0 -0
- codex/static_root/assets/flag-tab-BacZLlVi.8deba6a5370d.css.gz +0 -0
- codex/static_root/assets/flag-tab-BacZLlVi.css +1 -0
- codex/static_root/assets/flag-tab-BacZLlVi.css.br +0 -0
- codex/static_root/assets/flag-tab-BacZLlVi.css.gz +0 -0
- codex/static_root/assets/flag-tab-Dpyvhwb_.2812bd46db2d.js +1 -0
- codex/static_root/assets/flag-tab-Dpyvhwb_.2812bd46db2d.js.br +0 -0
- codex/static_root/assets/flag-tab-Dpyvhwb_.2812bd46db2d.js.gz +0 -0
- codex/static_root/assets/flag-tab-Dpyvhwb_.js +1 -0
- codex/static_root/assets/flag-tab-Dpyvhwb_.js.br +0 -0
- codex/static_root/assets/flag-tab-Dpyvhwb_.js.gz +0 -0
- codex/static_root/assets/{group-tab-D5vWrihT.1afb2ce453ff.js → group-tab-DAjvuSUO.4494d4846fa6.js} +1 -1
- codex/static_root/assets/group-tab-DAjvuSUO.4494d4846fa6.js.br +0 -0
- codex/static_root/assets/group-tab-DAjvuSUO.4494d4846fa6.js.gz +0 -0
- codex/static_root/assets/{group-tab-D5vWrihT.js → group-tab-DAjvuSUO.js} +1 -1
- codex/static_root/assets/group-tab-DAjvuSUO.js.br +0 -0
- codex/static_root/assets/group-tab-DAjvuSUO.js.gz +0 -0
- codex/static_root/assets/http-error-CDQ-296a.6ea61686beb8.js +1 -0
- codex/static_root/assets/http-error-CDQ-296a.6ea61686beb8.js.br +0 -0
- codex/static_root/assets/http-error-CDQ-296a.6ea61686beb8.js.gz +0 -0
- codex/static_root/assets/http-error-CDQ-296a.js +1 -0
- codex/static_root/assets/http-error-CDQ-296a.js.br +0 -0
- codex/static_root/assets/http-error-CDQ-296a.js.gz +0 -0
- codex/static_root/assets/http-error-_wlDqEcp.5b78d3e332c9.css +1 -0
- codex/static_root/assets/{http-error-DKulXuTl.95e42988d5d5.css.br → http-error-_wlDqEcp.5b78d3e332c9.css.br} +0 -0
- codex/static_root/assets/http-error-_wlDqEcp.5b78d3e332c9.css.gz +0 -0
- codex/static_root/assets/http-error-_wlDqEcp.css +1 -0
- codex/static_root/assets/{http-error-DKulXuTl.css.br → http-error-_wlDqEcp.css.br} +0 -0
- codex/static_root/assets/http-error-_wlDqEcp.css.gz +0 -0
- codex/static_root/assets/index-DUjeNg4x.36d50c91b2c1.js +1 -0
- codex/static_root/assets/index-DUjeNg4x.36d50c91b2c1.js.br +0 -0
- codex/static_root/assets/index-DUjeNg4x.36d50c91b2c1.js.gz +0 -0
- codex/static_root/assets/index-DUjeNg4x.js +1 -0
- codex/static_root/assets/index-DUjeNg4x.js.br +0 -0
- codex/static_root/assets/index-DUjeNg4x.js.gz +0 -0
- codex/static_root/assets/library-tab-CXbkxNZt.954f2850a439.css +1 -0
- codex/static_root/assets/library-tab-CXbkxNZt.954f2850a439.css.br +2 -0
- codex/static_root/assets/library-tab-CXbkxNZt.954f2850a439.css.gz +0 -0
- codex/static_root/assets/library-tab-CXbkxNZt.css +1 -0
- codex/static_root/assets/library-tab-CXbkxNZt.css.br +2 -0
- codex/static_root/assets/library-tab-CXbkxNZt.css.gz +0 -0
- codex/static_root/assets/library-tab-LsexSRi2.34b88bbbfcdc.js +1 -0
- codex/static_root/assets/library-tab-LsexSRi2.34b88bbbfcdc.js.br +0 -0
- codex/static_root/assets/library-tab-LsexSRi2.34b88bbbfcdc.js.gz +0 -0
- codex/static_root/assets/library-tab-LsexSRi2.js +1 -0
- codex/static_root/assets/library-tab-LsexSRi2.js.br +0 -0
- codex/static_root/assets/library-tab-LsexSRi2.js.gz +0 -0
- codex/static_root/assets/main-CjPnwTfF.0f333ec81a42.js +32 -0
- codex/static_root/assets/main-CjPnwTfF.0f333ec81a42.js.br +0 -0
- codex/static_root/assets/main-CjPnwTfF.0f333ec81a42.js.gz +0 -0
- codex/static_root/assets/main-CjPnwTfF.js +32 -0
- codex/static_root/assets/main-CjPnwTfF.js.br +0 -0
- codex/static_root/assets/main-CjPnwTfF.js.gz +0 -0
- codex/static_root/assets/{main-Ztp855PW.d46d718fac45.css → main-sK7HC5h4.6f04ddfc5f1a.css} +1 -1
- codex/static_root/assets/main-sK7HC5h4.6f04ddfc5f1a.css.br +0 -0
- codex/static_root/assets/{main-Ztp855PW.d46d718fac45.css.gz → main-sK7HC5h4.6f04ddfc5f1a.css.gz} +0 -0
- codex/static_root/assets/{main-Ztp855PW.css → main-sK7HC5h4.css} +1 -1
- codex/static_root/assets/main-sK7HC5h4.css.br +0 -0
- codex/static_root/assets/{main-Ztp855PW.css.gz → main-sK7HC5h4.css.gz} +0 -0
- codex/static_root/assets/pagination-toolbar-B3wS4_7p.7695fafdefce.css +1 -0
- codex/static_root/assets/pagination-toolbar-B3wS4_7p.7695fafdefce.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-B3wS4_7p.7695fafdefce.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-B3wS4_7p.css +1 -0
- codex/static_root/assets/pagination-toolbar-B3wS4_7p.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-B3wS4_7p.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-B955aa-d.3fd9249f7342.js +1 -0
- codex/static_root/assets/pagination-toolbar-B955aa-d.3fd9249f7342.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-B955aa-d.3fd9249f7342.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-B955aa-d.js +1 -0
- codex/static_root/assets/pagination-toolbar-B955aa-d.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-B955aa-d.js.gz +0 -0
- codex/static_root/assets/pdf-doc-DPDmmEEp.74cab27a76e1.js +35 -0
- codex/static_root/assets/pdf-doc-DPDmmEEp.74cab27a76e1.js.br +0 -0
- codex/static_root/assets/pdf-doc-DPDmmEEp.74cab27a76e1.js.gz +0 -0
- codex/static_root/assets/pdf-doc-DPDmmEEp.js +35 -0
- codex/static_root/assets/pdf-doc-DPDmmEEp.js.br +0 -0
- codex/static_root/assets/pdf-doc-DPDmmEEp.js.gz +0 -0
- codex/static_root/assets/reader-BuMh4x3f.f4d7f1c97387.js +2 -0
- codex/static_root/assets/reader-BuMh4x3f.f4d7f1c97387.js.br +0 -0
- codex/static_root/assets/reader-BuMh4x3f.f4d7f1c97387.js.gz +0 -0
- codex/static_root/assets/reader-BuMh4x3f.js +2 -0
- codex/static_root/assets/reader-BuMh4x3f.js.br +0 -0
- codex/static_root/assets/reader-BuMh4x3f.js.gz +0 -0
- codex/static_root/assets/reader-Dspy46e8.925a6b05bfcf.css +1 -0
- codex/static_root/assets/reader-Dspy46e8.925a6b05bfcf.css.br +0 -0
- codex/static_root/assets/reader-Dspy46e8.925a6b05bfcf.css.gz +0 -0
- codex/static_root/assets/reader-Dspy46e8.css +1 -0
- codex/static_root/assets/reader-Dspy46e8.css.br +0 -0
- codex/static_root/assets/reader-Dspy46e8.css.gz +0 -0
- codex/static_root/assets/{relation-chips-Bsc-gUxE.98e65384c3c9.css → relation-chips-D6T6FX7G.css} +1 -1
- codex/static_root/assets/relation-chips-D6T6FX7G.css.br +0 -0
- codex/static_root/assets/relation-chips-D6T6FX7G.css.gz +0 -0
- codex/static_root/assets/{relation-chips-Bsc-gUxE.css → relation-chips-D6T6FX7G.db095b2497e4.css} +1 -1
- codex/static_root/assets/relation-chips-D6T6FX7G.db095b2497e4.css.br +0 -0
- codex/static_root/assets/relation-chips-D6T6FX7G.db095b2497e4.css.gz +0 -0
- codex/static_root/assets/relation-chips-DN_pPmnS.684c4eae4bdb.js +1 -0
- codex/static_root/assets/relation-chips-DN_pPmnS.684c4eae4bdb.js.br +0 -0
- codex/static_root/assets/relation-chips-DN_pPmnS.684c4eae4bdb.js.gz +0 -0
- codex/static_root/assets/relation-chips-DN_pPmnS.js +1 -0
- codex/static_root/assets/relation-chips-DN_pPmnS.js.br +0 -0
- codex/static_root/assets/relation-chips-DN_pPmnS.js.gz +0 -0
- codex/static_root/assets/settings-drawer-BgUazs7O.7bbeb1fd98f1.css +1 -0
- codex/static_root/assets/settings-drawer-BgUazs7O.7bbeb1fd98f1.css.br +0 -0
- codex/static_root/assets/settings-drawer-BgUazs7O.7bbeb1fd98f1.css.gz +0 -0
- codex/static_root/assets/settings-drawer-BgUazs7O.css +1 -0
- codex/static_root/assets/settings-drawer-BgUazs7O.css.br +0 -0
- codex/static_root/assets/settings-drawer-BgUazs7O.css.gz +0 -0
- codex/static_root/assets/settings-drawer-D4FgDG4z.de28fd4ce82a.js +2 -0
- codex/static_root/assets/settings-drawer-D4FgDG4z.de28fd4ce82a.js.br +0 -0
- codex/static_root/assets/settings-drawer-D4FgDG4z.de28fd4ce82a.js.gz +0 -0
- codex/static_root/assets/settings-drawer-D4FgDG4z.js +2 -0
- codex/static_root/assets/settings-drawer-D4FgDG4z.js.br +0 -0
- codex/static_root/assets/settings-drawer-D4FgDG4z.js.gz +0 -0
- codex/static_root/assets/stats-tab-AwbCeW63.a95f7d9b2059.js +1 -0
- codex/static_root/assets/stats-tab-AwbCeW63.a95f7d9b2059.js.br +0 -0
- codex/static_root/assets/stats-tab-AwbCeW63.a95f7d9b2059.js.gz +0 -0
- codex/static_root/assets/stats-tab-AwbCeW63.js +1 -0
- codex/static_root/assets/stats-tab-AwbCeW63.js.br +0 -0
- codex/static_root/assets/stats-tab-AwbCeW63.js.gz +0 -0
- codex/static_root/assets/stats-tab-TsyG3wH_.b93c080356fc.css +1 -0
- codex/static_root/assets/stats-tab-TsyG3wH_.b93c080356fc.css.br +2 -0
- codex/static_root/assets/stats-tab-TsyG3wH_.b93c080356fc.css.gz +0 -0
- codex/static_root/assets/stats-tab-TsyG3wH_.css +1 -0
- codex/static_root/assets/stats-tab-TsyG3wH_.css.br +2 -0
- codex/static_root/assets/stats-tab-TsyG3wH_.css.gz +0 -0
- codex/static_root/assets/task-tab-DeHQTHuz.5f967defca9f.js +1 -0
- codex/static_root/assets/task-tab-DeHQTHuz.5f967defca9f.js.br +0 -0
- codex/static_root/assets/task-tab-DeHQTHuz.5f967defca9f.js.gz +0 -0
- codex/static_root/assets/task-tab-DeHQTHuz.js +1 -0
- codex/static_root/assets/task-tab-DeHQTHuz.js.br +0 -0
- codex/static_root/assets/task-tab-DeHQTHuz.js.gz +0 -0
- codex/static_root/assets/to-case-kUm8NPpW.5b3369f511b8.js +1 -0
- codex/static_root/assets/to-case-kUm8NPpW.js +1 -0
- codex/static_root/assets/unauthorized-BXCbvRsL.bc44d7ba68b3.js +1 -0
- codex/static_root/assets/unauthorized-BXCbvRsL.bc44d7ba68b3.js.br +0 -0
- codex/static_root/assets/unauthorized-BXCbvRsL.bc44d7ba68b3.js.gz +0 -0
- codex/static_root/assets/unauthorized-BXCbvRsL.js +1 -0
- codex/static_root/assets/unauthorized-BXCbvRsL.js.br +0 -0
- codex/static_root/assets/unauthorized-BXCbvRsL.js.gz +0 -0
- codex/static_root/assets/{unauthorized-CibJYD8o.4c2de98c2b53.css → unauthorized-DWgytUow.ca2f13dbdbf5.css} +1 -1
- codex/static_root/assets/unauthorized-DWgytUow.ca2f13dbdbf5.css.br +0 -0
- codex/static_root/assets/unauthorized-DWgytUow.ca2f13dbdbf5.css.gz +0 -0
- codex/static_root/assets/{unauthorized-CibJYD8o.css → unauthorized-DWgytUow.css} +1 -1
- codex/static_root/assets/unauthorized-DWgytUow.css.br +0 -0
- codex/static_root/assets/unauthorized-DWgytUow.css.gz +0 -0
- codex/static_root/assets/user-tab-Dq4qYzgp.5d1b6c07edd0.js +1 -0
- codex/static_root/assets/user-tab-Dq4qYzgp.5d1b6c07edd0.js.br +0 -0
- codex/static_root/assets/user-tab-Dq4qYzgp.5d1b6c07edd0.js.gz +0 -0
- codex/static_root/assets/user-tab-Dq4qYzgp.js +1 -0
- codex/static_root/assets/user-tab-Dq4qYzgp.js.br +0 -0
- codex/static_root/assets/user-tab-Dq4qYzgp.js.gz +0 -0
- codex/static_root/js/choices-admin.248384ece3f6.json +1 -0
- codex/static_root/js/choices-admin.248384ece3f6.json.br +0 -0
- codex/static_root/js/choices-admin.248384ece3f6.json.gz +0 -0
- codex/static_root/js/choices-admin.json +1 -1
- codex/static_root/js/choices-admin.json.br +0 -0
- codex/static_root/js/choices-admin.json.gz +0 -0
- codex/static_root/js/choices.b60817ba0a93.json +1 -0
- codex/static_root/js/choices.b60817ba0a93.json.br +0 -0
- codex/static_root/js/choices.b60817ba0a93.json.gz +0 -0
- codex/static_root/js/choices.json +1 -1
- codex/static_root/js/choices.json.br +0 -0
- codex/static_root/js/choices.json.gz +0 -0
- codex/static_root/manifest.b5fe5d7ef44e.json +641 -0
- codex/static_root/manifest.b5fe5d7ef44e.json.br +0 -0
- codex/static_root/manifest.b5fe5d7ef44e.json.gz +0 -0
- codex/static_root/manifest.json +298 -279
- codex/static_root/manifest.json.br +0 -0
- codex/static_root/manifest.json.gz +0 -0
- codex/static_root/staticfiles.json +1 -1
- codex/status_controller.py +2 -11
- codex/urls/api/auth.py +1 -2
- codex/urls/api/browser.py +4 -13
- codex/urls/api/reader.py +9 -3
- codex/urls/api/v3.py +0 -2
- codex/urls/opds/binary.py +1 -1
- codex/views/admin/api_key.py +8 -7
- codex/views/admin/flag.py +7 -2
- codex/views/admin/group.py +6 -2
- codex/views/admin/library.py +37 -44
- codex/views/admin/stats.py +83 -20
- codex/views/admin/tasks.py +12 -26
- codex/views/admin/user.py +9 -3
- codex/views/auth.py +54 -31
- codex/views/bookmark.py +72 -92
- codex/views/browser/base.py +90 -42
- codex/views/browser/browser.py +371 -92
- codex/views/browser/{annotations.py → browser_annotations.py} +121 -67
- codex/views/browser/browser_breadcrumbs.py +175 -0
- codex/views/browser/browser_order_by.py +63 -0
- codex/views/browser/choices.py +85 -38
- codex/views/browser/const.py +3 -0
- codex/views/browser/filters/annotations.py +19 -87
- codex/views/browser/filters/bookmark.py +12 -24
- codex/views/browser/filters/field.py +6 -8
- codex/views/browser/filters/group.py +14 -35
- codex/views/browser/filters/search.py +20 -31
- codex/views/browser/metadata.py +73 -112
- codex/views/browser/session.py +12 -0
- codex/views/const.py +0 -140
- codex/views/cover.py +77 -0
- codex/views/download.py +8 -5
- codex/views/frontend.py +2 -4
- codex/views/opds/authentication_v1.py +45 -46
- codex/views/opds/binary.py +10 -5
- codex/views/opds/const.py +0 -13
- codex/views/opds/urls.py +4 -6
- codex/views/opds/util.py +12 -4
- codex/views/opds/v1/entry/links.py +33 -18
- codex/views/opds/v1/facets.py +7 -7
- codex/views/opds/v1/feed.py +45 -55
- codex/views/opds/v1/links.py +5 -7
- codex/views/opds/v1/opensearch_v1.py +6 -2
- codex/views/opds/v2/feed.py +26 -25
- codex/views/opds/v2/links.py +2 -4
- codex/views/opds/v2/publications.py +54 -34
- codex/views/opds/v2/top_links.py +2 -2
- codex/views/reader/page.py +8 -15
- codex/views/reader/reader.py +322 -19
- codex/views/reader/{settings.py → session.py} +2 -4
- codex/views/session.py +102 -83
- codex/views/template.py +3 -3
- codex/views/version.py +2 -2
- codex/websockets/consumers.py +10 -14
- {codex-1.6.0.dist-info → codex-1.6.0a1.dist-info}/METADATA +15 -22
- {codex-1.6.0.dist-info → codex-1.6.0a1.dist-info}/RECORD +448 -466
- codex/librarian/importer/cache.py +0 -93
- codex/librarian/importer/create_covers.py +0 -96
- codex/librarian/importer/importer.py +0 -96
- codex/librarian/importer/init.py +0 -265
- codex/librarian/importer/link_covers.py +0 -73
- codex/librarian/importer/query_covers.py +0 -52
- codex/migrations/0027_import_order_and_covers.py +0 -280
- codex/serializers/browser/mtime.py +0 -21
- codex/serializers/fields.py +0 -149
- codex/serializers/settings.py +0 -12
- codex/static_root/assets/VCheckbox-DanrzdHo.8ec5e2094cbf.js +0 -1
- codex/static_root/assets/VCheckbox-DanrzdHo.8ec5e2094cbf.js.br +0 -0
- codex/static_root/assets/VCheckbox-DanrzdHo.8ec5e2094cbf.js.gz +0 -0
- codex/static_root/assets/VCheckbox-DanrzdHo.js +0 -1
- codex/static_root/assets/VCheckbox-DanrzdHo.js.br +0 -0
- codex/static_root/assets/VCheckbox-DanrzdHo.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-DxNOKONG.5ab34c4c47aa.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-DxNOKONG.5ab34c4c47aa.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-DxNOKONG.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-DxNOKONG.js.gz +0 -0
- codex/static_root/assets/VCombobox-DDvdoPTG.11d080e8edd7.js +0 -1
- codex/static_root/assets/VCombobox-DDvdoPTG.11d080e8edd7.js.br +0 -0
- codex/static_root/assets/VCombobox-DDvdoPTG.11d080e8edd7.js.gz +0 -0
- codex/static_root/assets/VCombobox-DDvdoPTG.js +0 -1
- codex/static_root/assets/VCombobox-DDvdoPTG.js.br +0 -0
- codex/static_root/assets/VCombobox-DDvdoPTG.js.gz +0 -0
- codex/static_root/assets/VDialog-Bd5dN_E1.457666d7fce1.js +0 -1
- codex/static_root/assets/VDialog-Bd5dN_E1.457666d7fce1.js.br +0 -0
- codex/static_root/assets/VDialog-Bd5dN_E1.457666d7fce1.js.gz +0 -0
- codex/static_root/assets/VDialog-Bd5dN_E1.js +0 -1
- codex/static_root/assets/VDialog-Bd5dN_E1.js.br +0 -0
- codex/static_root/assets/VDialog-Bd5dN_E1.js.gz +0 -0
- codex/static_root/assets/VDialog-lQ13FnRR.1c801ad756b2.css.br +0 -0
- codex/static_root/assets/VDialog-lQ13FnRR.1c801ad756b2.css.gz +0 -0
- codex/static_root/assets/VDialog-lQ13FnRR.css.br +0 -0
- codex/static_root/assets/VDialog-lQ13FnRR.css.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DqTuYpTR.12673cf9f391.js +0 -1
- codex/static_root/assets/VExpansionPanels-DqTuYpTR.12673cf9f391.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-DqTuYpTR.12673cf9f391.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DqTuYpTR.js +0 -1
- codex/static_root/assets/VExpansionPanels-DqTuYpTR.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-DqTuYpTR.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-DKb8XPr-.3cf6bf5bf3bc.js +0 -1
- codex/static_root/assets/VRadioGroup-DKb8XPr-.3cf6bf5bf3bc.js.br +0 -0
- codex/static_root/assets/VRadioGroup-DKb8XPr-.3cf6bf5bf3bc.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-DKb8XPr-.js +0 -1
- codex/static_root/assets/VRadioGroup-DKb8XPr-.js.br +0 -0
- codex/static_root/assets/VRadioGroup-DKb8XPr-.js.gz +0 -0
- codex/static_root/assets/VSelect-C_yPbyCG.08bd6b53a7ce.js +0 -1
- codex/static_root/assets/VSelect-C_yPbyCG.08bd6b53a7ce.js.br +0 -0
- codex/static_root/assets/VSelect-C_yPbyCG.08bd6b53a7ce.js.gz +0 -0
- codex/static_root/assets/VSelect-C_yPbyCG.js +0 -1
- codex/static_root/assets/VSelect-C_yPbyCG.js.br +0 -0
- codex/static_root/assets/VSelect-C_yPbyCG.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-CmFPvGMS.802c9b3e6e28.js +0 -1
- codex/static_root/assets/VSelectionControl-CmFPvGMS.802c9b3e6e28.js.br +0 -0
- codex/static_root/assets/VSelectionControl-CmFPvGMS.802c9b3e6e28.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-CmFPvGMS.js +0 -1
- codex/static_root/assets/VSelectionControl-CmFPvGMS.js.br +0 -0
- codex/static_root/assets/VSelectionControl-CmFPvGMS.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-D5FZWsM1.a47491fe3e6d.js +0 -1
- codex/static_root/assets/VSlideGroup-D5FZWsM1.a47491fe3e6d.js.br +0 -0
- codex/static_root/assets/VSlideGroup-D5FZWsM1.a47491fe3e6d.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-D5FZWsM1.js +0 -1
- codex/static_root/assets/VSlideGroup-D5FZWsM1.js.br +0 -0
- codex/static_root/assets/VSlideGroup-D5FZWsM1.js.gz +0 -0
- codex/static_root/assets/VTable-2RHFqfg6.f0f2106b158b.js.br +0 -0
- codex/static_root/assets/VTable-2RHFqfg6.f0f2106b158b.js.gz +0 -0
- codex/static_root/assets/VTable-2RHFqfg6.js.br +0 -0
- codex/static_root/assets/VTable-2RHFqfg6.js.gz +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.4cc388b4aa3c.css +0 -1
- codex/static_root/assets/VTextField-BssVoDhB.4cc388b4aa3c.css.br +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.4cc388b4aa3c.css.gz +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.css +0 -1
- codex/static_root/assets/VTextField-BssVoDhB.css.br +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.css.gz +0 -0
- codex/static_root/assets/VTextField-o1N9ylIb.7fffaeff8d40.js +0 -1
- codex/static_root/assets/VTextField-o1N9ylIb.7fffaeff8d40.js.br +0 -0
- codex/static_root/assets/VTextField-o1N9ylIb.7fffaeff8d40.js.gz +0 -0
- codex/static_root/assets/VTextField-o1N9ylIb.js +0 -1
- codex/static_root/assets/VTextField-o1N9ylIb.js.br +0 -0
- codex/static_root/assets/VTextField-o1N9ylIb.js.gz +0 -0
- codex/static_root/assets/VWindowItem-C_zvuz9C.663fa48efea4.js +0 -1
- codex/static_root/assets/VWindowItem-C_zvuz9C.663fa48efea4.js.br +0 -0
- codex/static_root/assets/VWindowItem-C_zvuz9C.663fa48efea4.js.gz +0 -0
- codex/static_root/assets/VWindowItem-C_zvuz9C.js +0 -1
- codex/static_root/assets/VWindowItem-C_zvuz9C.js.br +0 -0
- codex/static_root/assets/VWindowItem-C_zvuz9C.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-DHyHEWZ3.7a8015456c0f.js +0 -1
- codex/static_root/assets/admin-DHyHEWZ3.7a8015456c0f.js.br +0 -0
- codex/static_root/assets/admin-DHyHEWZ3.7a8015456c0f.js.gz +0 -0
- codex/static_root/assets/admin-DHyHEWZ3.js +0 -1
- codex/static_root/assets/admin-DHyHEWZ3.js.br +0 -0
- codex/static_root/assets/admin-DHyHEWZ3.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-BXpIDQXM.19507a95375b.js +0 -30
- codex/static_root/assets/admin-drawer-panel-BXpIDQXM.19507a95375b.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BXpIDQXM.19507a95375b.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-BXpIDQXM.js +0 -30
- codex/static_root/assets/admin-drawer-panel-BXpIDQXM.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BXpIDQXM.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-mne3FIj6.561b3f75fe65.css +0 -1
- codex/static_root/assets/admin-drawer-panel-mne3FIj6.561b3f75fe65.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-mne3FIj6.561b3f75fe65.css.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-mne3FIj6.css +0 -1
- codex/static_root/assets/admin-drawer-panel-mne3FIj6.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-mne3FIj6.css.gz +0 -0
- codex/static_root/assets/browser-D0Vjmmp_.a1bfaf48d65f.js +0 -1
- codex/static_root/assets/browser-D0Vjmmp_.a1bfaf48d65f.js.br +0 -0
- codex/static_root/assets/browser-D0Vjmmp_.a1bfaf48d65f.js.gz +0 -0
- codex/static_root/assets/browser-D0Vjmmp_.js +0 -1
- codex/static_root/assets/browser-D0Vjmmp_.js.br +0 -0
- codex/static_root/assets/browser-D0Vjmmp_.js.gz +0 -0
- codex/static_root/assets/browser-D7QQDneO.155cb612ed0c.css +0 -1
- codex/static_root/assets/browser-D7QQDneO.155cb612ed0c.css.br +0 -0
- codex/static_root/assets/browser-D7QQDneO.155cb612ed0c.css.gz +0 -0
- codex/static_root/assets/browser-D7QQDneO.css +0 -1
- codex/static_root/assets/browser-D7QQDneO.css.br +0 -0
- codex/static_root/assets/browser-D7QQDneO.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css +0 -1
- codex/static_root/assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css.br +0 -0
- codex/static_root/assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-0u6IJA87.css +0 -1
- codex/static_root/assets/change-password-dialog-0u6IJA87.css.br +0 -0
- codex/static_root/assets/change-password-dialog-0u6IJA87.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-BBsJLPXZ.e642f7e2b96f.js +0 -1
- codex/static_root/assets/change-password-dialog-BBsJLPXZ.e642f7e2b96f.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BBsJLPXZ.e642f7e2b96f.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-BBsJLPXZ.js +0 -1
- codex/static_root/assets/change-password-dialog-BBsJLPXZ.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BBsJLPXZ.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-DCKvg3ai.2a3277b3c147.js +0 -1
- codex/static_root/assets/confirm-dialog-DCKvg3ai.2a3277b3c147.js.br +0 -0
- codex/static_root/assets/confirm-dialog-DCKvg3ai.2a3277b3c147.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-DCKvg3ai.js +0 -1
- codex/static_root/assets/confirm-dialog-DCKvg3ai.js.br +0 -0
- codex/static_root/assets/confirm-dialog-DCKvg3ai.js.gz +0 -0
- codex/static_root/assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js +0 -1
- codex/static_root/assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js.br +0 -0
- codex/static_root/assets/copy-to-clipboard-DoUvDJVx.js +0 -1
- codex/static_root/assets/copy-to-clipboard-DoUvDJVx.js.br +0 -0
- codex/static_root/assets/datetime-column-DeCthByU.1f3bf499e063.css +0 -1
- codex/static_root/assets/datetime-column-DeCthByU.css +0 -1
- codex/static_root/assets/datetime-column-jHKA_uNm.039c7da2036f.js +0 -1
- codex/static_root/assets/datetime-column-jHKA_uNm.039c7da2036f.js.br +0 -0
- codex/static_root/assets/datetime-column-jHKA_uNm.039c7da2036f.js.gz +0 -0
- codex/static_root/assets/datetime-column-jHKA_uNm.js +0 -1
- codex/static_root/assets/datetime-column-jHKA_uNm.js.br +0 -0
- codex/static_root/assets/datetime-column-jHKA_uNm.js.gz +0 -0
- codex/static_root/assets/filter-DgPg2ts9.af0fcf0888c6.js +0 -1
- codex/static_root/assets/filter-DgPg2ts9.af0fcf0888c6.js.br +0 -0
- codex/static_root/assets/filter-DgPg2ts9.af0fcf0888c6.js.gz +0 -0
- codex/static_root/assets/filter-DgPg2ts9.js +0 -1
- codex/static_root/assets/filter-DgPg2ts9.js.br +0 -0
- codex/static_root/assets/filter-DgPg2ts9.js.gz +0 -0
- codex/static_root/assets/flag-tab-9qxOALxP.f89bc9891671.js +0 -1
- codex/static_root/assets/flag-tab-9qxOALxP.f89bc9891671.js.br +0 -0
- codex/static_root/assets/flag-tab-9qxOALxP.f89bc9891671.js.gz +0 -0
- codex/static_root/assets/flag-tab-9qxOALxP.js +0 -1
- codex/static_root/assets/flag-tab-9qxOALxP.js.br +0 -0
- codex/static_root/assets/flag-tab-9qxOALxP.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-D5vWrihT.1afb2ce453ff.js.br +0 -0
- codex/static_root/assets/group-tab-D5vWrihT.1afb2ce453ff.js.gz +0 -0
- codex/static_root/assets/group-tab-D5vWrihT.js.br +0 -0
- codex/static_root/assets/group-tab-D5vWrihT.js.gz +0 -0
- codex/static_root/assets/http-error-B4FHoKfs.141fdae409bc.js +0 -1
- codex/static_root/assets/http-error-B4FHoKfs.141fdae409bc.js.br +0 -0
- codex/static_root/assets/http-error-B4FHoKfs.141fdae409bc.js.gz +0 -0
- codex/static_root/assets/http-error-B4FHoKfs.js +0 -1
- codex/static_root/assets/http-error-B4FHoKfs.js.br +0 -0
- codex/static_root/assets/http-error-B4FHoKfs.js.gz +0 -0
- codex/static_root/assets/http-error-DKulXuTl.95e42988d5d5.css +0 -1
- codex/static_root/assets/http-error-DKulXuTl.95e42988d5d5.css.gz +0 -0
- codex/static_root/assets/http-error-DKulXuTl.css +0 -1
- codex/static_root/assets/http-error-DKulXuTl.css.gz +0 -0
- codex/static_root/assets/library-tab-BN0SfPcH.913e236f625e.css +0 -1
- 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 +0 -1
- 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-BWo0cmzk.0e3d67d0c41a.js +0 -1
- codex/static_root/assets/library-tab-BWo0cmzk.0e3d67d0c41a.js.br +0 -0
- codex/static_root/assets/library-tab-BWo0cmzk.0e3d67d0c41a.js.gz +0 -0
- codex/static_root/assets/library-tab-BWo0cmzk.js +0 -1
- codex/static_root/assets/library-tab-BWo0cmzk.js.br +0 -0
- codex/static_root/assets/library-tab-BWo0cmzk.js.gz +0 -0
- codex/static_root/assets/main-Ztp855PW.css.br +0 -0
- codex/static_root/assets/main-Ztp855PW.d46d718fac45.css.br +0 -0
- codex/static_root/assets/main-ipmlipkF.5e60e6e8e447.js +0 -32
- codex/static_root/assets/main-ipmlipkF.5e60e6e8e447.js.br +0 -0
- codex/static_root/assets/main-ipmlipkF.5e60e6e8e447.js.gz +0 -0
- codex/static_root/assets/main-ipmlipkF.js +0 -32
- codex/static_root/assets/main-ipmlipkF.js.br +0 -0
- codex/static_root/assets/main-ipmlipkF.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BA9ifTed.b4865334ee08.css +0 -1
- codex/static_root/assets/pagination-toolbar-BA9ifTed.b4865334ee08.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-BA9ifTed.b4865334ee08.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BA9ifTed.css +0 -1
- codex/static_root/assets/pagination-toolbar-BA9ifTed.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-BA9ifTed.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-kZ-Xdv8c.b3341b8028df.js +0 -1
- codex/static_root/assets/pagination-toolbar-kZ-Xdv8c.b3341b8028df.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-kZ-Xdv8c.b3341b8028df.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-kZ-Xdv8c.js +0 -1
- codex/static_root/assets/pagination-toolbar-kZ-Xdv8c.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-kZ-Xdv8c.js.gz +0 -0
- codex/static_root/assets/pdf-doc-C2StaYUz.cb848834dbe1.js +0 -305
- codex/static_root/assets/pdf-doc-C2StaYUz.cb848834dbe1.js.br +0 -0
- codex/static_root/assets/pdf-doc-C2StaYUz.cb848834dbe1.js.gz +0 -0
- codex/static_root/assets/pdf-doc-C2StaYUz.js +0 -305
- codex/static_root/assets/pdf-doc-C2StaYUz.js.br +0 -0
- codex/static_root/assets/pdf-doc-C2StaYUz.js.gz +0 -0
- codex/static_root/assets/reader-CCnq3j1-.b6b38ed5521e.js +0 -2
- codex/static_root/assets/reader-CCnq3j1-.b6b38ed5521e.js.br +0 -0
- codex/static_root/assets/reader-CCnq3j1-.b6b38ed5521e.js.gz +0 -0
- codex/static_root/assets/reader-CCnq3j1-.js +0 -2
- codex/static_root/assets/reader-CCnq3j1-.js.br +0 -0
- codex/static_root/assets/reader-CCnq3j1-.js.gz +0 -0
- codex/static_root/assets/reader-CqXFa_gE.78267e9de0c2.css +0 -1
- codex/static_root/assets/reader-CqXFa_gE.78267e9de0c2.css.br +0 -0
- codex/static_root/assets/reader-CqXFa_gE.78267e9de0c2.css.gz +0 -0
- codex/static_root/assets/reader-CqXFa_gE.css +0 -1
- codex/static_root/assets/reader-CqXFa_gE.css.br +0 -0
- codex/static_root/assets/reader-CqXFa_gE.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-C9ysW0tU.670f1d1f273f.js +0 -1
- codex/static_root/assets/relation-chips-C9ysW0tU.670f1d1f273f.js.br +0 -0
- codex/static_root/assets/relation-chips-C9ysW0tU.670f1d1f273f.js.gz +0 -0
- codex/static_root/assets/relation-chips-C9ysW0tU.js +0 -1
- codex/static_root/assets/relation-chips-C9ysW0tU.js.br +0 -0
- codex/static_root/assets/relation-chips-C9ysW0tU.js.gz +0 -0
- codex/static_root/assets/settings-drawer-C0ofzAhW.c0def8f383cb.js +0 -2
- codex/static_root/assets/settings-drawer-C0ofzAhW.c0def8f383cb.js.br +0 -0
- codex/static_root/assets/settings-drawer-C0ofzAhW.c0def8f383cb.js.gz +0 -0
- codex/static_root/assets/settings-drawer-C0ofzAhW.js +0 -2
- codex/static_root/assets/settings-drawer-C0ofzAhW.js.br +0 -0
- codex/static_root/assets/settings-drawer-C0ofzAhW.js.gz +0 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.01744e131806.css +0 -1
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.01744e131806.css.br +0 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.01744e131806.css.gz +0 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.css +0 -1
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.css.br +0 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.css.gz +0 -0
- codex/static_root/assets/stats-tab-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-BqJj7j1w.38a3459d61ea.js +0 -1
- codex/static_root/assets/stats-tab-BqJj7j1w.38a3459d61ea.js.br +0 -0
- codex/static_root/assets/stats-tab-BqJj7j1w.38a3459d61ea.js.gz +0 -0
- codex/static_root/assets/stats-tab-BqJj7j1w.js +0 -1
- codex/static_root/assets/stats-tab-BqJj7j1w.js.br +0 -0
- codex/static_root/assets/stats-tab-BqJj7j1w.js.gz +0 -0
- codex/static_root/assets/task-tab-BsPzNk8S.e00630a60b43.js +0 -1
- codex/static_root/assets/task-tab-BsPzNk8S.e00630a60b43.js.br +0 -0
- codex/static_root/assets/task-tab-BsPzNk8S.e00630a60b43.js.gz +0 -0
- codex/static_root/assets/task-tab-BsPzNk8S.js +0 -1
- codex/static_root/assets/task-tab-BsPzNk8S.js.br +0 -0
- codex/static_root/assets/task-tab-BsPzNk8S.js.gz +0 -0
- codex/static_root/assets/to-case-KvqtSug2.9c02da2e47c7.js +0 -1
- codex/static_root/assets/to-case-KvqtSug2.9c02da2e47c7.js.br +0 -0
- codex/static_root/assets/to-case-KvqtSug2.js +0 -1
- codex/static_root/assets/to-case-KvqtSug2.js.br +0 -0
- codex/static_root/assets/unauthorized-CibJYD8o.4c2de98c2b53.css.br +0 -0
- codex/static_root/assets/unauthorized-CibJYD8o.4c2de98c2b53.css.gz +0 -0
- codex/static_root/assets/unauthorized-CibJYD8o.css.br +0 -0
- codex/static_root/assets/unauthorized-CibJYD8o.css.gz +0 -0
- codex/static_root/assets/unauthorized-DwSdNzX2.f418e69f3afe.js +0 -1
- codex/static_root/assets/unauthorized-DwSdNzX2.f418e69f3afe.js.br +0 -0
- codex/static_root/assets/unauthorized-DwSdNzX2.f418e69f3afe.js.gz +0 -0
- codex/static_root/assets/unauthorized-DwSdNzX2.js +0 -1
- codex/static_root/assets/unauthorized-DwSdNzX2.js.br +0 -0
- codex/static_root/assets/unauthorized-DwSdNzX2.js.gz +0 -0
- codex/static_root/assets/user-tab-DrJOb9Ys.083d993726d8.js +0 -1
- codex/static_root/assets/user-tab-DrJOb9Ys.083d993726d8.js.br +0 -0
- codex/static_root/assets/user-tab-DrJOb9Ys.083d993726d8.js.gz +0 -0
- codex/static_root/assets/user-tab-DrJOb9Ys.js +0 -1
- codex/static_root/assets/user-tab-DrJOb9Ys.js.br +0 -0
- codex/static_root/assets/user-tab-DrJOb9Ys.js.gz +0 -0
- codex/static_root/js/choices-admin.3521e2a863df.json +0 -1
- codex/static_root/js/choices-admin.3521e2a863df.json.br +0 -0
- codex/static_root/js/choices-admin.3521e2a863df.json.gz +0 -0
- codex/static_root/js/choices.2f6b0359e1ef.json +0 -1
- codex/static_root/js/choices.2f6b0359e1ef.json.br +0 -0
- codex/static_root/js/choices.2f6b0359e1ef.json.gz +0 -0
- codex/static_root/manifest.1c84116d9a0a.json +0 -622
- codex/static_root/manifest.1c84116d9a0a.json.br +0 -0
- codex/static_root/manifest.1c84116d9a0a.json.gz +0 -0
- codex/util.py +0 -12
- codex/views/admin/auth.py +0 -28
- codex/views/browser/breadcrumbs.py +0 -202
- codex/views/browser/cover.py +0 -165
- codex/views/browser/mtime.py +0 -61
- codex/views/browser/order_by.py +0 -65
- codex/views/browser/paginate.py +0 -106
- codex/views/browser/settings.py +0 -66
- codex/views/browser/title.py +0 -48
- codex/views/browser/validate.py +0 -161
- codex/views/opds/auth.py +0 -17
- codex/views/public.py +0 -36
- codex/views/reader/arcs.py +0 -92
- codex/views/reader/books.py +0 -181
- codex/views/reader/init.py +0 -125
- codex/views/settings.py +0 -47
- codex/views/util.py +0 -77
- {codex-1.6.0.dist-info → codex-1.6.0a1.dist-info}/LICENSE +0 -0
- {codex-1.6.0.dist-info → codex-1.6.0a1.dist-info}/WHEEL +0 -0
- {codex-1.6.0.dist-info → codex-1.6.0a1.dist-info}/entry_points.txt +0 -0
|
@@ -1,23 +1,9 @@
|
|
|
1
1
|
"""Codex Serializers for the metadata box."""
|
|
2
2
|
|
|
3
|
-
from rest_framework.serializers import CharField, IntegerField
|
|
3
|
+
from rest_framework.serializers import CharField, IntegerField
|
|
4
4
|
|
|
5
5
|
from codex.serializers.browser.mixins import BrowserAggregateSerializerMixin
|
|
6
6
|
from codex.serializers.models.comic import ComicSerializer
|
|
7
|
-
from codex.serializers.models.named import (
|
|
8
|
-
ContributorSerializer,
|
|
9
|
-
IdentifierSeralizer,
|
|
10
|
-
StoryArcNumberSerializer,
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
PREFETCH_PREFIX = "attached_"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class GroupSerializer(Serializer):
|
|
17
|
-
"""Serialize a group pk and name."""
|
|
18
|
-
|
|
19
|
-
ids = ListField(child=IntegerField(), read_only=True)
|
|
20
|
-
name = CharField(read_only=True)
|
|
21
7
|
|
|
22
8
|
|
|
23
9
|
class MetadataSerializer(BrowserAggregateSerializerMixin, ComicSerializer):
|
|
@@ -27,33 +13,3 @@ class MetadataSerializer(BrowserAggregateSerializerMixin, ComicSerializer):
|
|
|
27
13
|
parent_folder_id = IntegerField(read_only=True, required=False)
|
|
28
14
|
series_volume_count = IntegerField(read_only=True)
|
|
29
15
|
volume_issue_count = IntegerField(read_only=True)
|
|
30
|
-
|
|
31
|
-
publisher_list = GroupSerializer(many=True, required=False)
|
|
32
|
-
imprint_list = GroupSerializer(many=True, required=False)
|
|
33
|
-
series_list = GroupSerializer(many=True, required=False)
|
|
34
|
-
volume_list = GroupSerializer(many=True, required=False)
|
|
35
|
-
publisher = None
|
|
36
|
-
imprint = None
|
|
37
|
-
series = None
|
|
38
|
-
volume = None
|
|
39
|
-
|
|
40
|
-
identifiers = IdentifierSeralizer(
|
|
41
|
-
source=f"{PREFETCH_PREFIX}identifiers", many=True, allow_null=True
|
|
42
|
-
)
|
|
43
|
-
contributors = ContributorSerializer(
|
|
44
|
-
source=f"{PREFETCH_PREFIX}contributors", many=True, allow_null=True
|
|
45
|
-
)
|
|
46
|
-
stroy_arc_numbers = StoryArcNumberSerializer(
|
|
47
|
-
source=f"{PREFETCH_PREFIX}story_arc_numbers", many=True, allow_null=True
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
class Meta(ComicSerializer.Meta):
|
|
51
|
-
"""Configure the model."""
|
|
52
|
-
|
|
53
|
-
exclude = (
|
|
54
|
-
*ComicSerializer.Meta.exclude,
|
|
55
|
-
"publisher",
|
|
56
|
-
"imprint",
|
|
57
|
-
"series",
|
|
58
|
-
"volume",
|
|
59
|
-
)
|
|
@@ -1,33 +1,27 @@
|
|
|
1
1
|
"""Serializer mixins."""
|
|
2
2
|
|
|
3
|
-
from datetime import datetime, timezone
|
|
4
|
-
|
|
5
3
|
from rest_framework.serializers import (
|
|
6
4
|
BooleanField,
|
|
7
5
|
CharField,
|
|
8
6
|
DateTimeField,
|
|
9
7
|
DecimalField,
|
|
10
8
|
IntegerField,
|
|
11
|
-
ListField,
|
|
12
9
|
Serializer,
|
|
13
|
-
SerializerMethodField,
|
|
14
10
|
)
|
|
15
11
|
|
|
16
|
-
from codex.
|
|
17
|
-
from codex.views.const import COMIC_GROUP, EPOCH_START
|
|
18
|
-
|
|
19
|
-
LOG = get_logger(__name__)
|
|
12
|
+
from codex.serializers.browser.filters import IntListField
|
|
20
13
|
|
|
21
14
|
|
|
22
15
|
class BrowserAggregateSerializerMixin(Serializer):
|
|
23
16
|
"""Mixin for browser, opds & metadata serializers."""
|
|
24
17
|
|
|
25
18
|
group = CharField(read_only=True, max_length=1)
|
|
26
|
-
ids =
|
|
19
|
+
ids = IntListField(read_only=True)
|
|
27
20
|
|
|
28
21
|
# Aggregate Annotations
|
|
29
22
|
child_count = IntegerField(read_only=True)
|
|
30
|
-
|
|
23
|
+
cover_pk = IntegerField(read_only=True)
|
|
24
|
+
cover_mtime = DateTimeField(format="%s", read_only=True)
|
|
31
25
|
|
|
32
26
|
# Bookmark annotations
|
|
33
27
|
page = IntegerField(read_only=True)
|
|
@@ -36,30 +30,3 @@ class BrowserAggregateSerializerMixin(Serializer):
|
|
|
36
30
|
progress = DecimalField(
|
|
37
31
|
max_digits=5, decimal_places=2, read_only=True, coerce_to_string=False
|
|
38
32
|
)
|
|
39
|
-
|
|
40
|
-
def get_mtime(self, obj) -> int:
|
|
41
|
-
"""Compute mtime from json array aggregates."""
|
|
42
|
-
mtime = EPOCH_START
|
|
43
|
-
for dt_str in obj.updated_ats:
|
|
44
|
-
if not dt_str:
|
|
45
|
-
continue
|
|
46
|
-
try:
|
|
47
|
-
dt = datetime.strptime(dt_str, "%Y-%m-%d %H:%M:%S.%f").replace(
|
|
48
|
-
tzinfo=timezone.utc
|
|
49
|
-
)
|
|
50
|
-
except ValueError:
|
|
51
|
-
LOG.warning(
|
|
52
|
-
f"computing group mtime: {dt_str} is not a valid datetime string."
|
|
53
|
-
)
|
|
54
|
-
continue
|
|
55
|
-
|
|
56
|
-
if dt > mtime:
|
|
57
|
-
mtime = dt
|
|
58
|
-
|
|
59
|
-
if obj.group != COMIC_GROUP and (
|
|
60
|
-
mbua := getattr(obj, "max_bookmark_updated_at", None)
|
|
61
|
-
):
|
|
62
|
-
mtime = max(mtime, mbua)
|
|
63
|
-
|
|
64
|
-
# print(obj.group, obj.pk, obj.name, obj.updated_ats, obj.max_bookmark_updated_at, "max:", mtime)
|
|
65
|
-
return int(mtime.timestamp() * 1000)
|
|
@@ -3,15 +3,17 @@
|
|
|
3
3
|
from rest_framework.serializers import (
|
|
4
4
|
BooleanField,
|
|
5
5
|
CharField,
|
|
6
|
+
DateTimeField,
|
|
6
7
|
DecimalField,
|
|
7
8
|
IntegerField,
|
|
9
|
+
ListSerializer,
|
|
8
10
|
Serializer,
|
|
9
11
|
)
|
|
10
12
|
|
|
11
13
|
from codex.serializers.browser.mixins import (
|
|
12
14
|
BrowserAggregateSerializerMixin,
|
|
13
15
|
)
|
|
14
|
-
from codex.serializers.
|
|
16
|
+
from codex.serializers.route import RouteSerializer
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class BrowserCardSerializer(BrowserAggregateSerializerMixin):
|
|
@@ -32,6 +34,7 @@ class BrowserCardSerializer(BrowserAggregateSerializerMixin):
|
|
|
32
34
|
order_value = CharField(read_only=True)
|
|
33
35
|
page_count = IntegerField(read_only=True)
|
|
34
36
|
reading_direction = CharField(read_only=True)
|
|
37
|
+
mtime = DateTimeField(format="%s", read_only=True)
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
class BrowserAdminFlagsSerializer(Serializer):
|
|
@@ -52,12 +55,12 @@ class BrowserPageSerializer(Serializer):
|
|
|
52
55
|
"""The main browse list."""
|
|
53
56
|
|
|
54
57
|
admin_flags = BrowserAdminFlagsSerializer(read_only=True)
|
|
55
|
-
breadcrumbs =
|
|
58
|
+
breadcrumbs = ListSerializer(child=RouteSerializer())
|
|
56
59
|
title = BrowserTitleSerializer(read_only=True)
|
|
60
|
+
covers_timestamp = IntegerField(read_only=True)
|
|
57
61
|
zero_pad = IntegerField(read_only=True)
|
|
58
62
|
libraries_exist = BooleanField(read_only=True)
|
|
59
63
|
model_group = CharField(read_only=True)
|
|
60
64
|
num_pages = IntegerField(read_only=True)
|
|
61
65
|
groups = BrowserCardSerializer(allow_empty=True, read_only=True, many=True)
|
|
62
66
|
books = BrowserCardSerializer(allow_empty=True, read_only=True, many=True)
|
|
63
|
-
mtime = TimestampField(read_only=True)
|
|
@@ -10,8 +10,6 @@ from rest_framework.serializers import (
|
|
|
10
10
|
|
|
11
11
|
from codex.serializers.browser.filters import BrowserSettingsFilterSerializer
|
|
12
12
|
from codex.serializers.choices import CHOICES, VUETIFY_NULL_CODE
|
|
13
|
-
from codex.serializers.fields import BreadcrumbsField, TimestampField, TopGroupField
|
|
14
|
-
from codex.serializers.route import SimpleRouteSerializer
|
|
15
13
|
|
|
16
14
|
VUETIFY_NULL_CODE_STR = str(VUETIFY_NULL_CODE)
|
|
17
15
|
|
|
@@ -25,50 +23,21 @@ class BrowserSettingsShowGroupFlagsSerializer(Serializer):
|
|
|
25
23
|
v = BooleanField()
|
|
26
24
|
|
|
27
25
|
|
|
28
|
-
class
|
|
29
|
-
"""Browser Settings
|
|
30
|
-
|
|
31
|
-
filters = BrowserSettingsFilterSerializer(required=False)
|
|
32
|
-
q = CharField(allow_blank=True, required=False)
|
|
33
|
-
|
|
26
|
+
class BrowserSettingsSerializer(Serializer):
|
|
27
|
+
"""Browser Settings that the user can change.
|
|
34
28
|
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
This is the only browse serializer that's submitted.
|
|
30
|
+
It is also sent to the browser as part of BrowserOpenedSerializer.
|
|
31
|
+
"""
|
|
37
32
|
|
|
38
|
-
|
|
39
|
-
dynamic_covers = BooleanField(required=False)
|
|
33
|
+
filters = BrowserSettingsFilterSerializer(required=False)
|
|
40
34
|
order_by = ChoiceField(choices=tuple(CHOICES["orderBy"].keys()), required=False)
|
|
41
35
|
order_reverse = BooleanField(required=False)
|
|
36
|
+
q = CharField(allow_blank=True, required=False)
|
|
37
|
+
query = CharField(allow_blank=True, required=False) # OPDS 2.0
|
|
42
38
|
show = BrowserSettingsShowGroupFlagsSerializer(required=False)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class BrowserCoverInputSerializer(BrowserCoverInputSerializerBase):
|
|
46
|
-
"""Browser Settings for the cover response."""
|
|
47
|
-
|
|
48
|
-
parent = SimpleRouteSerializer(required=False)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class BrowserSettingsSerializerBase(BrowserCoverInputSerializerBase):
|
|
52
|
-
"""Base Serializer for Browser & OPDS Settings."""
|
|
53
|
-
|
|
54
39
|
# search_results_limit = IntegerField(required=False)
|
|
55
|
-
top_group = TopGroupField(required=False)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class OPDSSettingsSerializer(BrowserSettingsSerializerBase):
|
|
59
|
-
"""Browser Settings for the OPDS."""
|
|
60
|
-
|
|
61
|
-
limit = IntegerField(required=False)
|
|
62
|
-
opds_metadata = BooleanField(required=False)
|
|
63
|
-
query = CharField(allow_blank=True, required=False) # OPDS 2.0
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
class BrowserSettingsSerializer(BrowserSettingsSerializerBase):
|
|
67
|
-
"""Browser Settings that the user can change.
|
|
68
|
-
|
|
69
|
-
This is the only browse serializer that's submitted.
|
|
70
|
-
"""
|
|
71
|
-
|
|
72
|
-
breadcrumbs = BreadcrumbsField(required=False)
|
|
73
|
-
mtime = TimestampField(read_only=True)
|
|
74
40
|
twenty_four_hour_time = BooleanField(required=False)
|
|
41
|
+
top_group = ChoiceField(choices=tuple(CHOICES["topGroup"].keys()), required=False)
|
|
42
|
+
opds_metadata = BooleanField(required=False)
|
|
43
|
+
limit = IntegerField(required=False)
|
codex/serializers/choices.py
CHANGED
|
@@ -49,26 +49,13 @@ _CHOICES_FN_RE = {
|
|
|
49
49
|
_CHOICES_MODULE_NAME: create_choices_fn_regexes(_CHOICES_MODULE_NAME),
|
|
50
50
|
_ADMIN_CHOICES_MODULE_NAME: create_choices_fn_regexes(_ADMIN_CHOICES_MODULE_NAME),
|
|
51
51
|
}
|
|
52
|
-
_SINGLE_VALUE_KEYS = frozenset(
|
|
53
|
-
{
|
|
54
|
-
"customCovers",
|
|
55
|
-
"dynamicCovers",
|
|
56
|
-
"finishOnLastPage",
|
|
57
|
-
"orderReverse",
|
|
58
|
-
"q",
|
|
59
|
-
"readRtlInReverse",
|
|
60
|
-
"searchResultsLimit",
|
|
61
|
-
"twentyFourHourTime",
|
|
62
|
-
"twoPages",
|
|
63
|
-
}
|
|
64
|
-
)
|
|
52
|
+
_SINGLE_VALUE_KEYS = frozenset({"orderReverse", "q", "searchResultsLimit"})
|
|
65
53
|
|
|
66
54
|
# Exports
|
|
67
55
|
CHOICES = {}
|
|
68
56
|
DEFAULTS = {}
|
|
69
57
|
WEBSOCKET_MESSAGES = {}
|
|
70
58
|
VUETIFY_NULL_CODE = -1
|
|
71
|
-
DUMMY_NULL_NAME = "_none_"
|
|
72
59
|
|
|
73
60
|
|
|
74
61
|
def _find_filename_regex(js_root, module_name):
|
|
@@ -1,33 +1,73 @@
|
|
|
1
1
|
"""Pycountry Model Serializers."""
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import pycountry
|
|
4
|
+
from drf_spectacular.types import OpenApiTypes
|
|
5
|
+
from drf_spectacular.utils import extend_schema_field
|
|
6
|
+
from rest_framework.serializers import (
|
|
7
|
+
SerializerMethodField,
|
|
8
|
+
)
|
|
9
|
+
|
|
4
10
|
from codex.models import (
|
|
5
11
|
Country,
|
|
6
12
|
Language,
|
|
7
13
|
)
|
|
8
|
-
from codex.serializers.fields import CountryField, LanguageField
|
|
9
14
|
from codex.serializers.models.named import NamedModelSerializer
|
|
10
15
|
|
|
11
|
-
LOG = get_logger(__name__)
|
|
12
16
|
|
|
17
|
+
class PyCountrySerializer(NamedModelSerializer):
|
|
18
|
+
"""PyCountry tag serializer to include long names.
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
Takes a single string value and serializes the value to
|
|
21
|
+
a pk attribute and a pycountry long name lookup of that value to
|
|
22
|
+
the name.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
LOOKUP_MODULE = pycountry.countries
|
|
26
|
+
_ALPHA_2_LEN = 2
|
|
16
27
|
|
|
17
|
-
name =
|
|
28
|
+
name = SerializerMethodField()
|
|
18
29
|
|
|
19
30
|
class Meta(NamedModelSerializer.Meta):
|
|
20
|
-
"""
|
|
31
|
+
"""Abstract class."""
|
|
21
32
|
|
|
22
|
-
|
|
33
|
+
abstract = True
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def lookup_name(cls, lookup_module, obj):
|
|
37
|
+
"""Lookup the name with pycountry, just copy the key on fail."""
|
|
38
|
+
name = obj.name
|
|
39
|
+
if not name:
|
|
40
|
+
return ""
|
|
41
|
+
# fix for https://github.com/flyingcircusio/pycountry/issues/41
|
|
42
|
+
lookup_obj = (
|
|
43
|
+
lookup_module.get(alpha_2=name)
|
|
44
|
+
if len(name) == cls._ALPHA_2_LEN
|
|
45
|
+
else lookup_module.lookup(name)
|
|
46
|
+
)
|
|
47
|
+
# If lookup fails, return the key as the name
|
|
48
|
+
return lookup_obj.name if lookup_obj else name
|
|
49
|
+
|
|
50
|
+
@extend_schema_field(OpenApiTypes.STR)
|
|
51
|
+
def get_name(self, obj):
|
|
52
|
+
"""Lookup the name with pycountry, just copy the key on fail."""
|
|
53
|
+
return self.lookup_name(self.LOOKUP_MODULE, obj)
|
|
23
54
|
|
|
24
55
|
|
|
25
|
-
class LanguageSerializer(
|
|
56
|
+
class LanguageSerializer(PyCountrySerializer):
|
|
26
57
|
"""Pycountry serializer for language field."""
|
|
27
58
|
|
|
28
|
-
|
|
59
|
+
LOOKUP_MODULE = pycountry.languages
|
|
29
60
|
|
|
30
|
-
class Meta(
|
|
61
|
+
class Meta(PyCountrySerializer.Meta):
|
|
31
62
|
"""Configure model."""
|
|
32
63
|
|
|
33
64
|
model = Language
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class CountrySerializer(PyCountrySerializer):
|
|
68
|
+
"""Pycountry serializer for country field."""
|
|
69
|
+
|
|
70
|
+
class Meta(PyCountrySerializer.Meta):
|
|
71
|
+
"""Configure model."""
|
|
72
|
+
|
|
73
|
+
model = Country
|
codex/serializers/opds/v2.py
CHANGED
|
@@ -12,6 +12,12 @@ from rest_framework.fields import (
|
|
|
12
12
|
from rest_framework.serializers import Serializer
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
class CharListField(ListField):
|
|
16
|
+
"""List of CharFields."""
|
|
17
|
+
|
|
18
|
+
child = CharField()
|
|
19
|
+
|
|
20
|
+
|
|
15
21
|
class OPDS2LinkPropertiesSerializer(Serializer):
|
|
16
22
|
"""Link Properties.
|
|
17
23
|
|
|
@@ -49,9 +55,9 @@ class OPDS2LinkSerializer(Serializer):
|
|
|
49
55
|
width = IntegerField(read_only=True, required=False)
|
|
50
56
|
# bitrate = IntegerField(read_only=True, required=False)
|
|
51
57
|
# duration = IntegerField(read_only=True, required=False)
|
|
52
|
-
# language =
|
|
53
|
-
alternate =
|
|
54
|
-
children =
|
|
58
|
+
# language = CharListField(read_only=True, required=False)
|
|
59
|
+
alternate = CharListField(read_only=True, required=False)
|
|
60
|
+
children = CharListField(read_only=True, required=False)
|
|
55
61
|
properties = OPDS2LinkPropertiesSerializer(read_only=True, required=False)
|
|
56
62
|
|
|
57
63
|
def get_rel(self, obj) -> str | None:
|
|
@@ -63,7 +69,7 @@ class OPDS2LinkSerializer(Serializer):
|
|
|
63
69
|
return obj.get("rel")
|
|
64
70
|
|
|
65
71
|
|
|
66
|
-
class
|
|
72
|
+
class LinkListField(ListField):
|
|
67
73
|
"""Link List."""
|
|
68
74
|
|
|
69
75
|
child = OPDS2LinkSerializer()
|
|
@@ -125,7 +131,7 @@ class OPDS2PublicationMetadataSerializer(OPDS2MetadataSerializer):
|
|
|
125
131
|
#####################
|
|
126
132
|
# Extended metadata #
|
|
127
133
|
#####################
|
|
128
|
-
subject =
|
|
134
|
+
subject = CharListField(read_only=True, required=False)
|
|
129
135
|
author = OPDS2ContributorObjectSerializer(many=True, required=False)
|
|
130
136
|
# translator = OPDS2ContributorObjectSerializer(many=True, required=False)
|
|
131
137
|
editor = OPDS2ContributorObjectSerializer(many=True, required=False)
|
|
@@ -142,7 +148,7 @@ class OPDS2FacetSerializer(Serializer):
|
|
|
142
148
|
"""Facets."""
|
|
143
149
|
|
|
144
150
|
metadata = OPDS2MetadataSerializer(read_only=True)
|
|
145
|
-
links =
|
|
151
|
+
links = LinkListField(read_only=True)
|
|
146
152
|
|
|
147
153
|
|
|
148
154
|
class OPDS2PublicationSerializer(OPDS2FacetSerializer):
|
|
@@ -152,19 +158,19 @@ class OPDS2PublicationSerializer(OPDS2FacetSerializer):
|
|
|
152
158
|
"""
|
|
153
159
|
|
|
154
160
|
metadata = OPDS2PublicationMetadataSerializer(read_only=True)
|
|
155
|
-
links =
|
|
156
|
-
images =
|
|
161
|
+
links = LinkListField(read_only=True)
|
|
162
|
+
images = LinkListField(read_only=True, required=False)
|
|
157
163
|
|
|
158
164
|
|
|
159
165
|
class OPDS2GroupSerializer(Serializer):
|
|
160
166
|
"""Group."""
|
|
161
167
|
|
|
162
168
|
metadata = OPDS2MetadataSerializer(read_only=True)
|
|
163
|
-
links =
|
|
169
|
+
links = LinkListField(read_only=True, required=False)
|
|
164
170
|
publications = ListField(
|
|
165
171
|
child=OPDS2PublicationSerializer(), read_only=True, required=False
|
|
166
172
|
)
|
|
167
|
-
navigation =
|
|
173
|
+
navigation = LinkListField(read_only=True, required=False)
|
|
168
174
|
|
|
169
175
|
|
|
170
176
|
class OPDS2FeedSerializer(OPDS2GroupSerializer):
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from rest_framework.fields import CharField, DateTimeField, DecimalField, IntegerField
|
|
4
4
|
from rest_framework.serializers import ChoiceField, Serializer
|
|
5
5
|
|
|
6
|
-
from codex.serializers.opds.v2 import
|
|
6
|
+
from codex.serializers.opds.v2 import LinkListField
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class RecursiveField(Serializer):
|
|
@@ -15,9 +15,7 @@ class RecursiveField(Serializer):
|
|
|
15
15
|
|
|
16
16
|
def to_representation(self, instance):
|
|
17
17
|
"""Represent with own class."""
|
|
18
|
-
|
|
19
|
-
# Should not be ignored but is currently unused
|
|
20
|
-
serializer = parent.parent.__class__(instance, context=self.context) # type: ignore
|
|
18
|
+
serializer = self.parent.parent.__class__(instance, context=self.context)
|
|
21
19
|
return serializer.data
|
|
22
20
|
|
|
23
21
|
|
|
@@ -70,7 +68,7 @@ class OPDS2ProfileSerializer(Serializer):
|
|
|
70
68
|
|
|
71
69
|
name = CharField(read_only=True)
|
|
72
70
|
email = CharField(read_only=True)
|
|
73
|
-
links =
|
|
71
|
+
links = LinkListField(read_only=True, required=False)
|
|
74
72
|
loans = OPDS2CopiesSerializer(read_only=True)
|
|
75
73
|
holds = OPDS2HoldsSerializer(read_only=True)
|
|
76
74
|
|
codex/serializers/reader.py
CHANGED
|
@@ -4,15 +4,14 @@ from rest_framework.serializers import (
|
|
|
4
4
|
BooleanField,
|
|
5
5
|
CharField,
|
|
6
6
|
ChoiceField,
|
|
7
|
+
DateTimeField,
|
|
7
8
|
DecimalField,
|
|
8
9
|
IntegerField,
|
|
9
10
|
Serializer,
|
|
10
11
|
)
|
|
11
12
|
|
|
12
13
|
from codex.models import Bookmark
|
|
13
|
-
from codex.serializers.
|
|
14
|
-
from codex.serializers.fields import BreadcrumbsField, TimestampField, TopGroupField
|
|
15
|
-
from codex.serializers.route import RouteSerializer, SimpleRouteSerializer
|
|
14
|
+
from codex.serializers.route import RouteSerializer
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
class ReaderSettingsSerializer(Serializer):
|
|
@@ -26,8 +25,6 @@ class ReaderSettingsSerializer(Serializer):
|
|
|
26
25
|
two_pages = BooleanField(allow_null=True, required=False)
|
|
27
26
|
reading_direction = CharField(allow_null=True, required=False)
|
|
28
27
|
read_rtl_in_reverse = BooleanField(allow_null=True, required=False)
|
|
29
|
-
finish_on_last_page = BooleanField(allow_null=True, required=False)
|
|
30
|
-
mtime = TimestampField(read_only=True)
|
|
31
28
|
|
|
32
29
|
|
|
33
30
|
class ReaderComicSerializer(Serializer):
|
|
@@ -37,25 +34,15 @@ class ReaderComicSerializer(Serializer):
|
|
|
37
34
|
settings = ReaderSettingsSerializer(read_only=True)
|
|
38
35
|
max_page = IntegerField(read_only=True)
|
|
39
36
|
reading_direction = CharField(read_only=True)
|
|
40
|
-
mtime =
|
|
37
|
+
mtime = DateTimeField(format="%s", read_only=True)
|
|
41
38
|
|
|
42
39
|
|
|
43
|
-
class ReaderArcSerializer(
|
|
40
|
+
class ReaderArcSerializer(RouteSerializer):
|
|
44
41
|
"""Information about the current Arc."""
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
index = IntegerField(required=False)
|
|
48
|
-
count = IntegerField(required=False)
|
|
49
|
-
mtime = TimestampField(read_only=True)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class ReaderViewInputSerializer(Serializer):
|
|
53
|
-
"""Input for the reader serailizer."""
|
|
54
|
-
|
|
55
|
-
arc = ReaderArcSerializer(required=False)
|
|
56
|
-
breadcrumbs = BreadcrumbsField(required=False)
|
|
57
|
-
show = BrowserSettingsShowGroupFlagsSerializer(required=False)
|
|
58
|
-
top_group = TopGroupField(required=False)
|
|
43
|
+
page = None
|
|
44
|
+
index = IntegerField(read_only=True, required=False)
|
|
45
|
+
count = IntegerField(read_only=True, required=False)
|
|
59
46
|
|
|
60
47
|
|
|
61
48
|
class ReaderCurrentComicSerializer(ReaderComicSerializer):
|
|
@@ -97,4 +84,3 @@ class ReaderComicsSerializer(Serializer):
|
|
|
97
84
|
arcs = ReaderArcSerializer(many=True, read_only=True)
|
|
98
85
|
arc = ReaderArcSerializer(read_only=True)
|
|
99
86
|
close_route = RouteSerializer(read_only=True)
|
|
100
|
-
mtime = TimestampField(read_only=True)
|
codex/serializers/redirect.py
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"""Notification serializers."""
|
|
2
2
|
|
|
3
|
-
from rest_framework.serializers import CharField, Serializer
|
|
3
|
+
from rest_framework.serializers import CharField, JSONField, Serializer
|
|
4
4
|
|
|
5
5
|
from codex.serializers.browser.settings import BrowserSettingsSerializer
|
|
6
|
-
from codex.serializers.route import RouteSerializer
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
class ReaderRedirectSerializer(Serializer):
|
|
10
9
|
"""Reader 404 message."""
|
|
11
10
|
|
|
12
11
|
reason = CharField(read_only=True)
|
|
13
|
-
route =
|
|
12
|
+
route = JSONField(read_only=True)
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
class BrowserRedirectSerializer(ReaderRedirectSerializer):
|
codex/serializers/route.py
CHANGED
|
@@ -3,20 +3,18 @@
|
|
|
3
3
|
from rest_framework.fields import CharField, IntegerField
|
|
4
4
|
from rest_framework.serializers import Serializer
|
|
5
5
|
|
|
6
|
-
from codex.views.util import Route
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"""A an abbreviated vue route for the browser."""
|
|
7
|
+
class RouteSerializer(Serializer):
|
|
8
|
+
"""A vue route for the browser."""
|
|
11
9
|
|
|
12
10
|
group = CharField()
|
|
13
11
|
pks = CharField()
|
|
12
|
+
page = IntegerField()
|
|
13
|
+
name = CharField(required=False)
|
|
14
14
|
|
|
15
15
|
def to_representation(self, instance):
|
|
16
16
|
"""Allow submission of sequences instead of strings for pks."""
|
|
17
|
-
|
|
18
|
-
instance = instance.dict()
|
|
19
|
-
pks = instance["pks"]
|
|
17
|
+
pks = instance.get("pks")
|
|
20
18
|
if not pks:
|
|
21
19
|
instance["pks"] = "0"
|
|
22
20
|
elif not isinstance(pks, str):
|
|
@@ -30,16 +28,9 @@ class SimpleRouteSerializer(Serializer):
|
|
|
30
28
|
pks = instance.get("pks")
|
|
31
29
|
if isinstance(pks, str):
|
|
32
30
|
pks = tuple(sorted(int(pk) for pk in pks.split(",")))
|
|
33
|
-
if 0 in pks:
|
|
31
|
+
if 0 in pks:
|
|
34
32
|
pks = ()
|
|
35
|
-
instance["pks"] = tuple(pks)
|
|
33
|
+
instance["pks"] = tuple(pks)
|
|
36
34
|
except ValueError:
|
|
37
35
|
instance["pks"] = ()
|
|
38
36
|
return instance
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class RouteSerializer(SimpleRouteSerializer):
|
|
42
|
-
"""A vue route for the browser."""
|
|
43
|
-
|
|
44
|
-
page = IntegerField()
|
|
45
|
-
name = CharField(allow_blank=True, required=False)
|
codex/settings/settings.py
CHANGED
|
@@ -37,11 +37,10 @@ WRITER_MEMORY_PERCENT = float(environ.get("CODEX_WRITER_MEMORY_PERCENT", 0.6))
|
|
|
37
37
|
CPU_MULTIPLIER = float(environ.get("CODEX_CPU_MULTIPLIER", 1.25))
|
|
38
38
|
CHUNK_PER_GB = int(environ.get("CODEX_CHUNK_PER_GB", 250))
|
|
39
39
|
MAX_CHUNK_SIZE = int(environ.get("CODEX_MAX_CHUNK_SIZE", 1000))
|
|
40
|
-
# sqlite parser breaks with more than 1000 variables in a query and
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
FILTER_BATCH_SIZE = int(environ.get("CODEX_FILTER_BATCH_SIZE", 900))
|
|
40
|
+
# sqlite parser breaks with more than 1000 variables in a query and django only
|
|
41
|
+
# fixes this in the bulk_create & bulk_update functions. So for complicated
|
|
42
|
+
# queries I gotta batch them myself. Filter arg count is a proxy, but it works.
|
|
43
|
+
FILTER_BATCH_SIZE = int(environ.get("CODEX_FILTER_BATCH_SIZE", 990))
|
|
45
44
|
VITE_HOST = environ.get("VITE_HOST")
|
|
46
45
|
|
|
47
46
|
####################################
|
|
@@ -63,12 +62,7 @@ THROTTLE_OPENSEARCH = int(environ.get("CODEX_THROTTLE_OPENSEARCH", 0))
|
|
|
63
62
|
# Base paths
|
|
64
63
|
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
|
65
64
|
CODEX_PATH = BASE_DIR / "codex"
|
|
66
|
-
|
|
67
|
-
CUSTOM_COVERS_DIR = CONFIG_PATH / CUSTOM_COVERS_SUBDIR
|
|
68
|
-
CUSTOM_COVERS_GROUP_DIRS = ("publishers", "imprints", "series", "volumes", "story-arcs")
|
|
69
|
-
for group_dir in CUSTOM_COVERS_GROUP_DIRS:
|
|
70
|
-
custom_cover_group_dir = CUSTOM_COVERS_DIR / group_dir
|
|
71
|
-
custom_cover_group_dir.mkdir(exist_ok=True, parents=True)
|
|
65
|
+
CONFIG_PATH.mkdir(exist_ok=True, parents=True)
|
|
72
66
|
|
|
73
67
|
# SECURITY WARNING: keep the secret key used in production secret!
|
|
74
68
|
SECRET_KEY = get_secret_key(CONFIG_PATH)
|
|
@@ -291,9 +285,9 @@ REST_FRAMEWORK = {
|
|
|
291
285
|
"djangorestframework_camel_case.render.CamelCaseBrowsableAPIRenderer",
|
|
292
286
|
),
|
|
293
287
|
"DEFAULT_PARSER_CLASSES": (
|
|
288
|
+
"djangorestframework_camel_case.parser.CamelCaseFormParser",
|
|
289
|
+
"djangorestframework_camel_case.parser.CamelCaseMultiPartParser",
|
|
294
290
|
"djangorestframework_camel_case.parser.CamelCaseJSONParser",
|
|
295
|
-
# "djangorestframework_camel_case.parser.CamelCaseFormParser",
|
|
296
|
-
# "djangorestframework_camel_case.parser.CamelCaseMultiPartParser",
|
|
297
291
|
),
|
|
298
292
|
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
|
299
293
|
"EXCEPTION_HANDLER": "codex.views.error.codex_exception_handler",
|
|
@@ -325,18 +319,9 @@ REST_REGISTRATION = {
|
|
|
325
319
|
SPECTACULAR_SETTINGS = {
|
|
326
320
|
"TITLE": "Codex API",
|
|
327
321
|
"DESCRIPTION": "Comic Library Browser and Reader",
|
|
328
|
-
"OAS_VERSION": "3.1.0",
|
|
329
322
|
"VERSION": "3.0.0",
|
|
330
|
-
"CONTACT": {
|
|
331
|
-
"name": "Support",
|
|
332
|
-
"url": "https://github.com/ajslater/codex?tab=readme-ov-file#-support",
|
|
333
|
-
},
|
|
323
|
+
"CONTACT": {"name": "Repository", "url": "https://github.com/ajslater/codex/"},
|
|
334
324
|
"PREPROCESSING_HOOKS": ["codex.urls.spectacular.allow_list"],
|
|
335
|
-
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
|
|
336
|
-
"EXTERNAL_DOCS": {
|
|
337
|
-
"url": "https://github.com/ajslater/codex/",
|
|
338
|
-
"description": "Codex Docs",
|
|
339
|
-
},
|
|
340
325
|
}
|
|
341
326
|
|
|
342
327
|
CORS_ALLOW_CREDENTIALS = True
|