codex 1.6.0a10__py3-none-any.whl → 1.6.0a12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of codex might be problematic. Click here for more details.
- codex/librarian/covers/create.py +21 -16
- codex/serializers/browser/choices.py +23 -44
- codex/serializers/browser/filters.py +30 -36
- codex/serializers/browser/mixins.py +37 -4
- codex/serializers/browser/settings.py +10 -3
- codex/serializers/choices.py +4 -0
- codex/serializers/fields.py +75 -66
- codex/serializers/models/pycountry.py +11 -51
- codex/serializers/opds/v2.py +4 -6
- codex/serializers/reader.py +1 -0
- codex/static_root/assets/{VCheckbox-CY3rcqlS.de5154294920.js → VCheckbox-B3vCf1Vu.e1991f98ab6c.js} +1 -1
- codex/static_root/assets/VCheckbox-B3vCf1Vu.e1991f98ab6c.js.br +0 -0
- codex/static_root/assets/VCheckbox-B3vCf1Vu.e1991f98ab6c.js.gz +0 -0
- codex/static_root/assets/{VCheckbox-CY3rcqlS.js → VCheckbox-B3vCf1Vu.js} +1 -1
- codex/static_root/assets/VCheckbox-B3vCf1Vu.js.br +0 -0
- codex/static_root/assets/VCheckbox-B3vCf1Vu.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-D2tPTt6P.9a90d6818bf6.js → VCheckboxBtn-Cj6bUYmw.196cc43ca1c8.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-Cj6bUYmw.196cc43ca1c8.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-Cj6bUYmw.196cc43ca1c8.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-D2tPTt6P.js → VCheckboxBtn-Cj6bUYmw.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-Cj6bUYmw.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-Cj6bUYmw.js.gz +0 -0
- codex/static_root/assets/{VCombobox-aJr--Ou7.f290ccf2ce25.js → VCombobox-wIqJY8no.3547ff73e91e.js} +1 -1
- codex/static_root/assets/VCombobox-wIqJY8no.3547ff73e91e.js.br +0 -0
- codex/static_root/assets/VCombobox-wIqJY8no.3547ff73e91e.js.gz +0 -0
- codex/static_root/assets/{VCombobox-aJr--Ou7.js → VCombobox-wIqJY8no.js} +1 -1
- codex/static_root/assets/VCombobox-wIqJY8no.js.br +0 -0
- codex/static_root/assets/VCombobox-wIqJY8no.js.gz +0 -0
- codex/static_root/assets/{VDialog-61pzfUB2.33f73beb5224.js → VDialog-D6HUFV6a.ac71da510b3f.js} +1 -1
- codex/static_root/assets/VDialog-D6HUFV6a.ac71da510b3f.js.br +0 -0
- codex/static_root/assets/VDialog-D6HUFV6a.ac71da510b3f.js.gz +0 -0
- codex/static_root/assets/{VDialog-61pzfUB2.js → VDialog-D6HUFV6a.js} +1 -1
- codex/static_root/assets/VDialog-D6HUFV6a.js.br +0 -0
- codex/static_root/assets/VDialog-D6HUFV6a.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-rewm0P4z.5c7680f815b6.js → VExpansionPanels-BUJaYmzY.44e8a00a2ebe.js} +1 -1
- codex/static_root/assets/VExpansionPanels-BUJaYmzY.44e8a00a2ebe.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-BUJaYmzY.44e8a00a2ebe.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-rewm0P4z.js → VExpansionPanels-BUJaYmzY.js} +1 -1
- codex/static_root/assets/VExpansionPanels-BUJaYmzY.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-BUJaYmzY.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-QFQbK1qo.750a42b1b814.js → VRadioGroup-CayclHra.0a5b1c9a7b71.js} +1 -1
- codex/static_root/assets/VRadioGroup-CayclHra.0a5b1c9a7b71.js.br +0 -0
- codex/static_root/assets/VRadioGroup-CayclHra.0a5b1c9a7b71.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-QFQbK1qo.js → VRadioGroup-CayclHra.js} +1 -1
- codex/static_root/assets/VRadioGroup-CayclHra.js.br +0 -0
- codex/static_root/assets/VRadioGroup-CayclHra.js.gz +0 -0
- codex/static_root/assets/{VSelect-Dixy6okt.5d53830daa8a.js → VSelect-ou2Q9UaN.8ddd219784e1.js} +1 -1
- codex/static_root/assets/VSelect-ou2Q9UaN.8ddd219784e1.js.br +0 -0
- codex/static_root/assets/VSelect-ou2Q9UaN.8ddd219784e1.js.gz +0 -0
- codex/static_root/assets/{VSelect-Dixy6okt.js → VSelect-ou2Q9UaN.js} +1 -1
- codex/static_root/assets/VSelect-ou2Q9UaN.js.br +0 -0
- codex/static_root/assets/VSelect-ou2Q9UaN.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-MNmxKc3J.js → VSelectionControl-BOKIwNZb.16e0cdde978c.js} +1 -1
- codex/static_root/assets/VSelectionControl-BOKIwNZb.16e0cdde978c.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BOKIwNZb.16e0cdde978c.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-MNmxKc3J.08055d00917e.js → VSelectionControl-BOKIwNZb.js} +1 -1
- codex/static_root/assets/VSelectionControl-BOKIwNZb.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BOKIwNZb.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-DZEV0FoV.5f996daf0e98.js → VSlideGroup-C3XgVg2T.d2b0ee4f596c.js} +1 -1
- codex/static_root/assets/VSlideGroup-C3XgVg2T.d2b0ee4f596c.js.br +0 -0
- codex/static_root/assets/VSlideGroup-C3XgVg2T.d2b0ee4f596c.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-DZEV0FoV.js → VSlideGroup-C3XgVg2T.js} +1 -1
- codex/static_root/assets/VSlideGroup-C3XgVg2T.js.br +0 -0
- codex/static_root/assets/VSlideGroup-C3XgVg2T.js.gz +0 -0
- codex/static_root/assets/{VTable-lcnYg9Ee.d72927b13c2e.js → VTable-CrIiBr9q.b4669247af45.js} +1 -1
- codex/static_root/assets/VTable-CrIiBr9q.b4669247af45.js.br +0 -0
- codex/static_root/assets/VTable-CrIiBr9q.b4669247af45.js.gz +0 -0
- codex/static_root/assets/{VTable-lcnYg9Ee.js → VTable-CrIiBr9q.js} +1 -1
- codex/static_root/assets/VTable-CrIiBr9q.js.br +0 -0
- codex/static_root/assets/VTable-CrIiBr9q.js.gz +0 -0
- codex/static_root/assets/{VTextField-BkFrjhdV.js → VTextField-HAAxrpNi.6f6dcb50079a.js} +1 -1
- codex/static_root/assets/VTextField-HAAxrpNi.6f6dcb50079a.js.br +0 -0
- codex/static_root/assets/VTextField-HAAxrpNi.6f6dcb50079a.js.gz +0 -0
- codex/static_root/assets/{VTextField-BkFrjhdV.b02653a9b3b7.js → VTextField-HAAxrpNi.js} +1 -1
- codex/static_root/assets/VTextField-HAAxrpNi.js.br +0 -0
- codex/static_root/assets/VTextField-HAAxrpNi.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-C__tAqdc.9791c128c3b7.js → VWindowItem-aal6-Uv4.d178e2af20a7.js} +1 -1
- codex/static_root/assets/VWindowItem-aal6-Uv4.d178e2af20a7.js.br +0 -0
- codex/static_root/assets/VWindowItem-aal6-Uv4.d178e2af20a7.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-C__tAqdc.js → VWindowItem-aal6-Uv4.js} +1 -1
- codex/static_root/assets/VWindowItem-aal6-Uv4.js.br +0 -0
- codex/static_root/assets/VWindowItem-aal6-Uv4.js.gz +0 -0
- codex/static_root/assets/admin-D5JDmLDy.e4df3dd3a3fe.js +1 -0
- codex/static_root/assets/admin-D5JDmLDy.e4df3dd3a3fe.js.br +0 -0
- codex/static_root/assets/admin-D5JDmLDy.e4df3dd3a3fe.js.gz +0 -0
- codex/static_root/assets/admin-D5JDmLDy.js +1 -0
- codex/static_root/assets/admin-D5JDmLDy.js.br +0 -0
- codex/static_root/assets/admin-D5JDmLDy.js.gz +0 -0
- codex/static_root/assets/{admin-drawer-panel-rrNKi_GE.e2b034db7934.js → admin-drawer-panel-BF-h3Wm0.1f372db8d08f.js} +2 -2
- codex/static_root/assets/admin-drawer-panel-BF-h3Wm0.1f372db8d08f.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BF-h3Wm0.1f372db8d08f.js.gz +0 -0
- codex/static_root/assets/{admin-drawer-panel-rrNKi_GE.js → admin-drawer-panel-BF-h3Wm0.js} +2 -2
- codex/static_root/assets/admin-drawer-panel-BF-h3Wm0.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BF-h3Wm0.js.gz +0 -0
- codex/static_root/assets/browser-B1-dPld9.0b3fa4fdbe22.css +1 -0
- codex/static_root/assets/browser-B1-dPld9.0b3fa4fdbe22.css.br +0 -0
- codex/static_root/assets/browser-B1-dPld9.0b3fa4fdbe22.css.gz +0 -0
- codex/static_root/assets/browser-B1-dPld9.css +1 -0
- codex/static_root/assets/browser-B1-dPld9.css.br +0 -0
- codex/static_root/assets/browser-B1-dPld9.css.gz +0 -0
- codex/static_root/assets/browser-VhFkImB_.9c3b2c746614.js +1 -0
- codex/static_root/assets/browser-VhFkImB_.9c3b2c746614.js.br +0 -0
- codex/static_root/assets/browser-VhFkImB_.9c3b2c746614.js.gz +0 -0
- codex/static_root/assets/browser-VhFkImB_.js +1 -0
- codex/static_root/assets/browser-VhFkImB_.js.br +0 -0
- codex/static_root/assets/browser-VhFkImB_.js.gz +0 -0
- codex/static_root/assets/{change-password-dialog-Bn20jYzD.593c5af1732b.js → change-password-dialog-BCYw5K7E.a8bae0450f20.js} +1 -1
- codex/static_root/assets/change-password-dialog-BCYw5K7E.a8bae0450f20.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BCYw5K7E.a8bae0450f20.js.gz +0 -0
- codex/static_root/assets/{change-password-dialog-Bn20jYzD.js → change-password-dialog-BCYw5K7E.js} +1 -1
- codex/static_root/assets/change-password-dialog-BCYw5K7E.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BCYw5K7E.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-CWszioQE.859051c35dd9.js → confirm-dialog-c9JOSGSy.3c5788f95f47.js} +1 -1
- codex/static_root/assets/confirm-dialog-c9JOSGSy.3c5788f95f47.js.br +3 -0
- codex/static_root/assets/confirm-dialog-c9JOSGSy.3c5788f95f47.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-CWszioQE.js → confirm-dialog-c9JOSGSy.js} +1 -1
- codex/static_root/assets/confirm-dialog-c9JOSGSy.js.br +3 -0
- codex/static_root/assets/confirm-dialog-c9JOSGSy.js.gz +0 -0
- codex/static_root/assets/{datetime-column-BSdlLt-4.27ec2df67a0b.js → datetime-column-D-6LPKdI.d46bbd8134df.js} +1 -1
- codex/static_root/assets/datetime-column-D-6LPKdI.d46bbd8134df.js.br +0 -0
- codex/static_root/assets/datetime-column-D-6LPKdI.d46bbd8134df.js.gz +0 -0
- codex/static_root/assets/{datetime-column-BSdlLt-4.js → datetime-column-D-6LPKdI.js} +1 -1
- codex/static_root/assets/datetime-column-D-6LPKdI.js.br +0 -0
- codex/static_root/assets/datetime-column-D-6LPKdI.js.gz +0 -0
- codex/static_root/assets/{filter-D3gaGf87.1f14dbfd9929.js → filter-BOnVoHTU.93c3d0d0d3f6.js} +1 -1
- codex/static_root/assets/filter-BOnVoHTU.93c3d0d0d3f6.js.br +0 -0
- codex/static_root/assets/filter-BOnVoHTU.93c3d0d0d3f6.js.gz +0 -0
- codex/static_root/assets/{filter-D3gaGf87.js → filter-BOnVoHTU.js} +1 -1
- codex/static_root/assets/filter-BOnVoHTU.js.br +0 -0
- codex/static_root/assets/filter-BOnVoHTU.js.gz +0 -0
- codex/static_root/assets/{flag-tab-8vzpdySX.a982c7f0776a.js → flag-tab-IniE-dLy.a02733e359aa.js} +1 -1
- codex/static_root/assets/flag-tab-IniE-dLy.a02733e359aa.js.br +0 -0
- codex/static_root/assets/flag-tab-IniE-dLy.a02733e359aa.js.gz +0 -0
- codex/static_root/assets/{flag-tab-8vzpdySX.js → flag-tab-IniE-dLy.js} +1 -1
- codex/static_root/assets/flag-tab-IniE-dLy.js.br +0 -0
- codex/static_root/assets/flag-tab-IniE-dLy.js.gz +0 -0
- codex/static_root/assets/{group-tab-Cz9t_ECi.a9e8aea79254.js → group-tab-RPa8XC0J.3d483919ea92.js} +1 -1
- codex/static_root/assets/group-tab-RPa8XC0J.3d483919ea92.js.br +0 -0
- codex/static_root/assets/group-tab-RPa8XC0J.3d483919ea92.js.gz +0 -0
- codex/static_root/assets/{group-tab-Cz9t_ECi.js → group-tab-RPa8XC0J.js} +1 -1
- codex/static_root/assets/group-tab-RPa8XC0J.js.br +0 -0
- codex/static_root/assets/group-tab-RPa8XC0J.js.gz +0 -0
- codex/static_root/assets/{http-error-Cqtszzf1.b31df3d9c29f.js → http-error-DBQycf8i.561cde2b4598.js} +1 -1
- codex/static_root/assets/http-error-DBQycf8i.561cde2b4598.js.br +0 -0
- codex/static_root/assets/http-error-DBQycf8i.561cde2b4598.js.gz +0 -0
- codex/static_root/assets/{http-error-Cqtszzf1.js → http-error-DBQycf8i.js} +1 -1
- codex/static_root/assets/http-error-DBQycf8i.js.br +0 -0
- codex/static_root/assets/http-error-DBQycf8i.js.gz +0 -0
- codex/static_root/assets/{library-tab-DMlnswUU.js → library-tab-C5trLvkq.35c7a1b79c71.js} +1 -1
- codex/static_root/assets/library-tab-C5trLvkq.35c7a1b79c71.js.br +0 -0
- codex/static_root/assets/library-tab-C5trLvkq.35c7a1b79c71.js.gz +0 -0
- codex/static_root/assets/{library-tab-DMlnswUU.30f454e84184.js → library-tab-C5trLvkq.js} +1 -1
- codex/static_root/assets/library-tab-C5trLvkq.js.br +0 -0
- codex/static_root/assets/library-tab-C5trLvkq.js.gz +0 -0
- codex/static_root/assets/main-x0Pcl23A.364bfe447c9c.js +32 -0
- codex/static_root/assets/main-x0Pcl23A.364bfe447c9c.js.br +0 -0
- codex/static_root/assets/main-x0Pcl23A.364bfe447c9c.js.gz +0 -0
- codex/static_root/assets/main-x0Pcl23A.js +32 -0
- codex/static_root/assets/main-x0Pcl23A.js.br +0 -0
- codex/static_root/assets/main-x0Pcl23A.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BLUoVz2y.50051431acf1.css +1 -0
- codex/static_root/assets/pagination-toolbar-BLUoVz2y.50051431acf1.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-BLUoVz2y.50051431acf1.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BLUoVz2y.css +1 -0
- codex/static_root/assets/pagination-toolbar-BLUoVz2y.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-BLUoVz2y.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-DEgDOzzp.71aa03f525e4.js +1 -0
- codex/static_root/assets/pagination-toolbar-DEgDOzzp.71aa03f525e4.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-DEgDOzzp.71aa03f525e4.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-DEgDOzzp.js +1 -0
- codex/static_root/assets/pagination-toolbar-DEgDOzzp.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-DEgDOzzp.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-BiamrjRZ.4c9be1ade43c.js → pdf-doc-CkV-xfvG.35c1a6a19a41.js} +1 -1
- codex/static_root/assets/pdf-doc-CkV-xfvG.35c1a6a19a41.js.br +0 -0
- codex/static_root/assets/pdf-doc-CkV-xfvG.35c1a6a19a41.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-BiamrjRZ.js → pdf-doc-CkV-xfvG.js} +1 -1
- codex/static_root/assets/pdf-doc-CkV-xfvG.js.br +0 -0
- codex/static_root/assets/pdf-doc-CkV-xfvG.js.gz +0 -0
- codex/static_root/assets/reader-ClcgSG93.6afe950e70ac.js +2 -0
- codex/static_root/assets/reader-ClcgSG93.6afe950e70ac.js.br +0 -0
- codex/static_root/assets/reader-ClcgSG93.6afe950e70ac.js.gz +0 -0
- codex/static_root/assets/reader-ClcgSG93.js +2 -0
- codex/static_root/assets/reader-ClcgSG93.js.br +0 -0
- codex/static_root/assets/reader-ClcgSG93.js.gz +0 -0
- codex/static_root/assets/{reader-BpsctRsY.5d72e393911a.css → reader-CqXFa_gE.78267e9de0c2.css} +1 -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-BpsctRsY.css → reader-CqXFa_gE.css} +1 -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-C5acBjpy.dc67d4528868.js → relation-chips-2vga5ApB.d94c344f909b.js} +1 -1
- codex/static_root/assets/relation-chips-2vga5ApB.d94c344f909b.js.br +0 -0
- codex/static_root/assets/relation-chips-2vga5ApB.d94c344f909b.js.gz +0 -0
- codex/static_root/assets/{relation-chips-C5acBjpy.js → relation-chips-2vga5ApB.js} +1 -1
- codex/static_root/assets/relation-chips-2vga5ApB.js.br +0 -0
- codex/static_root/assets/relation-chips-2vga5ApB.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-D_JuRi7F.f02f3f981f8f.js → settings-drawer-BOTI_tHr.03748f801e08.js} +2 -2
- codex/static_root/assets/settings-drawer-BOTI_tHr.03748f801e08.js.br +0 -0
- codex/static_root/assets/settings-drawer-BOTI_tHr.03748f801e08.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-D_JuRi7F.js → settings-drawer-BOTI_tHr.js} +2 -2
- codex/static_root/assets/settings-drawer-BOTI_tHr.js.br +0 -0
- codex/static_root/assets/settings-drawer-BOTI_tHr.js.gz +0 -0
- codex/static_root/assets/{stats-tab-ClqRTk1z.c759ace65a87.js → stats-tab-CBz_jhmH.9bdc41225f06.js} +1 -1
- codex/static_root/assets/stats-tab-CBz_jhmH.9bdc41225f06.js.br +0 -0
- codex/static_root/assets/stats-tab-CBz_jhmH.9bdc41225f06.js.gz +0 -0
- codex/static_root/assets/{stats-tab-ClqRTk1z.js → stats-tab-CBz_jhmH.js} +1 -1
- codex/static_root/assets/stats-tab-CBz_jhmH.js.br +0 -0
- codex/static_root/assets/stats-tab-CBz_jhmH.js.gz +0 -0
- codex/static_root/assets/{task-tab-DF9qa6LO.0b32cafde4ad.js → task-tab-B8sYV6Ia.90a8deec0214.js} +1 -1
- codex/static_root/assets/task-tab-B8sYV6Ia.90a8deec0214.js.br +0 -0
- codex/static_root/assets/task-tab-B8sYV6Ia.90a8deec0214.js.gz +0 -0
- codex/static_root/assets/{task-tab-DF9qa6LO.js → task-tab-B8sYV6Ia.js} +1 -1
- codex/static_root/assets/task-tab-B8sYV6Ia.js.br +0 -0
- codex/static_root/assets/task-tab-B8sYV6Ia.js.gz +0 -0
- codex/static_root/assets/to-case-CnnzURtN.f0e4b42ddb89.js +1 -0
- codex/static_root/assets/to-case-CnnzURtN.js +1 -0
- codex/static_root/assets/{unauthorized-BjKuLH6k.2ae00ddd79fb.js → unauthorized-D5-FvA2_.61b1cd239b47.js} +1 -1
- codex/static_root/assets/unauthorized-D5-FvA2_.61b1cd239b47.js.br +0 -0
- codex/static_root/assets/unauthorized-D5-FvA2_.61b1cd239b47.js.gz +0 -0
- codex/static_root/assets/{unauthorized-BjKuLH6k.js → unauthorized-D5-FvA2_.js} +1 -1
- codex/static_root/assets/unauthorized-D5-FvA2_.js.br +0 -0
- codex/static_root/assets/unauthorized-D5-FvA2_.js.gz +0 -0
- codex/static_root/assets/{user-tab-Dpxe3ygA.7d90174631f0.js → user-tab-pzFjrggM.97c02ebee729.js} +1 -1
- codex/static_root/assets/user-tab-pzFjrggM.97c02ebee729.js.br +0 -0
- codex/static_root/assets/user-tab-pzFjrggM.97c02ebee729.js.gz +0 -0
- codex/static_root/assets/{user-tab-Dpxe3ygA.js → user-tab-pzFjrggM.js} +1 -1
- codex/static_root/assets/user-tab-pzFjrggM.js.br +0 -0
- codex/static_root/assets/user-tab-pzFjrggM.js.gz +0 -0
- codex/static_root/js/{choices.a0aaaa6c7ef7.json → choices.2f6b0359e1ef.json} +1 -1
- codex/static_root/js/choices.2f6b0359e1ef.json.br +0 -0
- codex/static_root/js/choices.2f6b0359e1ef.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.35e46a3ec8fa.json → manifest.a18726680d5f.json} +223 -223
- codex/static_root/manifest.a18726680d5f.json.br +0 -0
- codex/static_root/manifest.a18726680d5f.json.gz +0 -0
- codex/static_root/manifest.json +223 -223
- codex/static_root/manifest.json.br +0 -0
- codex/static_root/manifest.json.gz +0 -0
- codex/static_root/staticfiles.json +1 -1
- codex/util.py +8 -6
- codex/views/bookmark.py +29 -23
- codex/views/browser/annotations.py +9 -45
- codex/views/browser/browser.py +26 -6
- codex/views/browser/choices.py +4 -22
- codex/views/browser/cover.py +35 -11
- codex/views/browser/filters/annotations.py +23 -8
- codex/views/browser/metadata.py +22 -12
- codex/views/const.py +1 -1
- codex/views/reader/init.py +16 -12
- codex/views/reader/page.py +13 -2
- codex/views/session.py +3 -1
- codex/views/util.py +13 -0
- codex/websockets/consumers.py +1 -1
- {codex-1.6.0a10.dist-info → codex-1.6.0a12.dist-info}/METADATA +1 -1
- {codex-1.6.0a10.dist-info → codex-1.6.0a12.dist-info}/RECORD +260 -262
- codex/static_root/assets/VCheckbox-CY3rcqlS.de5154294920.js.br +0 -0
- codex/static_root/assets/VCheckbox-CY3rcqlS.de5154294920.js.gz +0 -0
- codex/static_root/assets/VCheckbox-CY3rcqlS.js.br +0 -0
- codex/static_root/assets/VCheckbox-CY3rcqlS.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-D2tPTt6P.9a90d6818bf6.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-D2tPTt6P.9a90d6818bf6.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-D2tPTt6P.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-D2tPTt6P.js.gz +0 -0
- codex/static_root/assets/VCombobox-aJr--Ou7.f290ccf2ce25.js.br +0 -0
- codex/static_root/assets/VCombobox-aJr--Ou7.f290ccf2ce25.js.gz +0 -0
- codex/static_root/assets/VCombobox-aJr--Ou7.js.br +0 -0
- codex/static_root/assets/VCombobox-aJr--Ou7.js.gz +0 -0
- codex/static_root/assets/VDialog-61pzfUB2.33f73beb5224.js.br +0 -0
- codex/static_root/assets/VDialog-61pzfUB2.33f73beb5224.js.gz +0 -0
- codex/static_root/assets/VDialog-61pzfUB2.js.br +0 -0
- codex/static_root/assets/VDialog-61pzfUB2.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-rewm0P4z.5c7680f815b6.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-rewm0P4z.5c7680f815b6.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-rewm0P4z.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-rewm0P4z.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-QFQbK1qo.750a42b1b814.js.br +0 -0
- codex/static_root/assets/VRadioGroup-QFQbK1qo.750a42b1b814.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-QFQbK1qo.js.br +0 -0
- codex/static_root/assets/VRadioGroup-QFQbK1qo.js.gz +0 -0
- codex/static_root/assets/VSelect-Dixy6okt.5d53830daa8a.js.br +0 -0
- codex/static_root/assets/VSelect-Dixy6okt.5d53830daa8a.js.gz +0 -0
- codex/static_root/assets/VSelect-Dixy6okt.js.br +0 -0
- codex/static_root/assets/VSelect-Dixy6okt.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-MNmxKc3J.08055d00917e.js.br +0 -0
- codex/static_root/assets/VSelectionControl-MNmxKc3J.08055d00917e.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-MNmxKc3J.js.br +0 -0
- codex/static_root/assets/VSelectionControl-MNmxKc3J.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-DZEV0FoV.5f996daf0e98.js.br +0 -0
- codex/static_root/assets/VSlideGroup-DZEV0FoV.5f996daf0e98.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-DZEV0FoV.js.br +0 -0
- codex/static_root/assets/VSlideGroup-DZEV0FoV.js.gz +0 -0
- codex/static_root/assets/VTable-lcnYg9Ee.d72927b13c2e.js.br +0 -0
- codex/static_root/assets/VTable-lcnYg9Ee.d72927b13c2e.js.gz +0 -0
- codex/static_root/assets/VTable-lcnYg9Ee.js.br +0 -0
- codex/static_root/assets/VTable-lcnYg9Ee.js.gz +0 -0
- codex/static_root/assets/VTextField-BkFrjhdV.b02653a9b3b7.js.br +0 -0
- codex/static_root/assets/VTextField-BkFrjhdV.b02653a9b3b7.js.gz +0 -0
- codex/static_root/assets/VTextField-BkFrjhdV.js.br +0 -0
- codex/static_root/assets/VTextField-BkFrjhdV.js.gz +0 -0
- codex/static_root/assets/VWindowItem-C__tAqdc.9791c128c3b7.js.br +0 -0
- codex/static_root/assets/VWindowItem-C__tAqdc.9791c128c3b7.js.gz +0 -0
- codex/static_root/assets/VWindowItem-C__tAqdc.js.br +0 -0
- codex/static_root/assets/VWindowItem-C__tAqdc.js.gz +0 -0
- codex/static_root/assets/admin-CXES2HXe.9e48a9bf84e0.js +0 -1
- codex/static_root/assets/admin-CXES2HXe.9e48a9bf84e0.js.br +0 -0
- codex/static_root/assets/admin-CXES2HXe.9e48a9bf84e0.js.gz +0 -0
- codex/static_root/assets/admin-CXES2HXe.js +0 -1
- codex/static_root/assets/admin-CXES2HXe.js.br +0 -0
- codex/static_root/assets/admin-CXES2HXe.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-rrNKi_GE.e2b034db7934.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-rrNKi_GE.e2b034db7934.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-rrNKi_GE.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-rrNKi_GE.js.gz +0 -0
- codex/static_root/assets/browser-BuDeXGEe.css +0 -1
- codex/static_root/assets/browser-BuDeXGEe.css.br +0 -0
- codex/static_root/assets/browser-BuDeXGEe.css.gz +0 -0
- codex/static_root/assets/browser-BuDeXGEe.f60854183b45.css +0 -1
- codex/static_root/assets/browser-BuDeXGEe.f60854183b45.css.br +0 -0
- codex/static_root/assets/browser-BuDeXGEe.f60854183b45.css.gz +0 -0
- codex/static_root/assets/browser-s6mFzrK9.0d2200b451af.js +0 -1
- codex/static_root/assets/browser-s6mFzrK9.0d2200b451af.js.br +0 -0
- codex/static_root/assets/browser-s6mFzrK9.0d2200b451af.js.gz +0 -0
- codex/static_root/assets/browser-s6mFzrK9.js +0 -1
- codex/static_root/assets/browser-s6mFzrK9.js.br +0 -0
- codex/static_root/assets/browser-s6mFzrK9.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-Bn20jYzD.593c5af1732b.js.br +0 -0
- codex/static_root/assets/change-password-dialog-Bn20jYzD.593c5af1732b.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-Bn20jYzD.js.br +0 -0
- codex/static_root/assets/change-password-dialog-Bn20jYzD.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-CWszioQE.859051c35dd9.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CWszioQE.859051c35dd9.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-CWszioQE.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CWszioQE.js.gz +0 -0
- codex/static_root/assets/datetime-column-BSdlLt-4.27ec2df67a0b.js.br +0 -0
- codex/static_root/assets/datetime-column-BSdlLt-4.27ec2df67a0b.js.gz +0 -0
- codex/static_root/assets/datetime-column-BSdlLt-4.js.br +0 -0
- codex/static_root/assets/datetime-column-BSdlLt-4.js.gz +0 -0
- codex/static_root/assets/filter-D3gaGf87.1f14dbfd9929.js.br +0 -0
- codex/static_root/assets/filter-D3gaGf87.1f14dbfd9929.js.gz +0 -0
- codex/static_root/assets/filter-D3gaGf87.js.br +0 -0
- codex/static_root/assets/filter-D3gaGf87.js.gz +0 -0
- codex/static_root/assets/flag-tab-8vzpdySX.a982c7f0776a.js.br +0 -0
- codex/static_root/assets/flag-tab-8vzpdySX.a982c7f0776a.js.gz +0 -0
- codex/static_root/assets/flag-tab-8vzpdySX.js.br +0 -0
- codex/static_root/assets/flag-tab-8vzpdySX.js.gz +0 -0
- codex/static_root/assets/group-tab-Cz9t_ECi.a9e8aea79254.js.br +0 -0
- codex/static_root/assets/group-tab-Cz9t_ECi.a9e8aea79254.js.gz +0 -0
- codex/static_root/assets/group-tab-Cz9t_ECi.js.br +0 -0
- codex/static_root/assets/group-tab-Cz9t_ECi.js.gz +0 -0
- codex/static_root/assets/http-error-Cqtszzf1.b31df3d9c29f.js.br +0 -0
- codex/static_root/assets/http-error-Cqtszzf1.b31df3d9c29f.js.gz +0 -0
- codex/static_root/assets/http-error-Cqtszzf1.js.br +0 -0
- codex/static_root/assets/http-error-Cqtszzf1.js.gz +0 -0
- codex/static_root/assets/library-tab-DMlnswUU.30f454e84184.js.br +0 -0
- codex/static_root/assets/library-tab-DMlnswUU.30f454e84184.js.gz +0 -0
- codex/static_root/assets/library-tab-DMlnswUU.js.br +0 -0
- codex/static_root/assets/library-tab-DMlnswUU.js.gz +0 -0
- codex/static_root/assets/main-vjXu_QYL.548bd4c38799.js +0 -32
- codex/static_root/assets/main-vjXu_QYL.548bd4c38799.js.br +0 -0
- codex/static_root/assets/main-vjXu_QYL.548bd4c38799.js.gz +0 -0
- codex/static_root/assets/main-vjXu_QYL.js +0 -32
- codex/static_root/assets/main-vjXu_QYL.js.br +0 -0
- codex/static_root/assets/main-vjXu_QYL.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-DGdMiBRs.5829b01b8a2f.css +0 -1
- codex/static_root/assets/pagination-toolbar-DGdMiBRs.5829b01b8a2f.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-DGdMiBRs.5829b01b8a2f.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-DGdMiBRs.css +0 -1
- codex/static_root/assets/pagination-toolbar-DGdMiBRs.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-DGdMiBRs.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-JW78pa0q.91024effdab9.js +0 -1
- codex/static_root/assets/pagination-toolbar-JW78pa0q.91024effdab9.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-JW78pa0q.91024effdab9.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-JW78pa0q.js +0 -1
- codex/static_root/assets/pagination-toolbar-JW78pa0q.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-JW78pa0q.js.gz +0 -0
- codex/static_root/assets/pdf-doc-BiamrjRZ.4c9be1ade43c.js.br +0 -0
- codex/static_root/assets/pdf-doc-BiamrjRZ.4c9be1ade43c.js.gz +0 -0
- codex/static_root/assets/pdf-doc-BiamrjRZ.js.br +0 -0
- codex/static_root/assets/pdf-doc-BiamrjRZ.js.gz +0 -0
- codex/static_root/assets/reader-BpsctRsY.5d72e393911a.css.br +0 -0
- codex/static_root/assets/reader-BpsctRsY.5d72e393911a.css.gz +0 -0
- codex/static_root/assets/reader-BpsctRsY.css.br +0 -0
- codex/static_root/assets/reader-BpsctRsY.css.gz +0 -0
- codex/static_root/assets/reader-CDk8oZzB.ad62eebda920.js +0 -2
- codex/static_root/assets/reader-CDk8oZzB.ad62eebda920.js.br +0 -0
- codex/static_root/assets/reader-CDk8oZzB.ad62eebda920.js.gz +0 -0
- codex/static_root/assets/reader-CDk8oZzB.js +0 -2
- codex/static_root/assets/reader-CDk8oZzB.js.br +0 -0
- codex/static_root/assets/reader-CDk8oZzB.js.gz +0 -0
- codex/static_root/assets/relation-chips-C5acBjpy.dc67d4528868.js.br +0 -0
- codex/static_root/assets/relation-chips-C5acBjpy.dc67d4528868.js.gz +0 -0
- codex/static_root/assets/relation-chips-C5acBjpy.js.br +0 -0
- codex/static_root/assets/relation-chips-C5acBjpy.js.gz +0 -0
- codex/static_root/assets/settings-drawer-D_JuRi7F.f02f3f981f8f.js.br +0 -0
- codex/static_root/assets/settings-drawer-D_JuRi7F.f02f3f981f8f.js.gz +0 -0
- codex/static_root/assets/settings-drawer-D_JuRi7F.js.br +0 -0
- codex/static_root/assets/settings-drawer-D_JuRi7F.js.gz +0 -0
- codex/static_root/assets/stats-tab-ClqRTk1z.c759ace65a87.js.br +0 -0
- codex/static_root/assets/stats-tab-ClqRTk1z.c759ace65a87.js.gz +0 -0
- codex/static_root/assets/stats-tab-ClqRTk1z.js.br +0 -0
- codex/static_root/assets/stats-tab-ClqRTk1z.js.gz +0 -0
- codex/static_root/assets/task-tab-DF9qa6LO.0b32cafde4ad.js.br +0 -0
- codex/static_root/assets/task-tab-DF9qa6LO.0b32cafde4ad.js.gz +0 -0
- codex/static_root/assets/task-tab-DF9qa6LO.js.br +0 -0
- codex/static_root/assets/task-tab-DF9qa6LO.js.gz +0 -0
- codex/static_root/assets/to-case-CGbULRaE.4c80644f460d.js +0 -1
- codex/static_root/assets/to-case-CGbULRaE.4c80644f460d.js.br +0 -0
- codex/static_root/assets/to-case-CGbULRaE.js +0 -1
- codex/static_root/assets/to-case-CGbULRaE.js.br +0 -0
- codex/static_root/assets/unauthorized-BjKuLH6k.2ae00ddd79fb.js.br +0 -0
- codex/static_root/assets/unauthorized-BjKuLH6k.2ae00ddd79fb.js.gz +0 -0
- codex/static_root/assets/unauthorized-BjKuLH6k.js.br +0 -0
- codex/static_root/assets/unauthorized-BjKuLH6k.js.gz +0 -0
- codex/static_root/assets/user-tab-Dpxe3ygA.7d90174631f0.js.br +0 -0
- codex/static_root/assets/user-tab-Dpxe3ygA.7d90174631f0.js.gz +0 -0
- codex/static_root/assets/user-tab-Dpxe3ygA.js.br +0 -0
- codex/static_root/assets/user-tab-Dpxe3ygA.js.gz +0 -0
- codex/static_root/js/choices.a0aaaa6c7ef7.json.br +0 -0
- codex/static_root/js/choices.a0aaaa6c7ef7.json.gz +0 -0
- codex/static_root/manifest.35e46a3ec8fa.json.br +0 -0
- codex/static_root/manifest.35e46a3ec8fa.json.gz +0 -0
- {codex-1.6.0a10.dist-info → codex-1.6.0a12.dist-info}/LICENSE +0 -0
- {codex-1.6.0a10.dist-info → codex-1.6.0a12.dist-info}/WHEEL +0 -0
- {codex-1.6.0a10.dist-info → codex-1.6.0a12.dist-info}/entry_points.txt +0 -0
codex/views/browser/metadata.py
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from types import MappingProxyType
|
|
4
4
|
|
|
5
|
-
from django.core.exceptions import FieldDoesNotExist
|
|
6
5
|
from django.db.models import Count, IntegerField, Sum, Value
|
|
7
6
|
from drf_spectacular.utils import extend_schema
|
|
8
7
|
from rest_framework.exceptions import NotFound
|
|
@@ -15,6 +14,7 @@ from codex.logger.logging import get_logger
|
|
|
15
14
|
from codex.models import AdminFlag, Comic
|
|
16
15
|
from codex.models.functions import JsonGroupArray
|
|
17
16
|
from codex.serializers.browser.metadata import PREFETCH_PREFIX, MetadataSerializer
|
|
17
|
+
from codex.serializers.browser.settings import BrowserFilterChoicesInputSerilalizer
|
|
18
18
|
from codex.views.browser.annotations import BrowserAnnotationsView
|
|
19
19
|
from codex.views.const import METADATA_GROUP_RELATION
|
|
20
20
|
|
|
@@ -42,13 +42,28 @@ _COMIC_RELATED_VALUE_FIELDS = frozenset({"series__volume_count", "volume__issue_
|
|
|
42
42
|
_PATH_GROUPS = frozenset({"c", "f"})
|
|
43
43
|
_CONTRIBUTOR_RELATIONS = ("role", "person")
|
|
44
44
|
_SUM_FIELDS = frozenset({"page_count", "size"})
|
|
45
|
-
_GROUP_RELS =
|
|
45
|
+
_GROUP_RELS = MappingProxyType(
|
|
46
|
+
{
|
|
47
|
+
"i": ("publisher",),
|
|
48
|
+
"s": (
|
|
49
|
+
"publisher",
|
|
50
|
+
"imprint",
|
|
51
|
+
),
|
|
52
|
+
"v": (
|
|
53
|
+
"publisher",
|
|
54
|
+
"imprint",
|
|
55
|
+
"series",
|
|
56
|
+
),
|
|
57
|
+
"c": ("publisher", "imprint", "series", "volume"),
|
|
58
|
+
}
|
|
59
|
+
)
|
|
46
60
|
|
|
47
61
|
|
|
48
62
|
class MetadataView(BrowserAnnotationsView):
|
|
49
63
|
"""Comic metadata."""
|
|
50
64
|
|
|
51
65
|
serializer_class = MetadataSerializer
|
|
66
|
+
input_serializer_class = BrowserFilterChoicesInputSerilalizer
|
|
52
67
|
TARGET = "metadata"
|
|
53
68
|
ADMIN_FLAG_VALUE_KEY_MAP = MappingProxyType(
|
|
54
69
|
{
|
|
@@ -156,19 +171,15 @@ class MetadataView(BrowserAnnotationsView):
|
|
|
156
171
|
pks = self.kwargs["pks"]
|
|
157
172
|
group_filter = {rel: pks}
|
|
158
173
|
|
|
159
|
-
for field_name in _GROUP_RELS:
|
|
160
|
-
|
|
161
|
-
field = self.model._meta.get_field(field_name)
|
|
162
|
-
except FieldDoesNotExist:
|
|
163
|
-
continue
|
|
174
|
+
for field_name in _GROUP_RELS.get(group, ()):
|
|
175
|
+
field = self.model._meta.get_field(field_name)
|
|
164
176
|
model = field.related_model
|
|
165
177
|
if not model:
|
|
166
178
|
continue
|
|
167
179
|
|
|
168
180
|
qs = model.objects.filter(**group_filter)
|
|
169
181
|
qs = qs.only("name").distinct()
|
|
170
|
-
|
|
171
|
-
qs = qs.group_by(group_by)
|
|
182
|
+
qs = qs.group_by("name")
|
|
172
183
|
qs = qs.annotate(ids=JsonGroupArray("id", distinct=True))
|
|
173
184
|
qs = qs.values("ids", "name")
|
|
174
185
|
groups[field_name] = qs
|
|
@@ -228,8 +239,7 @@ class MetadataView(BrowserAnnotationsView):
|
|
|
228
239
|
if self.model and not self.is_model_comic:
|
|
229
240
|
# move the name of the group to the correct field
|
|
230
241
|
field = self.model.__name__.lower() + "_list"
|
|
231
|
-
|
|
232
|
-
group_list = [group_obj]
|
|
242
|
+
group_list = self.model.objects.filter(pk__in=obj.ids).values("name")
|
|
233
243
|
setattr(obj, field, group_list)
|
|
234
244
|
obj.name = None
|
|
235
245
|
|
|
@@ -312,7 +322,7 @@ class MetadataView(BrowserAnnotationsView):
|
|
|
312
322
|
m2m_intersections = self._query_m2m_intersections(filtered_qs)
|
|
313
323
|
return self._copy_annotations_into_comic_fields(obj, groups, m2m_intersections) # type: ignore
|
|
314
324
|
|
|
315
|
-
@extend_schema(parameters=[
|
|
325
|
+
@extend_schema(parameters=[input_serializer_class])
|
|
316
326
|
def get(self, *_args, **_kwargs):
|
|
317
327
|
"""Get metadata for a filtered browse group."""
|
|
318
328
|
# Init
|
codex/views/const.py
CHANGED
|
@@ -157,4 +157,4 @@ EPOCH_START = datetime.fromtimestamp(0, tz=timezone.utc)
|
|
|
157
157
|
ONE_INTEGERFIELD = Value(1, PositiveSmallIntegerField())
|
|
158
158
|
NONE_INTEGERFIELD = Value(None, PositiveSmallIntegerField())
|
|
159
159
|
NONE_DATETIMEFIELD = Value(None, DateTimeField())
|
|
160
|
-
|
|
160
|
+
EPOCH_START_DATETIMEFIELD = Value(EPOCH_START)
|
codex/views/reader/init.py
CHANGED
|
@@ -107,15 +107,19 @@ class ReaderInitView(SessionView):
|
|
|
107
107
|
params["arc"] = arc
|
|
108
108
|
|
|
109
109
|
def _parse_params(self):
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
110
|
+
try:
|
|
111
|
+
data = self.request.GET
|
|
112
|
+
data = reparse_json_query_params(self.request.GET, _JSON_KEYS)
|
|
113
|
+
serializer = self.input_serializer_class(data=data)
|
|
114
|
+
serializer.is_valid(raise_exception=True)
|
|
115
|
+
|
|
116
|
+
params = deepcopy(_DEFAULT_PARAMS)
|
|
117
|
+
if serializer.validated_data:
|
|
118
|
+
params.update(serializer.validated_data) # type: ignore
|
|
119
|
+
self._ensure_arc_contains_comic(params)
|
|
120
|
+
self._ensure_arc(params)
|
|
121
|
+
|
|
122
|
+
self.params = MappingProxyType(params)
|
|
123
|
+
except Exception:
|
|
124
|
+
LOG.exception("validate")
|
|
125
|
+
raise
|
codex/views/reader/page.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""Views for reading comic books."""
|
|
2
2
|
|
|
3
|
+
from io import BytesIO
|
|
4
|
+
|
|
3
5
|
from comicbox.box import Comicbox
|
|
4
|
-
from django.http import
|
|
6
|
+
from django.http.response import StreamingHttpResponse
|
|
5
7
|
from drf_spectacular.types import OpenApiTypes
|
|
6
8
|
from drf_spectacular.utils import OpenApiParameter, extend_schema
|
|
7
9
|
from rest_framework.exceptions import NotFound
|
|
@@ -11,9 +13,13 @@ from codex.logger.logging import get_logger
|
|
|
11
13
|
from codex.models import Comic
|
|
12
14
|
from codex.views.bookmark import BookmarkBaseView
|
|
13
15
|
from codex.views.const import FALSY
|
|
16
|
+
from codex.views.util import chunker
|
|
14
17
|
|
|
15
18
|
LOG = get_logger(__name__)
|
|
16
19
|
_PDF_MIME_TYPE = "application/pdf"
|
|
20
|
+
# Most pages seem to be 2.5 Mb
|
|
21
|
+
# largest pages I've seen were 9 Mb
|
|
22
|
+
_PAGE_CHUNK_SIZE = (1024**2) * 3 # 3 Mb
|
|
17
23
|
|
|
18
24
|
|
|
19
25
|
class IgnoreClientContentNegotiation(BaseContentNegotiation):
|
|
@@ -66,8 +72,12 @@ class ReaderPageView(BookmarkBaseView):
|
|
|
66
72
|
content_type = _PDF_MIME_TYPE
|
|
67
73
|
else:
|
|
68
74
|
content_type = self.content_type
|
|
75
|
+
|
|
69
76
|
with Comicbox(comic.path) as cb:
|
|
70
77
|
page_image = cb.get_page_by_index(page, to_pixmap=to_pixmap)
|
|
78
|
+
if not page_image:
|
|
79
|
+
page_image = b""
|
|
80
|
+
|
|
71
81
|
return page_image, content_type
|
|
72
82
|
|
|
73
83
|
@extend_schema(
|
|
@@ -98,4 +108,5 @@ class ReaderPageView(BookmarkBaseView):
|
|
|
98
108
|
LOG.warning(exc)
|
|
99
109
|
raise NotFound(detail="comic page not found") from exc
|
|
100
110
|
else:
|
|
101
|
-
|
|
111
|
+
page_chunker = chunker(BytesIO(page_image), _PAGE_CHUNK_SIZE)
|
|
112
|
+
return StreamingHttpResponse(page_chunker, content_type=content_type)
|
codex/views/session.py
CHANGED
|
@@ -69,8 +69,10 @@ class SessionView(AuthFilterGenericAPIView, ABC):
|
|
|
69
69
|
"top_group": DEFAULTS["topGroup"],
|
|
70
70
|
},
|
|
71
71
|
READER_SESSION_KEY: {
|
|
72
|
+
"finish_on_last_page": DEFAULTS["finishOnLastPage"],
|
|
72
73
|
"fit_to": DEFAULTS["fitTo"],
|
|
73
|
-
"two_pages":
|
|
74
|
+
"two_pages": DEFAULTS["twoPages"],
|
|
75
|
+
"read_rtl_in_reverse": DEFAULTS["readRtlInReverse"],
|
|
74
76
|
"reading_direction": DEFAULTS["readingDirection"],
|
|
75
77
|
},
|
|
76
78
|
}
|
codex/views/util.py
CHANGED
|
@@ -10,6 +10,9 @@ from urllib.parse import unquote_plus
|
|
|
10
10
|
from djangorestframework_camel_case.settings import api_settings
|
|
11
11
|
from djangorestframework_camel_case.util import underscoreize
|
|
12
12
|
|
|
13
|
+
# Maximum cover size is around 24 Kb
|
|
14
|
+
DEFAULT_CHUNK_SIZE = 64 * 1024 # 64 Kb
|
|
15
|
+
|
|
13
16
|
|
|
14
17
|
@dataclass()
|
|
15
18
|
class Route(dict):
|
|
@@ -62,3 +65,13 @@ def pop_name(kwargs: Mapping):
|
|
|
62
65
|
kwargs = dict(kwargs)
|
|
63
66
|
kwargs.pop("name", None)
|
|
64
67
|
return kwargs
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
async def chunker(open_file, chunk_size=DEFAULT_CHUNK_SIZE):
|
|
71
|
+
"""Asynchronous iterator for serving files."""
|
|
72
|
+
while True:
|
|
73
|
+
chunk = open_file.read(chunk_size)
|
|
74
|
+
if not chunk:
|
|
75
|
+
open_file.close()
|
|
76
|
+
break
|
|
77
|
+
yield chunk
|
codex/websockets/consumers.py
CHANGED