codex 1.6.19__py3-none-any.whl → 1.7.0a0__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/db.py +119 -0
- codex/librarian/covers/purge.py +1 -1
- codex/librarian/importer/const.py +7 -1
- codex/librarian/importer/create_fks.py +5 -2
- codex/librarian/importer/importerd.py +17 -12
- codex/librarian/importer/moved.py +44 -13
- codex/librarian/importer/tasks.py +2 -0
- codex/librarian/janitor/cleanup.py +21 -8
- codex/librarian/janitor/integrity.py +369 -0
- codex/librarian/janitor/janitor.py +50 -15
- codex/librarian/janitor/latest_version.py +2 -1
- codex/librarian/janitor/status.py +5 -0
- codex/librarian/janitor/tasks.py +37 -0
- codex/librarian/janitor/update.py +1 -1
- codex/librarian/librariand.py +32 -24
- codex/librarian/search/optimize.py +43 -0
- codex/librarian/search/remove.py +18 -46
- codex/librarian/search/searchd.py +14 -17
- codex/librarian/search/status.py +2 -1
- codex/librarian/search/tasks.py +4 -9
- codex/librarian/search/update.py +223 -301
- codex/librarian/watchdog/observers.py +2 -1
- codex/migrations/0029_comicfts.py +58 -0
- codex/migrations/0030_nocase_collation_day_month_indexes_status_types.py +198 -0
- codex/models/admin.py +15 -6
- codex/models/base.py +9 -0
- codex/models/bookmark.py +3 -3
- codex/models/comic.py +68 -16
- codex/models/functions.py +59 -2
- codex/models/groups.py +6 -1
- codex/models/library.py +1 -3
- codex/models/paths.py +9 -3
- codex/serializers/browser/page.py +2 -0
- codex/settings/settings.py +16 -17
- codex/signals/django_signals.py +4 -10
- codex/startup.py +1 -35
- codex/static_root/assets/{VCheckbox-Cko1sQK-.170726b3b8a1.js → VCheckbox-CWiqcZ7a.3feebd47daab.js} +1 -1
- codex/static_root/assets/VCheckbox-CWiqcZ7a.3feebd47daab.js.br +0 -0
- codex/static_root/assets/VCheckbox-CWiqcZ7a.3feebd47daab.js.gz +0 -0
- codex/static_root/assets/{VCheckbox-Cko1sQK-.js → VCheckbox-CWiqcZ7a.js} +1 -1
- codex/static_root/assets/VCheckbox-CWiqcZ7a.js.br +0 -0
- codex/static_root/assets/VCheckbox-CWiqcZ7a.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-CO3-aqQL.c9b8062fd66f.js → VCheckboxBtn-Dk3iB62X.bc66d5351baa.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-Dk3iB62X.bc66d5351baa.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-Dk3iB62X.bc66d5351baa.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-CO3-aqQL.js → VCheckboxBtn-Dk3iB62X.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-Dk3iB62X.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-Dk3iB62X.js.gz +0 -0
- codex/static_root/assets/{VCombobox-Bjp6lffE.js → VCombobox-D1_KU27A.b1d30587a973.js} +1 -1
- codex/static_root/assets/VCombobox-D1_KU27A.b1d30587a973.js.br +0 -0
- codex/static_root/assets/VCombobox-D1_KU27A.b1d30587a973.js.gz +0 -0
- codex/static_root/assets/{VCombobox-Bjp6lffE.caf59fba486e.js → VCombobox-D1_KU27A.js} +1 -1
- codex/static_root/assets/VCombobox-D1_KU27A.js.br +0 -0
- codex/static_root/assets/VCombobox-D1_KU27A.js.gz +0 -0
- codex/static_root/assets/{VDialog-BkpVGB70.6eea3ca762a5.js → VDialog-GbxvFMMN.594fb3a39ced.js} +1 -1
- codex/static_root/assets/VDialog-GbxvFMMN.594fb3a39ced.js.br +0 -0
- codex/static_root/assets/VDialog-GbxvFMMN.594fb3a39ced.js.gz +0 -0
- codex/static_root/assets/{VDialog-BkpVGB70.js → VDialog-GbxvFMMN.js} +1 -1
- codex/static_root/assets/VDialog-GbxvFMMN.js.br +0 -0
- codex/static_root/assets/VDialog-GbxvFMMN.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-Ci2-j8XX.9c55db4ef49e.js → VExpansionPanels-Cywv_bEj.a762e63858e5.js} +1 -1
- codex/static_root/assets/VExpansionPanels-Cywv_bEj.a762e63858e5.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-Cywv_bEj.a762e63858e5.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-Ci2-j8XX.js → VExpansionPanels-Cywv_bEj.js} +1 -1
- codex/static_root/assets/VExpansionPanels-Cywv_bEj.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-Cywv_bEj.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-D3Py5BfQ.a4f25edb86d3.js → VRadioGroup-C0etmxpZ.0eb3009a6300.js} +1 -1
- codex/static_root/assets/VRadioGroup-C0etmxpZ.0eb3009a6300.js.br +0 -0
- codex/static_root/assets/VRadioGroup-C0etmxpZ.0eb3009a6300.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-D3Py5BfQ.js → VRadioGroup-C0etmxpZ.js} +1 -1
- codex/static_root/assets/VRadioGroup-C0etmxpZ.js.br +0 -0
- codex/static_root/assets/VRadioGroup-C0etmxpZ.js.gz +0 -0
- codex/static_root/assets/{VSelect-DtvZsYZz.e98745d858eb.js → VSelect-txrnRiNJ.a5625760018c.js} +1 -1
- codex/static_root/assets/VSelect-txrnRiNJ.a5625760018c.js.br +0 -0
- codex/static_root/assets/VSelect-txrnRiNJ.a5625760018c.js.gz +0 -0
- codex/static_root/assets/{VSelect-DtvZsYZz.js → VSelect-txrnRiNJ.js} +1 -1
- codex/static_root/assets/VSelect-txrnRiNJ.js.br +0 -0
- codex/static_root/assets/VSelect-txrnRiNJ.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-D6kmykQW.1e1fda62ceba.js → VSelectionControl-CY6RmcvW.7e8824224f6c.js} +1 -1
- codex/static_root/assets/VSelectionControl-CY6RmcvW.7e8824224f6c.js.br +0 -0
- codex/static_root/assets/VSelectionControl-CY6RmcvW.7e8824224f6c.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-D6kmykQW.js → VSelectionControl-CY6RmcvW.js} +1 -1
- codex/static_root/assets/VSelectionControl-CY6RmcvW.js.br +0 -0
- codex/static_root/assets/VSelectionControl-CY6RmcvW.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-UGZWxpF5.360bdefcd215.js → VSlideGroup-DtEQMwY1.6c72325635ed.js} +1 -1
- codex/static_root/assets/VSlideGroup-DtEQMwY1.6c72325635ed.js.br +0 -0
- codex/static_root/assets/VSlideGroup-DtEQMwY1.6c72325635ed.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-UGZWxpF5.js → VSlideGroup-DtEQMwY1.js} +1 -1
- codex/static_root/assets/VSlideGroup-DtEQMwY1.js.br +0 -0
- codex/static_root/assets/VSlideGroup-DtEQMwY1.js.gz +0 -0
- codex/static_root/assets/{VTable-DXH_yQ0o.1149f56ad566.js → VTable-2af995xo.6c5bf36631b2.js} +1 -1
- codex/static_root/assets/VTable-2af995xo.6c5bf36631b2.js.br +0 -0
- codex/static_root/assets/VTable-2af995xo.6c5bf36631b2.js.gz +0 -0
- codex/static_root/assets/{VTable-DXH_yQ0o.js → VTable-2af995xo.js} +1 -1
- codex/static_root/assets/VTable-2af995xo.js.br +0 -0
- codex/static_root/assets/VTable-2af995xo.js.gz +0 -0
- codex/static_root/assets/{VTextField-Blqy56_L.26d8761e0155.js → VTextField-G6CMj7yO.657a130dd302.js} +1 -1
- codex/static_root/assets/VTextField-G6CMj7yO.657a130dd302.js.br +0 -0
- codex/static_root/assets/VTextField-G6CMj7yO.657a130dd302.js.gz +0 -0
- codex/static_root/assets/{VTextField-Blqy56_L.js → VTextField-G6CMj7yO.js} +1 -1
- codex/static_root/assets/VTextField-G6CMj7yO.js.br +0 -0
- codex/static_root/assets/VTextField-G6CMj7yO.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-C8_ovV7e.afbc08414765.js → VWindowItem-CzoGd6Ul.721e5da11ad4.js} +1 -1
- codex/static_root/assets/VWindowItem-CzoGd6Ul.721e5da11ad4.js.br +0 -0
- codex/static_root/assets/VWindowItem-CzoGd6Ul.721e5da11ad4.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-C8_ovV7e.js → VWindowItem-CzoGd6Ul.js} +1 -1
- codex/static_root/assets/VWindowItem-CzoGd6Ul.js.br +0 -0
- codex/static_root/assets/VWindowItem-CzoGd6Ul.js.gz +0 -0
- codex/static_root/assets/{admin-DTRn8bBs.d031ea42d8d0.js → admin-CsPAIQeG.5175467148a3.js} +1 -1
- codex/static_root/assets/admin-CsPAIQeG.5175467148a3.js.br +0 -0
- codex/static_root/assets/admin-CsPAIQeG.5175467148a3.js.gz +0 -0
- codex/static_root/assets/{admin-DTRn8bBs.js → admin-CsPAIQeG.js} +1 -1
- codex/static_root/assets/admin-CsPAIQeG.js.br +0 -0
- codex/static_root/assets/admin-CsPAIQeG.js.gz +0 -0
- codex/static_root/assets/{admin-drawer-panel-BaXFOcru.b1a44b05f482.js → admin-drawer-panel-BAT7GA64.73a064628c19.js} +11 -11
- codex/static_root/assets/admin-drawer-panel-BAT7GA64.73a064628c19.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BAT7GA64.73a064628c19.js.gz +0 -0
- codex/static_root/assets/{admin-drawer-panel-BaXFOcru.js → admin-drawer-panel-BAT7GA64.js} +11 -11
- codex/static_root/assets/admin-drawer-panel-BAT7GA64.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BAT7GA64.js.gz +0 -0
- codex/static_root/assets/browser-C18l93yc.923860009ef4.js +1 -0
- codex/static_root/assets/browser-C18l93yc.923860009ef4.js.br +0 -0
- codex/static_root/assets/browser-C18l93yc.923860009ef4.js.gz +0 -0
- codex/static_root/assets/browser-C18l93yc.js +1 -0
- codex/static_root/assets/browser-C18l93yc.js.br +0 -0
- codex/static_root/assets/browser-C18l93yc.js.gz +0 -0
- codex/static_root/assets/browser-DaAqlBYO.708ecf0904bb.css +1 -0
- codex/static_root/assets/browser-DaAqlBYO.708ecf0904bb.css.br +0 -0
- codex/static_root/assets/browser-DaAqlBYO.708ecf0904bb.css.gz +0 -0
- codex/static_root/assets/browser-DaAqlBYO.css +1 -0
- codex/static_root/assets/browser-DaAqlBYO.css.br +0 -0
- codex/static_root/assets/browser-DaAqlBYO.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-BazJdNs9.0a4e02656a35.js +1 -0
- codex/static_root/assets/change-password-dialog-BazJdNs9.0a4e02656a35.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BazJdNs9.0a4e02656a35.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-BazJdNs9.js +1 -0
- codex/static_root/assets/change-password-dialog-BazJdNs9.js.br +0 -0
- codex/static_root/assets/change-password-dialog-BazJdNs9.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-Mlmvz8_4.111421f51e79.css +1 -0
- codex/static_root/assets/change-password-dialog-Mlmvz8_4.111421f51e79.css.br +0 -0
- codex/static_root/assets/change-password-dialog-Mlmvz8_4.111421f51e79.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-Mlmvz8_4.css +1 -0
- codex/static_root/assets/change-password-dialog-Mlmvz8_4.css.br +0 -0
- codex/static_root/assets/change-password-dialog-Mlmvz8_4.css.gz +0 -0
- codex/static_root/assets/{confirm-dialog-D3_s2DQy.9dde66036c72.js → confirm-dialog-CbW3hlOp.9dd39b443c31.js} +1 -1
- codex/static_root/assets/confirm-dialog-CbW3hlOp.9dd39b443c31.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CbW3hlOp.9dd39b443c31.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-D3_s2DQy.js → confirm-dialog-CbW3hlOp.js} +1 -1
- codex/static_root/assets/confirm-dialog-CbW3hlOp.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CbW3hlOp.js.gz +0 -0
- codex/static_root/assets/{datetime-column-BxC1Li9e.3dc314b3295d.js → datetime-column-uSqKZU37.b157b0743db5.js} +1 -1
- codex/static_root/assets/datetime-column-uSqKZU37.b157b0743db5.js.br +0 -0
- codex/static_root/assets/datetime-column-uSqKZU37.b157b0743db5.js.gz +0 -0
- codex/static_root/assets/{datetime-column-BxC1Li9e.js → datetime-column-uSqKZU37.js} +1 -1
- codex/static_root/assets/datetime-column-uSqKZU37.js.br +0 -0
- codex/static_root/assets/datetime-column-uSqKZU37.js.gz +0 -0
- codex/static_root/assets/{filter-Bzk7x841.d0c3b602e62d.js → filter-CBl5KEsB.845a81573c2e.js} +1 -1
- codex/static_root/assets/filter-CBl5KEsB.845a81573c2e.js.br +0 -0
- codex/static_root/assets/filter-CBl5KEsB.845a81573c2e.js.gz +0 -0
- codex/static_root/assets/{filter-Bzk7x841.js → filter-CBl5KEsB.js} +1 -1
- codex/static_root/assets/filter-CBl5KEsB.js.br +0 -0
- codex/static_root/assets/filter-CBl5KEsB.js.gz +0 -0
- codex/static_root/assets/flag-tab-CT8pqM4r.ecb6eee2e7a0.js +1 -0
- codex/static_root/assets/flag-tab-CT8pqM4r.ecb6eee2e7a0.js.br +0 -0
- codex/static_root/assets/flag-tab-CT8pqM4r.ecb6eee2e7a0.js.gz +0 -0
- codex/static_root/assets/flag-tab-CT8pqM4r.js +1 -0
- codex/static_root/assets/flag-tab-CT8pqM4r.js.br +0 -0
- codex/static_root/assets/flag-tab-CT8pqM4r.js.gz +0 -0
- codex/static_root/assets/{group-tab-5esH4lwX.a81fdd258117.js → group-tab-BOW9kigw.7e5007596367.js} +1 -1
- codex/static_root/assets/group-tab-BOW9kigw.7e5007596367.js.br +0 -0
- codex/static_root/assets/group-tab-BOW9kigw.7e5007596367.js.gz +0 -0
- codex/static_root/assets/{group-tab-5esH4lwX.js → group-tab-BOW9kigw.js} +1 -1
- codex/static_root/assets/group-tab-BOW9kigw.js.br +0 -0
- codex/static_root/assets/group-tab-BOW9kigw.js.gz +0 -0
- codex/static_root/assets/{http-error-BTOBfcGY.52ced6f28420.js → http-error-C6yuLApo.45cf99eb7a70.js} +1 -1
- codex/static_root/assets/http-error-C6yuLApo.45cf99eb7a70.js.br +4 -0
- codex/static_root/assets/http-error-C6yuLApo.45cf99eb7a70.js.gz +0 -0
- codex/static_root/assets/{http-error-BTOBfcGY.js → http-error-C6yuLApo.js} +1 -1
- codex/static_root/assets/http-error-C6yuLApo.js.br +4 -0
- codex/static_root/assets/http-error-C6yuLApo.js.gz +0 -0
- codex/static_root/assets/{library-tab-DiPEdOF7.ece2d642a9dc.js → library-tab-D3WOtpE0.9af34e6e7235.js} +1 -1
- codex/static_root/assets/library-tab-D3WOtpE0.9af34e6e7235.js.br +0 -0
- codex/static_root/assets/library-tab-D3WOtpE0.9af34e6e7235.js.gz +0 -0
- codex/static_root/assets/{library-tab-DiPEdOF7.js → library-tab-D3WOtpE0.js} +1 -1
- codex/static_root/assets/library-tab-D3WOtpE0.js.br +0 -0
- codex/static_root/assets/library-tab-D3WOtpE0.js.gz +0 -0
- codex/static_root/assets/main-CmjU2oTp.6a471f6900e5.js +6 -0
- codex/static_root/assets/main-CmjU2oTp.6a471f6900e5.js.br +0 -0
- codex/static_root/assets/main-CmjU2oTp.6a471f6900e5.js.gz +0 -0
- codex/static_root/assets/main-CmjU2oTp.js +6 -0
- codex/static_root/assets/main-CmjU2oTp.js.br +0 -0
- codex/static_root/assets/main-CmjU2oTp.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-BH54_5f6.6e92d0555cd7.js +1 -0
- codex/static_root/assets/pager-full-pdf-BH54_5f6.6e92d0555cd7.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-BH54_5f6.6e92d0555cd7.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-BH54_5f6.js +1 -0
- codex/static_root/assets/pager-full-pdf-BH54_5f6.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-BH54_5f6.js.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-C45-onwe.4722195bb60b.css → pagination-toolbar-DGrxp2OD.css} +1 -1
- codex/static_root/assets/pagination-toolbar-DGrxp2OD.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-DGrxp2OD.css.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-C45-onwe.css → pagination-toolbar-DGrxp2OD.f960a624f04f.css} +1 -1
- codex/static_root/assets/pagination-toolbar-DGrxp2OD.f960a624f04f.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-DGrxp2OD.f960a624f04f.css.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-CkIzuyx1.00c354a82e6e.js → pagination-toolbar-JH3Kbffr.451171f7ac33.js} +1 -1
- codex/static_root/assets/pagination-toolbar-JH3Kbffr.451171f7ac33.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-JH3Kbffr.451171f7ac33.js.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-CkIzuyx1.js → pagination-toolbar-JH3Kbffr.js} +1 -1
- codex/static_root/assets/pagination-toolbar-JH3Kbffr.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-JH3Kbffr.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-BjlRPuf4.0f056fa321b6.js → pdf-doc-BcRNpoaW.882f6e967869.js} +1 -1
- codex/static_root/assets/pdf-doc-BcRNpoaW.882f6e967869.js.br +0 -0
- codex/static_root/assets/pdf-doc-BcRNpoaW.882f6e967869.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-BjlRPuf4.js → pdf-doc-BcRNpoaW.js} +1 -1
- codex/static_root/assets/pdf-doc-BcRNpoaW.js.br +0 -0
- codex/static_root/assets/pdf-doc-BcRNpoaW.js.gz +0 -0
- codex/static_root/assets/reader-DIPRg2VB.900370e097aa.js +2 -0
- codex/static_root/assets/reader-DIPRg2VB.900370e097aa.js.br +0 -0
- codex/static_root/assets/reader-DIPRg2VB.900370e097aa.js.gz +0 -0
- codex/static_root/assets/reader-DIPRg2VB.js +2 -0
- codex/static_root/assets/reader-DIPRg2VB.js.br +0 -0
- codex/static_root/assets/reader-DIPRg2VB.js.gz +0 -0
- codex/static_root/assets/reader-DveZZr9x.7b21b9f8f628.css +1 -0
- codex/static_root/assets/reader-DveZZr9x.7b21b9f8f628.css.br +0 -0
- codex/static_root/assets/reader-DveZZr9x.7b21b9f8f628.css.gz +0 -0
- codex/static_root/assets/reader-DveZZr9x.css +1 -0
- codex/static_root/assets/reader-DveZZr9x.css.br +0 -0
- codex/static_root/assets/reader-DveZZr9x.css.gz +0 -0
- codex/static_root/assets/{relation-chips-CUSatZET.js → relation-chips-3tTlR5QH.71f18bc92adc.js} +1 -1
- codex/static_root/assets/relation-chips-3tTlR5QH.71f18bc92adc.js.br +0 -0
- codex/static_root/assets/relation-chips-3tTlR5QH.71f18bc92adc.js.gz +0 -0
- codex/static_root/assets/{relation-chips-CUSatZET.a58031ff8141.js → relation-chips-3tTlR5QH.js} +1 -1
- codex/static_root/assets/relation-chips-3tTlR5QH.js.br +0 -0
- codex/static_root/assets/relation-chips-3tTlR5QH.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-BSHTAsJ9.js → settings-drawer-BdyFhA_r.151f4c3061ed.js} +2 -2
- codex/static_root/assets/settings-drawer-BdyFhA_r.151f4c3061ed.js.br +0 -0
- codex/static_root/assets/settings-drawer-BdyFhA_r.151f4c3061ed.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-BSHTAsJ9.1d07ce084fc9.js → settings-drawer-BdyFhA_r.js} +2 -2
- codex/static_root/assets/settings-drawer-BdyFhA_r.js.br +0 -0
- codex/static_root/assets/settings-drawer-BdyFhA_r.js.gz +0 -0
- codex/static_root/assets/stats-tab-DeKjwvmh.7557c71b4cfa.js +1 -0
- codex/static_root/assets/stats-tab-DeKjwvmh.7557c71b4cfa.js.br +0 -0
- codex/static_root/assets/stats-tab-DeKjwvmh.7557c71b4cfa.js.gz +0 -0
- codex/static_root/assets/stats-tab-DeKjwvmh.js +1 -0
- codex/static_root/assets/stats-tab-DeKjwvmh.js.br +0 -0
- codex/static_root/assets/stats-tab-DeKjwvmh.js.gz +0 -0
- codex/static_root/assets/{stats-tab-BXGisn5N.9b7a71e7fe28.css → stats-tab-DpfGsVX3.1cb66f2649a9.css} +1 -1
- codex/static_root/assets/stats-tab-DpfGsVX3.1cb66f2649a9.css.br +0 -0
- codex/static_root/assets/stats-tab-DpfGsVX3.1cb66f2649a9.css.gz +0 -0
- codex/static_root/assets/{stats-tab-BXGisn5N.css → stats-tab-DpfGsVX3.css} +1 -1
- codex/static_root/assets/stats-tab-DpfGsVX3.css.br +0 -0
- codex/static_root/assets/stats-tab-DpfGsVX3.css.gz +0 -0
- codex/static_root/assets/{task-tab-NORFAa9p.97e07e366ddd.js → task-tab-C8D0qRP_.d4ab174c69a3.js} +1 -1
- codex/static_root/assets/task-tab-C8D0qRP_.d4ab174c69a3.js.br +0 -0
- codex/static_root/assets/task-tab-C8D0qRP_.d4ab174c69a3.js.gz +0 -0
- codex/static_root/assets/{task-tab-NORFAa9p.js → task-tab-C8D0qRP_.js} +1 -1
- codex/static_root/assets/task-tab-C8D0qRP_.js.br +0 -0
- codex/static_root/assets/task-tab-C8D0qRP_.js.gz +0 -0
- codex/static_root/assets/unauthorized-BHgBRF4z.8e5c1b9e52b0.js +1 -0
- codex/static_root/assets/unauthorized-BHgBRF4z.8e5c1b9e52b0.js.br +0 -0
- codex/static_root/assets/unauthorized-BHgBRF4z.8e5c1b9e52b0.js.gz +0 -0
- codex/static_root/assets/unauthorized-BHgBRF4z.js +1 -0
- codex/static_root/assets/unauthorized-BHgBRF4z.js.br +0 -0
- codex/static_root/assets/unauthorized-BHgBRF4z.js.gz +0 -0
- codex/static_root/assets/{unauthorized-muDsv-rC.css → unauthorized-BjhIc97q.728511c92cd0.css} +1 -1
- codex/static_root/assets/unauthorized-BjhIc97q.728511c92cd0.css.br +0 -0
- codex/static_root/assets/unauthorized-BjhIc97q.728511c92cd0.css.gz +0 -0
- codex/static_root/assets/{unauthorized-muDsv-rC.2166ec8b3a32.css → unauthorized-BjhIc97q.css} +1 -1
- codex/static_root/assets/unauthorized-BjhIc97q.css.br +0 -0
- codex/static_root/assets/unauthorized-BjhIc97q.css.gz +0 -0
- codex/static_root/assets/{user-tab-CHbyN1EW.e7206db08680.js → user-tab-BU31Z92y.35613c713faf.js} +1 -1
- codex/static_root/assets/user-tab-BU31Z92y.35613c713faf.js.br +0 -0
- codex/static_root/assets/user-tab-BU31Z92y.35613c713faf.js.gz +0 -0
- codex/static_root/assets/{user-tab-CHbyN1EW.js → user-tab-BU31Z92y.js} +1 -1
- codex/static_root/assets/user-tab-BU31Z92y.js.br +0 -0
- codex/static_root/assets/user-tab-BU31Z92y.js.gz +0 -0
- codex/static_root/js/choices-admin.8aa64c911203.json +1 -0
- codex/static_root/js/choices-admin.8aa64c911203.json.br +0 -0
- codex/static_root/js/choices-admin.8aa64c911203.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/manifest.45cb46e19686.json +635 -0
- codex/static_root/manifest.45cb46e19686.json.br +0 -0
- codex/static_root/manifest.45cb46e19686.json.gz +0 -0
- codex/static_root/manifest.json +248 -248
- 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 +10 -4
- codex/views/admin/tasks.py +46 -40
- codex/views/auth.py +15 -4
- codex/views/browser/annotations.py +94 -51
- codex/views/browser/base.py +1 -2
- codex/views/browser/browser.py +52 -21
- codex/views/browser/cover.py +8 -4
- codex/views/browser/filters/annotations.py +28 -6
- codex/views/browser/filters/search/__init__.py +1 -0
- codex/views/browser/filters/search/aliases.py +81 -0
- codex/views/browser/filters/search/field/__init__.py +1 -0
- codex/views/browser/filters/search/field/column.py +53 -0
- codex/views/browser/filters/search/field/expression.py +177 -0
- codex/views/browser/filters/search/field/filter.py +70 -0
- codex/views/browser/filters/search/field/optimize.py +71 -0
- codex/views/browser/filters/search/field/parse.py +187 -0
- codex/views/browser/filters/search/fts.py +38 -0
- codex/views/browser/filters/search/parse.py +220 -0
- codex/views/browser/order_by.py +8 -2
- codex/views/browser/page_in_bounds.py +88 -0
- codex/views/browser/paginate.py +28 -113
- codex/views/const.py +0 -1
- codex/views/opds/v1/feed.py +2 -1
- codex/views/opds/v2/feed.py +2 -1
- codex/views/opds/v2/links.py +1 -1
- codex/views/reader/books.py +1 -1
- codex/views/reader/page.py +3 -3
- {codex-1.6.19.dist-info → codex-1.7.0a0.dist-info}/METADATA +18 -10
- {codex-1.6.19.dist-info → codex-1.7.0a0.dist-info}/RECORD +321 -372
- codex/_vendor/__init__.py +0 -0
- codex/_vendor/django_haystack-3.2.1.dist-info/AUTHORS +0 -127
- codex/_vendor/django_haystack-3.2.1.dist-info/INSTALLER +0 -1
- codex/_vendor/django_haystack-3.2.1.dist-info/LICENSE +0 -31
- codex/_vendor/django_haystack-3.2.1.dist-info/METADATA +0 -98
- codex/_vendor/django_haystack-3.2.1.dist-info/RECORD +0 -97
- codex/_vendor/django_haystack-3.2.1.dist-info/REQUESTED +0 -0
- codex/_vendor/django_haystack-3.2.1.dist-info/WHEEL +0 -5
- codex/_vendor/django_haystack-3.2.1.dist-info/top_level.txt +0 -1
- codex/_vendor/haystack/__init__.py +0 -80
- codex/_vendor/haystack/admin.py +0 -163
- codex/_vendor/haystack/apps.py +0 -31
- codex/_vendor/haystack/backends/__init__.py +0 -1109
- codex/_vendor/haystack/backends/elasticsearch2_backend.py +0 -390
- codex/_vendor/haystack/backends/elasticsearch5_backend.py +0 -483
- codex/_vendor/haystack/backends/elasticsearch7_backend.py +0 -586
- codex/_vendor/haystack/backends/elasticsearch_backend.py +0 -1141
- codex/_vendor/haystack/backends/simple_backend.py +0 -132
- codex/_vendor/haystack/backends/solr_backend.py +0 -991
- codex/_vendor/haystack/backends/whoosh_backend.py +0 -1104
- codex/_vendor/haystack/constants.py +0 -57
- codex/_vendor/haystack/exceptions.py +0 -57
- codex/_vendor/haystack/fields.py +0 -562
- codex/_vendor/haystack/forms.py +0 -135
- codex/_vendor/haystack/generic_views.py +0 -141
- codex/_vendor/haystack/indexes.py +0 -548
- codex/_vendor/haystack/inputs.py +0 -169
- codex/_vendor/haystack/management/__init__.py +0 -0
- codex/_vendor/haystack/management/commands/__init__.py +0 -0
- codex/_vendor/haystack/management/commands/build_solr_schema.py +0 -187
- codex/_vendor/haystack/management/commands/clear_index.py +0 -67
- codex/_vendor/haystack/management/commands/haystack_info.py +0 -22
- codex/_vendor/haystack/management/commands/rebuild_index.py +0 -65
- codex/_vendor/haystack/management/commands/update_index.py +0 -438
- codex/_vendor/haystack/manager.py +0 -105
- codex/_vendor/haystack/models.py +0 -257
- codex/_vendor/haystack/panels.py +0 -89
- codex/_vendor/haystack/query.py +0 -771
- codex/_vendor/haystack/routers.py +0 -14
- codex/_vendor/haystack/signals.py +0 -88
- codex/_vendor/haystack/templates/panels/haystack.html +0 -33
- codex/_vendor/haystack/templates/search_configuration/schema.xml +0 -1056
- codex/_vendor/haystack/templates/search_configuration/solrconfig.xml +0 -1446
- codex/_vendor/haystack/templatetags/__init__.py +0 -0
- codex/_vendor/haystack/templatetags/highlight.py +0 -131
- codex/_vendor/haystack/templatetags/more_like_this.py +0 -119
- codex/_vendor/haystack/urls.py +0 -5
- codex/_vendor/haystack/utils/__init__.py +0 -84
- codex/_vendor/haystack/utils/app_loading.py +0 -34
- codex/_vendor/haystack/utils/geo.py +0 -71
- codex/_vendor/haystack/utils/highlighting.py +0 -165
- codex/_vendor/haystack/utils/loading.py +0 -374
- codex/_vendor/haystack/utils/log.py +0 -21
- codex/_vendor/haystack/version.py +0 -16
- codex/_vendor/haystack/views.py +0 -253
- codex/integrity.py +0 -492
- codex/librarian/search/merge.py +0 -86
- codex/librarian/search/version.py +0 -63
- codex/search/__init__.py +0 -1
- codex/search/backend.py +0 -524
- codex/search/backend_search.py +0 -229
- codex/search/engine.py +0 -33
- codex/search/indexes.py +0 -79
- codex/search/query.py +0 -67
- codex/search/writing.py +0 -180
- codex/static_root/assets/VCheckbox-Cko1sQK-.170726b3b8a1.js.br +0 -0
- codex/static_root/assets/VCheckbox-Cko1sQK-.170726b3b8a1.js.gz +0 -0
- codex/static_root/assets/VCheckbox-Cko1sQK-.js.br +0 -0
- codex/static_root/assets/VCheckbox-Cko1sQK-.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-CO3-aqQL.c9b8062fd66f.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-CO3-aqQL.c9b8062fd66f.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-CO3-aqQL.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-CO3-aqQL.js.gz +0 -0
- codex/static_root/assets/VCombobox-Bjp6lffE.caf59fba486e.js.br +0 -0
- codex/static_root/assets/VCombobox-Bjp6lffE.caf59fba486e.js.gz +0 -0
- codex/static_root/assets/VCombobox-Bjp6lffE.js.br +0 -0
- codex/static_root/assets/VCombobox-Bjp6lffE.js.gz +0 -0
- codex/static_root/assets/VDialog-BkpVGB70.6eea3ca762a5.js.br +0 -0
- codex/static_root/assets/VDialog-BkpVGB70.6eea3ca762a5.js.gz +0 -0
- codex/static_root/assets/VDialog-BkpVGB70.js.br +0 -0
- codex/static_root/assets/VDialog-BkpVGB70.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-Ci2-j8XX.9c55db4ef49e.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-Ci2-j8XX.9c55db4ef49e.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-Ci2-j8XX.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-Ci2-j8XX.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-D3Py5BfQ.a4f25edb86d3.js.br +0 -0
- codex/static_root/assets/VRadioGroup-D3Py5BfQ.a4f25edb86d3.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-D3Py5BfQ.js.br +0 -0
- codex/static_root/assets/VRadioGroup-D3Py5BfQ.js.gz +0 -0
- codex/static_root/assets/VSelect-DtvZsYZz.e98745d858eb.js.br +0 -0
- codex/static_root/assets/VSelect-DtvZsYZz.e98745d858eb.js.gz +0 -0
- codex/static_root/assets/VSelect-DtvZsYZz.js.br +0 -0
- codex/static_root/assets/VSelect-DtvZsYZz.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-D6kmykQW.1e1fda62ceba.js.br +0 -0
- codex/static_root/assets/VSelectionControl-D6kmykQW.1e1fda62ceba.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-D6kmykQW.js.br +0 -0
- codex/static_root/assets/VSelectionControl-D6kmykQW.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-UGZWxpF5.360bdefcd215.js.br +0 -0
- codex/static_root/assets/VSlideGroup-UGZWxpF5.360bdefcd215.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-UGZWxpF5.js.br +0 -0
- codex/static_root/assets/VSlideGroup-UGZWxpF5.js.gz +0 -0
- codex/static_root/assets/VTable-DXH_yQ0o.1149f56ad566.js.br +0 -0
- codex/static_root/assets/VTable-DXH_yQ0o.1149f56ad566.js.gz +0 -0
- codex/static_root/assets/VTable-DXH_yQ0o.js.br +0 -0
- codex/static_root/assets/VTable-DXH_yQ0o.js.gz +0 -0
- codex/static_root/assets/VTextField-Blqy56_L.26d8761e0155.js.br +0 -0
- codex/static_root/assets/VTextField-Blqy56_L.26d8761e0155.js.gz +0 -0
- codex/static_root/assets/VTextField-Blqy56_L.js.br +0 -0
- codex/static_root/assets/VTextField-Blqy56_L.js.gz +0 -0
- codex/static_root/assets/VWindowItem-C8_ovV7e.afbc08414765.js.br +0 -0
- codex/static_root/assets/VWindowItem-C8_ovV7e.afbc08414765.js.gz +0 -0
- codex/static_root/assets/VWindowItem-C8_ovV7e.js.br +0 -0
- codex/static_root/assets/VWindowItem-C8_ovV7e.js.gz +0 -0
- codex/static_root/assets/admin-DTRn8bBs.d031ea42d8d0.js.br +0 -0
- codex/static_root/assets/admin-DTRn8bBs.d031ea42d8d0.js.gz +0 -0
- codex/static_root/assets/admin-DTRn8bBs.js.br +0 -0
- codex/static_root/assets/admin-DTRn8bBs.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-BaXFOcru.b1a44b05f482.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BaXFOcru.b1a44b05f482.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-BaXFOcru.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-BaXFOcru.js.gz +0 -0
- codex/static_root/assets/browser-BBpUyGmz.c1cb9e2d463b.js +0 -1
- codex/static_root/assets/browser-BBpUyGmz.c1cb9e2d463b.js.br +0 -0
- codex/static_root/assets/browser-BBpUyGmz.c1cb9e2d463b.js.gz +0 -0
- codex/static_root/assets/browser-BBpUyGmz.js +0 -1
- codex/static_root/assets/browser-BBpUyGmz.js.br +0 -0
- codex/static_root/assets/browser-BBpUyGmz.js.gz +0 -0
- codex/static_root/assets/browser-Binc3n9H.313722d27ca3.css +0 -1
- codex/static_root/assets/browser-Binc3n9H.313722d27ca3.css.br +0 -0
- codex/static_root/assets/browser-Binc3n9H.313722d27ca3.css.gz +0 -0
- codex/static_root/assets/browser-Binc3n9H.css +0 -1
- codex/static_root/assets/browser-Binc3n9H.css.br +0 -0
- codex/static_root/assets/browser-Binc3n9H.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-Cebek1-c.aff2975e31f8.css +0 -1
- codex/static_root/assets/change-password-dialog-Cebek1-c.aff2975e31f8.css.br +0 -0
- codex/static_root/assets/change-password-dialog-Cebek1-c.aff2975e31f8.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-Cebek1-c.css +0 -1
- codex/static_root/assets/change-password-dialog-Cebek1-c.css.br +0 -0
- codex/static_root/assets/change-password-dialog-Cebek1-c.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-DlHoLhDF.76ab4a29bb9b.js +0 -1
- codex/static_root/assets/change-password-dialog-DlHoLhDF.76ab4a29bb9b.js.br +0 -0
- codex/static_root/assets/change-password-dialog-DlHoLhDF.76ab4a29bb9b.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-DlHoLhDF.js +0 -1
- codex/static_root/assets/change-password-dialog-DlHoLhDF.js.br +0 -0
- codex/static_root/assets/change-password-dialog-DlHoLhDF.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-D3_s2DQy.9dde66036c72.js.br +0 -0
- codex/static_root/assets/confirm-dialog-D3_s2DQy.9dde66036c72.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-D3_s2DQy.js.br +0 -0
- codex/static_root/assets/confirm-dialog-D3_s2DQy.js.gz +0 -0
- codex/static_root/assets/datetime-column-BxC1Li9e.3dc314b3295d.js.br +0 -0
- codex/static_root/assets/datetime-column-BxC1Li9e.3dc314b3295d.js.gz +0 -0
- codex/static_root/assets/datetime-column-BxC1Li9e.js.br +0 -0
- codex/static_root/assets/datetime-column-BxC1Li9e.js.gz +0 -0
- codex/static_root/assets/filter-Bzk7x841.d0c3b602e62d.js.br +0 -0
- codex/static_root/assets/filter-Bzk7x841.d0c3b602e62d.js.gz +0 -0
- codex/static_root/assets/filter-Bzk7x841.js.br +0 -0
- codex/static_root/assets/filter-Bzk7x841.js.gz +0 -0
- codex/static_root/assets/flag-tab-C2bI5zq3.8f8c297600a6.js +0 -1
- codex/static_root/assets/flag-tab-C2bI5zq3.8f8c297600a6.js.br +0 -0
- codex/static_root/assets/flag-tab-C2bI5zq3.8f8c297600a6.js.gz +0 -0
- codex/static_root/assets/flag-tab-C2bI5zq3.js +0 -1
- codex/static_root/assets/flag-tab-C2bI5zq3.js.br +0 -0
- codex/static_root/assets/flag-tab-C2bI5zq3.js.gz +0 -0
- codex/static_root/assets/group-tab-5esH4lwX.a81fdd258117.js.br +0 -0
- codex/static_root/assets/group-tab-5esH4lwX.a81fdd258117.js.gz +0 -0
- codex/static_root/assets/group-tab-5esH4lwX.js.br +0 -0
- codex/static_root/assets/group-tab-5esH4lwX.js.gz +0 -0
- codex/static_root/assets/http-error-BTOBfcGY.52ced6f28420.js.br +0 -0
- codex/static_root/assets/http-error-BTOBfcGY.52ced6f28420.js.gz +0 -0
- codex/static_root/assets/http-error-BTOBfcGY.js.br +0 -0
- codex/static_root/assets/http-error-BTOBfcGY.js.gz +0 -0
- codex/static_root/assets/library-tab-DiPEdOF7.ece2d642a9dc.js.br +0 -0
- codex/static_root/assets/library-tab-DiPEdOF7.ece2d642a9dc.js.gz +0 -0
- codex/static_root/assets/library-tab-DiPEdOF7.js.br +0 -0
- codex/static_root/assets/library-tab-DiPEdOF7.js.gz +0 -0
- codex/static_root/assets/main-BPIPjzsc.66def8991e38.js +0 -6
- codex/static_root/assets/main-BPIPjzsc.66def8991e38.js.br +0 -0
- codex/static_root/assets/main-BPIPjzsc.66def8991e38.js.gz +0 -0
- codex/static_root/assets/main-BPIPjzsc.js +0 -6
- codex/static_root/assets/main-BPIPjzsc.js.br +0 -0
- codex/static_root/assets/main-BPIPjzsc.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-CiyC6Al9.278b9978f36f.js +0 -1
- codex/static_root/assets/pager-full-pdf-CiyC6Al9.278b9978f36f.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-CiyC6Al9.278b9978f36f.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-CiyC6Al9.js +0 -1
- codex/static_root/assets/pager-full-pdf-CiyC6Al9.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-CiyC6Al9.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-C45-onwe.4722195bb60b.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-C45-onwe.4722195bb60b.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-C45-onwe.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-C45-onwe.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-CkIzuyx1.00c354a82e6e.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-CkIzuyx1.00c354a82e6e.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-CkIzuyx1.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-CkIzuyx1.js.gz +0 -0
- codex/static_root/assets/pdf-doc-BjlRPuf4.0f056fa321b6.js.br +0 -0
- codex/static_root/assets/pdf-doc-BjlRPuf4.0f056fa321b6.js.gz +0 -0
- codex/static_root/assets/pdf-doc-BjlRPuf4.js.br +0 -0
- codex/static_root/assets/pdf-doc-BjlRPuf4.js.gz +0 -0
- codex/static_root/assets/reader-_stAWL-4.5089e9144795.css +0 -1
- codex/static_root/assets/reader-_stAWL-4.5089e9144795.css.br +0 -0
- codex/static_root/assets/reader-_stAWL-4.5089e9144795.css.gz +0 -0
- codex/static_root/assets/reader-_stAWL-4.css +0 -1
- codex/static_root/assets/reader-_stAWL-4.css.br +0 -0
- codex/static_root/assets/reader-_stAWL-4.css.gz +0 -0
- codex/static_root/assets/reader-ucxnLi2K.d0fbce0f03c1.js +0 -2
- codex/static_root/assets/reader-ucxnLi2K.d0fbce0f03c1.js.br +0 -0
- codex/static_root/assets/reader-ucxnLi2K.d0fbce0f03c1.js.gz +0 -0
- codex/static_root/assets/reader-ucxnLi2K.js +0 -2
- codex/static_root/assets/reader-ucxnLi2K.js.br +0 -0
- codex/static_root/assets/reader-ucxnLi2K.js.gz +0 -0
- codex/static_root/assets/relation-chips-CUSatZET.a58031ff8141.js.br +0 -0
- codex/static_root/assets/relation-chips-CUSatZET.a58031ff8141.js.gz +0 -0
- codex/static_root/assets/relation-chips-CUSatZET.js.br +0 -0
- codex/static_root/assets/relation-chips-CUSatZET.js.gz +0 -0
- codex/static_root/assets/settings-drawer-BSHTAsJ9.1d07ce084fc9.js.br +0 -0
- codex/static_root/assets/settings-drawer-BSHTAsJ9.1d07ce084fc9.js.gz +0 -0
- codex/static_root/assets/settings-drawer-BSHTAsJ9.js.br +0 -0
- codex/static_root/assets/settings-drawer-BSHTAsJ9.js.gz +0 -0
- codex/static_root/assets/stats-tab-BXGisn5N.9b7a71e7fe28.css.br +0 -0
- codex/static_root/assets/stats-tab-BXGisn5N.9b7a71e7fe28.css.gz +0 -0
- codex/static_root/assets/stats-tab-BXGisn5N.css.br +0 -0
- codex/static_root/assets/stats-tab-BXGisn5N.css.gz +0 -0
- codex/static_root/assets/stats-tab-DKXVB2Cc.0a3de58bf5ee.js +0 -1
- codex/static_root/assets/stats-tab-DKXVB2Cc.0a3de58bf5ee.js.br +0 -0
- codex/static_root/assets/stats-tab-DKXVB2Cc.0a3de58bf5ee.js.gz +0 -0
- codex/static_root/assets/stats-tab-DKXVB2Cc.js +0 -1
- codex/static_root/assets/stats-tab-DKXVB2Cc.js.br +0 -0
- codex/static_root/assets/stats-tab-DKXVB2Cc.js.gz +0 -0
- codex/static_root/assets/task-tab-NORFAa9p.97e07e366ddd.js.br +0 -0
- codex/static_root/assets/task-tab-NORFAa9p.97e07e366ddd.js.gz +0 -0
- codex/static_root/assets/task-tab-NORFAa9p.js.br +0 -0
- codex/static_root/assets/task-tab-NORFAa9p.js.gz +0 -0
- codex/static_root/assets/unauthorized-RHaQZRfr.a234e9403f60.js +0 -1
- codex/static_root/assets/unauthorized-RHaQZRfr.a234e9403f60.js.br +0 -0
- codex/static_root/assets/unauthorized-RHaQZRfr.a234e9403f60.js.gz +0 -0
- codex/static_root/assets/unauthorized-RHaQZRfr.js +0 -1
- codex/static_root/assets/unauthorized-RHaQZRfr.js.br +0 -0
- codex/static_root/assets/unauthorized-RHaQZRfr.js.gz +0 -0
- codex/static_root/assets/unauthorized-muDsv-rC.2166ec8b3a32.css.br +0 -0
- codex/static_root/assets/unauthorized-muDsv-rC.2166ec8b3a32.css.gz +0 -0
- codex/static_root/assets/unauthorized-muDsv-rC.css.br +0 -0
- codex/static_root/assets/unauthorized-muDsv-rC.css.gz +0 -0
- codex/static_root/assets/user-tab-CHbyN1EW.e7206db08680.js.br +0 -0
- codex/static_root/assets/user-tab-CHbyN1EW.e7206db08680.js.gz +0 -0
- codex/static_root/assets/user-tab-CHbyN1EW.js.br +0 -0
- codex/static_root/assets/user-tab-CHbyN1EW.js.gz +0 -0
- codex/static_root/js/choices-admin.1a20a5648f20.json +0 -1
- codex/static_root/js/choices-admin.1a20a5648f20.json.br +0 -0
- codex/static_root/js/choices-admin.1a20a5648f20.json.gz +0 -0
- codex/static_root/manifest.0fe31a6cb99f.json +0 -635
- codex/static_root/manifest.0fe31a6cb99f.json.br +0 -0
- codex/static_root/manifest.0fe31a6cb99f.json.gz +0 -0
- codex/templates/search/indexes/codex/comic_text.txt +0 -47
- codex/views/browser/filters/search.py +0 -196
- {codex-1.6.19.dist-info → codex-1.7.0a0.dist-info}/LICENSE +0 -0
- {codex-1.6.19.dist-info → codex-1.7.0a0.dist-info}/WHEEL +0 -0
- {codex-1.6.19.dist-info → codex-1.7.0a0.dist-info}/entry_points.txt +0 -0
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
from django.conf import settings
|
|
2
|
-
|
|
3
|
-
DEFAULT_ALIAS = "default"
|
|
4
|
-
|
|
5
|
-
# Reserved field names
|
|
6
|
-
ID = getattr(settings, "HAYSTACK_ID_FIELD", "id")
|
|
7
|
-
DJANGO_CT = getattr(settings, "HAYSTACK_DJANGO_CT_FIELD", "django_ct")
|
|
8
|
-
DJANGO_ID = getattr(settings, "HAYSTACK_DJANGO_ID_FIELD", "django_id")
|
|
9
|
-
DOCUMENT_FIELD = getattr(settings, "HAYSTACK_DOCUMENT_FIELD", "text")
|
|
10
|
-
ALL_FIELD = "_all"
|
|
11
|
-
|
|
12
|
-
# Default operator. Valid options are AND/OR.
|
|
13
|
-
DEFAULT_OPERATOR = getattr(settings, "HAYSTACK_DEFAULT_OPERATOR", "AND")
|
|
14
|
-
|
|
15
|
-
# Default values on elasticsearch
|
|
16
|
-
FUZZINESS = getattr(settings, "HAYSTACK_FUZZINESS", "AUTO")
|
|
17
|
-
FUZZY_MIN_SIM = getattr(settings, "HAYSTACK_FUZZY_MIN_SIM", 0.5)
|
|
18
|
-
FUZZY_MAX_EXPANSIONS = getattr(settings, "HAYSTACK_FUZZY_MAX_EXPANSIONS", 50)
|
|
19
|
-
|
|
20
|
-
# Default values on whoosh
|
|
21
|
-
FUZZY_WHOOSH_MIN_PREFIX = getattr(settings, "HAYSTACK_FUZZY_WHOOSH_MIN_PREFIX", 3)
|
|
22
|
-
FUZZY_WHOOSH_MAX_EDITS = getattr(settings, "HAYSTACK_FUZZY_WHOOSH_MAX_EDITS", 2)
|
|
23
|
-
|
|
24
|
-
# Valid expression extensions.
|
|
25
|
-
VALID_FILTERS = {
|
|
26
|
-
"contains",
|
|
27
|
-
"exact",
|
|
28
|
-
"gt",
|
|
29
|
-
"gte",
|
|
30
|
-
"lt",
|
|
31
|
-
"lte",
|
|
32
|
-
"in",
|
|
33
|
-
"startswith",
|
|
34
|
-
"range",
|
|
35
|
-
"endswith",
|
|
36
|
-
"content",
|
|
37
|
-
"fuzzy",
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
FILTER_SEPARATOR = "__"
|
|
42
|
-
|
|
43
|
-
# The maximum number of items to display in a SearchQuerySet.__repr__
|
|
44
|
-
REPR_OUTPUT_SIZE = 20
|
|
45
|
-
|
|
46
|
-
# Number of SearchResults to load at a time.
|
|
47
|
-
ITERATOR_LOAD_PER_QUERY = getattr(settings, "HAYSTACK_ITERATOR_LOAD_PER_QUERY", 10)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
# A marker class in the hierarchy to indicate that it handles search data.
|
|
51
|
-
class Indexable:
|
|
52
|
-
haystack_use_for_indexing = True
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# For the geo bits, since that's what Solr & Elasticsearch seem to silently
|
|
56
|
-
# assume...
|
|
57
|
-
WGS_84_SRID = 4326
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
class HaystackError(Exception):
|
|
2
|
-
"""A generic exception for all others to extend."""
|
|
3
|
-
|
|
4
|
-
pass
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class SearchBackendError(HaystackError):
|
|
8
|
-
"""Raised when a backend can not be found."""
|
|
9
|
-
|
|
10
|
-
pass
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class SearchFieldError(HaystackError):
|
|
14
|
-
"""Raised when a field encounters an error."""
|
|
15
|
-
|
|
16
|
-
pass
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class MissingDependency(HaystackError):
|
|
20
|
-
"""Raised when a library a backend depends on can not be found."""
|
|
21
|
-
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class NotHandled(HaystackError):
|
|
26
|
-
"""Raised when a model is not handled by the router setup."""
|
|
27
|
-
|
|
28
|
-
pass
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class MoreLikeThisError(HaystackError):
|
|
32
|
-
"""Raised when a model instance has not been provided for More Like This."""
|
|
33
|
-
|
|
34
|
-
pass
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class FacetingError(HaystackError):
|
|
38
|
-
"""Raised when incorrect arguments have been provided for faceting."""
|
|
39
|
-
|
|
40
|
-
pass
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class SpatialError(HaystackError):
|
|
44
|
-
"""Raised when incorrect arguments have been provided for spatial."""
|
|
45
|
-
|
|
46
|
-
pass
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class StatsError(HaystackError):
|
|
50
|
-
"Raised when incorrect arguments have been provided for stats"
|
|
51
|
-
pass
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class SkipDocument(HaystackError):
|
|
55
|
-
"""Raised when a document should be skipped while updating"""
|
|
56
|
-
|
|
57
|
-
pass
|
codex/_vendor/haystack/fields.py
DELETED
|
@@ -1,562 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
from inspect import ismethod
|
|
3
|
-
|
|
4
|
-
from django.template import loader
|
|
5
|
-
import datetime as datetime_safe
|
|
6
|
-
|
|
7
|
-
from ..haystack.exceptions import SearchFieldError
|
|
8
|
-
from ..haystack.utils import get_model_ct_tuple
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class NOT_PROVIDED:
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
# Note that dates in the full ISO 8601 format will be accepted as long as the hour/minute/second components
|
|
16
|
-
# are zeroed for compatibility with search backends which lack a date time distinct from datetime:
|
|
17
|
-
DATE_REGEX = re.compile(
|
|
18
|
-
r"^(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})(?:|T00:00:00Z?)$"
|
|
19
|
-
)
|
|
20
|
-
DATETIME_REGEX = re.compile(
|
|
21
|
-
r"^(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})(T|\s+)(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2}).*?$"
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
# All the SearchFields variants.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class SearchField:
|
|
29
|
-
"""The base implementation of a search field."""
|
|
30
|
-
|
|
31
|
-
field_type = None
|
|
32
|
-
|
|
33
|
-
def __init__(
|
|
34
|
-
self,
|
|
35
|
-
model_attr=None,
|
|
36
|
-
use_template=False,
|
|
37
|
-
template_name=None,
|
|
38
|
-
document=False,
|
|
39
|
-
indexed=True,
|
|
40
|
-
stored=True,
|
|
41
|
-
faceted=False,
|
|
42
|
-
default=NOT_PROVIDED,
|
|
43
|
-
null=False,
|
|
44
|
-
index_fieldname=None,
|
|
45
|
-
facet_class=None,
|
|
46
|
-
boost=1.0,
|
|
47
|
-
weight=None,
|
|
48
|
-
analyzer=None,
|
|
49
|
-
):
|
|
50
|
-
# Track what the index thinks this field is called.
|
|
51
|
-
self.instance_name = None
|
|
52
|
-
self.model_attr = model_attr
|
|
53
|
-
self.use_template = use_template
|
|
54
|
-
self.template_name = template_name
|
|
55
|
-
self.document = document
|
|
56
|
-
self.indexed = indexed
|
|
57
|
-
self.stored = stored
|
|
58
|
-
self.faceted = faceted
|
|
59
|
-
self._default = default
|
|
60
|
-
self.null = null
|
|
61
|
-
self.index_fieldname = index_fieldname
|
|
62
|
-
self.boost = weight or boost
|
|
63
|
-
self.analyzer = analyzer
|
|
64
|
-
self.is_multivalued = False
|
|
65
|
-
|
|
66
|
-
# We supply the facet_class for making it easy to create a faceted
|
|
67
|
-
# field based off of this field.
|
|
68
|
-
self.facet_class = facet_class
|
|
69
|
-
|
|
70
|
-
if self.facet_class is None:
|
|
71
|
-
self.facet_class = FacetCharField
|
|
72
|
-
|
|
73
|
-
self.set_instance_name(None)
|
|
74
|
-
|
|
75
|
-
def set_instance_name(self, instance_name):
|
|
76
|
-
self.instance_name = instance_name
|
|
77
|
-
|
|
78
|
-
if self.index_fieldname is None:
|
|
79
|
-
self.index_fieldname = self.instance_name
|
|
80
|
-
|
|
81
|
-
def has_default(self):
|
|
82
|
-
"""Returns a boolean of whether this field has a default value."""
|
|
83
|
-
return self._default is not NOT_PROVIDED
|
|
84
|
-
|
|
85
|
-
@property
|
|
86
|
-
def default(self):
|
|
87
|
-
"""Returns the default value for the field."""
|
|
88
|
-
if callable(self._default):
|
|
89
|
-
return self._default()
|
|
90
|
-
|
|
91
|
-
return self._default
|
|
92
|
-
|
|
93
|
-
def prepare(self, obj):
|
|
94
|
-
"""
|
|
95
|
-
Takes data from the provided object and prepares it for storage in the
|
|
96
|
-
index.
|
|
97
|
-
"""
|
|
98
|
-
# Give priority to a template.
|
|
99
|
-
if self.use_template:
|
|
100
|
-
return self.prepare_template(obj)
|
|
101
|
-
elif self.model_attr is not None:
|
|
102
|
-
attrs = self.split_model_attr_lookups()
|
|
103
|
-
current_objects = [obj]
|
|
104
|
-
|
|
105
|
-
values = self.resolve_attributes_lookup(current_objects, attrs)
|
|
106
|
-
|
|
107
|
-
if len(values) == 1:
|
|
108
|
-
return values[0]
|
|
109
|
-
elif len(values) > 1:
|
|
110
|
-
return values
|
|
111
|
-
|
|
112
|
-
if self.has_default():
|
|
113
|
-
return self.default
|
|
114
|
-
else:
|
|
115
|
-
return None
|
|
116
|
-
|
|
117
|
-
def resolve_attributes_lookup(self, current_objects, attributes):
|
|
118
|
-
"""
|
|
119
|
-
Recursive method that looks, for one or more objects, for an attribute that can be multiple
|
|
120
|
-
objects (relations) deep.
|
|
121
|
-
"""
|
|
122
|
-
values = []
|
|
123
|
-
|
|
124
|
-
for current_object in current_objects:
|
|
125
|
-
if not hasattr(current_object, attributes[0]):
|
|
126
|
-
raise SearchFieldError(
|
|
127
|
-
"The model '%r' does not have a model_attr '%s'."
|
|
128
|
-
% (repr(current_object), attributes[0])
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
if len(attributes) > 1:
|
|
132
|
-
current_objects_in_attr = self.get_iterable_objects(
|
|
133
|
-
getattr(current_object, attributes[0])
|
|
134
|
-
)
|
|
135
|
-
values.extend(
|
|
136
|
-
self.resolve_attributes_lookup(
|
|
137
|
-
current_objects_in_attr, attributes[1:]
|
|
138
|
-
)
|
|
139
|
-
)
|
|
140
|
-
continue
|
|
141
|
-
|
|
142
|
-
current_object = getattr(current_object, attributes[0])
|
|
143
|
-
|
|
144
|
-
if current_object is None:
|
|
145
|
-
if self.has_default():
|
|
146
|
-
current_object = self._default
|
|
147
|
-
elif self.null:
|
|
148
|
-
current_object = None
|
|
149
|
-
else:
|
|
150
|
-
raise SearchFieldError(
|
|
151
|
-
"The model '%s' combined with model_attr '%s' returned None, but doesn't allow "
|
|
152
|
-
"a default or null value."
|
|
153
|
-
% (repr(current_object), self.model_attr)
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
if callable(current_object):
|
|
157
|
-
values.append(current_object())
|
|
158
|
-
else:
|
|
159
|
-
values.append(current_object)
|
|
160
|
-
|
|
161
|
-
return values
|
|
162
|
-
|
|
163
|
-
def split_model_attr_lookups(self):
|
|
164
|
-
"""Returns list of nested attributes for looking through the relation."""
|
|
165
|
-
return self.model_attr.split("__")
|
|
166
|
-
|
|
167
|
-
@classmethod
|
|
168
|
-
def get_iterable_objects(cls, current_objects):
|
|
169
|
-
"""
|
|
170
|
-
Returns iterable of objects that contain data. For example, resolves Django ManyToMany relationship
|
|
171
|
-
so the attributes of the related models can then be accessed.
|
|
172
|
-
"""
|
|
173
|
-
if current_objects is None:
|
|
174
|
-
return []
|
|
175
|
-
|
|
176
|
-
if hasattr(current_objects, "all"):
|
|
177
|
-
# i.e, Django ManyToMany relationships
|
|
178
|
-
if ismethod(current_objects.all):
|
|
179
|
-
return current_objects.all()
|
|
180
|
-
return []
|
|
181
|
-
|
|
182
|
-
elif not hasattr(current_objects, "__iter__"):
|
|
183
|
-
current_objects = [current_objects]
|
|
184
|
-
|
|
185
|
-
return current_objects
|
|
186
|
-
|
|
187
|
-
def prepare_template(self, obj):
|
|
188
|
-
"""
|
|
189
|
-
Flattens an object for indexing.
|
|
190
|
-
|
|
191
|
-
This loads a template
|
|
192
|
-
(``search/indexes/{app_label}/{model_name}_{field_name}.txt``) and
|
|
193
|
-
returns the result of rendering that template. ``object`` will be in
|
|
194
|
-
its context.
|
|
195
|
-
"""
|
|
196
|
-
if self.instance_name is None and self.template_name is None:
|
|
197
|
-
raise SearchFieldError(
|
|
198
|
-
"This field requires either its instance_name variable to be populated or an explicit template_name in order to load the correct template."
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
if self.template_name is not None:
|
|
202
|
-
template_names = self.template_name
|
|
203
|
-
|
|
204
|
-
if not isinstance(template_names, (list, tuple)):
|
|
205
|
-
template_names = [template_names]
|
|
206
|
-
else:
|
|
207
|
-
app_label, model_name = get_model_ct_tuple(obj)
|
|
208
|
-
template_names = [
|
|
209
|
-
"search/indexes/%s/%s_%s.txt"
|
|
210
|
-
% (app_label, model_name, self.instance_name)
|
|
211
|
-
]
|
|
212
|
-
|
|
213
|
-
t = loader.select_template(template_names)
|
|
214
|
-
return t.render({"object": obj})
|
|
215
|
-
|
|
216
|
-
def convert(self, value):
|
|
217
|
-
"""
|
|
218
|
-
Handles conversion between the data found and the type of the field.
|
|
219
|
-
|
|
220
|
-
Extending classes should override this method and provide correct
|
|
221
|
-
data coercion.
|
|
222
|
-
"""
|
|
223
|
-
return value
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
class CharField(SearchField):
|
|
227
|
-
field_type = "string"
|
|
228
|
-
|
|
229
|
-
def __init__(self, **kwargs):
|
|
230
|
-
if kwargs.get("facet_class") is None:
|
|
231
|
-
kwargs["facet_class"] = FacetCharField
|
|
232
|
-
|
|
233
|
-
super().__init__(**kwargs)
|
|
234
|
-
|
|
235
|
-
def prepare(self, obj):
|
|
236
|
-
return self.convert(super().prepare(obj))
|
|
237
|
-
|
|
238
|
-
def convert(self, value):
|
|
239
|
-
if value is None:
|
|
240
|
-
return None
|
|
241
|
-
|
|
242
|
-
return str(value)
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
class LocationField(SearchField):
|
|
246
|
-
field_type = "location"
|
|
247
|
-
|
|
248
|
-
def prepare(self, obj):
|
|
249
|
-
from ..haystack.utils.geo import ensure_point
|
|
250
|
-
|
|
251
|
-
value = super().prepare(obj)
|
|
252
|
-
|
|
253
|
-
if value is None:
|
|
254
|
-
return None
|
|
255
|
-
|
|
256
|
-
pnt = ensure_point(value)
|
|
257
|
-
pnt_lng, pnt_lat = pnt.coords
|
|
258
|
-
return "%s,%s" % (pnt_lat, pnt_lng)
|
|
259
|
-
|
|
260
|
-
def convert(self, value):
|
|
261
|
-
from django.contrib.gis.geos import Point
|
|
262
|
-
|
|
263
|
-
from ..haystack.utils.geo import ensure_point
|
|
264
|
-
|
|
265
|
-
if value is None:
|
|
266
|
-
return None
|
|
267
|
-
|
|
268
|
-
if hasattr(value, "geom_type"):
|
|
269
|
-
value = ensure_point(value)
|
|
270
|
-
return value
|
|
271
|
-
|
|
272
|
-
if isinstance(value, str):
|
|
273
|
-
lat, lng = value.split(",")
|
|
274
|
-
elif isinstance(value, (list, tuple)):
|
|
275
|
-
# GeoJSON-alike
|
|
276
|
-
lat, lng = value[1], value[0]
|
|
277
|
-
elif isinstance(value, dict):
|
|
278
|
-
lat = value.get("lat", 0)
|
|
279
|
-
lng = value.get("lon", 0)
|
|
280
|
-
else:
|
|
281
|
-
raise TypeError("Unable to extract coordinates from %r" % value)
|
|
282
|
-
|
|
283
|
-
value = Point(float(lng), float(lat))
|
|
284
|
-
return value
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
class NgramField(CharField):
|
|
288
|
-
field_type = "ngram"
|
|
289
|
-
|
|
290
|
-
def __init__(self, **kwargs):
|
|
291
|
-
if kwargs.get("faceted") is True:
|
|
292
|
-
raise SearchFieldError("%s can not be faceted." % self.__class__.__name__)
|
|
293
|
-
|
|
294
|
-
super().__init__(**kwargs)
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
class EdgeNgramField(NgramField):
|
|
298
|
-
field_type = "edge_ngram"
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
class IntegerField(SearchField):
|
|
302
|
-
field_type = "integer"
|
|
303
|
-
|
|
304
|
-
def __init__(self, **kwargs):
|
|
305
|
-
if kwargs.get("facet_class") is None:
|
|
306
|
-
kwargs["facet_class"] = FacetIntegerField
|
|
307
|
-
|
|
308
|
-
super().__init__(**kwargs)
|
|
309
|
-
|
|
310
|
-
def prepare(self, obj):
|
|
311
|
-
return self.convert(super().prepare(obj))
|
|
312
|
-
|
|
313
|
-
def convert(self, value):
|
|
314
|
-
if value is None:
|
|
315
|
-
return None
|
|
316
|
-
|
|
317
|
-
return int(value)
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
class FloatField(SearchField):
|
|
321
|
-
field_type = "float"
|
|
322
|
-
|
|
323
|
-
def __init__(self, **kwargs):
|
|
324
|
-
if kwargs.get("facet_class") is None:
|
|
325
|
-
kwargs["facet_class"] = FacetFloatField
|
|
326
|
-
|
|
327
|
-
super().__init__(**kwargs)
|
|
328
|
-
|
|
329
|
-
def prepare(self, obj):
|
|
330
|
-
return self.convert(super().prepare(obj))
|
|
331
|
-
|
|
332
|
-
def convert(self, value):
|
|
333
|
-
if value is None:
|
|
334
|
-
return None
|
|
335
|
-
|
|
336
|
-
return float(value)
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
class DecimalField(SearchField):
|
|
340
|
-
field_type = "string"
|
|
341
|
-
|
|
342
|
-
def __init__(self, **kwargs):
|
|
343
|
-
if kwargs.get("facet_class") is None:
|
|
344
|
-
kwargs["facet_class"] = FacetDecimalField
|
|
345
|
-
|
|
346
|
-
super().__init__(**kwargs)
|
|
347
|
-
|
|
348
|
-
def prepare(self, obj):
|
|
349
|
-
return self.convert(super().prepare(obj))
|
|
350
|
-
|
|
351
|
-
def convert(self, value):
|
|
352
|
-
if value is None:
|
|
353
|
-
return None
|
|
354
|
-
|
|
355
|
-
return str(value)
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
class BooleanField(SearchField):
|
|
359
|
-
field_type = "boolean"
|
|
360
|
-
|
|
361
|
-
def __init__(self, **kwargs):
|
|
362
|
-
if kwargs.get("facet_class") is None:
|
|
363
|
-
kwargs["facet_class"] = FacetBooleanField
|
|
364
|
-
|
|
365
|
-
super().__init__(**kwargs)
|
|
366
|
-
|
|
367
|
-
def prepare(self, obj):
|
|
368
|
-
return self.convert(super().prepare(obj))
|
|
369
|
-
|
|
370
|
-
def convert(self, value):
|
|
371
|
-
if value is None:
|
|
372
|
-
return None
|
|
373
|
-
|
|
374
|
-
return bool(value)
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
class DateField(SearchField):
|
|
378
|
-
field_type = "date"
|
|
379
|
-
|
|
380
|
-
def __init__(self, **kwargs):
|
|
381
|
-
if kwargs.get("facet_class") is None:
|
|
382
|
-
kwargs["facet_class"] = FacetDateField
|
|
383
|
-
|
|
384
|
-
super().__init__(**kwargs)
|
|
385
|
-
|
|
386
|
-
def prepare(self, obj):
|
|
387
|
-
return self.convert(super().prepare(obj))
|
|
388
|
-
|
|
389
|
-
def convert(self, value):
|
|
390
|
-
if value is None:
|
|
391
|
-
return None
|
|
392
|
-
|
|
393
|
-
if isinstance(value, str):
|
|
394
|
-
match = DATE_REGEX.search(value)
|
|
395
|
-
|
|
396
|
-
if match:
|
|
397
|
-
data = match.groupdict()
|
|
398
|
-
return datetime_safe.date(
|
|
399
|
-
int(data["year"]), int(data["month"]), int(data["day"])
|
|
400
|
-
)
|
|
401
|
-
else:
|
|
402
|
-
raise SearchFieldError(
|
|
403
|
-
"Date provided to '%s' field doesn't appear to be a valid date string: '%s'"
|
|
404
|
-
% (self.instance_name, value)
|
|
405
|
-
)
|
|
406
|
-
|
|
407
|
-
return value
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
class DateTimeField(SearchField):
|
|
411
|
-
field_type = "datetime"
|
|
412
|
-
|
|
413
|
-
def __init__(self, **kwargs):
|
|
414
|
-
if kwargs.get("facet_class") is None:
|
|
415
|
-
kwargs["facet_class"] = FacetDateTimeField
|
|
416
|
-
|
|
417
|
-
super().__init__(**kwargs)
|
|
418
|
-
|
|
419
|
-
def prepare(self, obj):
|
|
420
|
-
return self.convert(super().prepare(obj))
|
|
421
|
-
|
|
422
|
-
def convert(self, value):
|
|
423
|
-
if value is None:
|
|
424
|
-
return None
|
|
425
|
-
|
|
426
|
-
if isinstance(value, str):
|
|
427
|
-
match = DATETIME_REGEX.search(value)
|
|
428
|
-
|
|
429
|
-
if match:
|
|
430
|
-
data = match.groupdict()
|
|
431
|
-
return datetime_safe.datetime(
|
|
432
|
-
int(data["year"]),
|
|
433
|
-
int(data["month"]),
|
|
434
|
-
int(data["day"]),
|
|
435
|
-
int(data["hour"]),
|
|
436
|
-
int(data["minute"]),
|
|
437
|
-
int(data["second"]),
|
|
438
|
-
)
|
|
439
|
-
else:
|
|
440
|
-
raise SearchFieldError(
|
|
441
|
-
"Datetime provided to '%s' field doesn't appear to be a valid datetime string: '%s'"
|
|
442
|
-
% (self.instance_name, value)
|
|
443
|
-
)
|
|
444
|
-
|
|
445
|
-
return value
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
class MultiValueField(SearchField):
|
|
449
|
-
field_type = "string"
|
|
450
|
-
|
|
451
|
-
def __init__(self, **kwargs):
|
|
452
|
-
if kwargs.get("facet_class") is None:
|
|
453
|
-
kwargs["facet_class"] = FacetMultiValueField
|
|
454
|
-
|
|
455
|
-
if kwargs.get("use_template") is True:
|
|
456
|
-
raise SearchFieldError(
|
|
457
|
-
"'%s' fields can not use templates to prepare their data."
|
|
458
|
-
% self.__class__.__name__
|
|
459
|
-
)
|
|
460
|
-
|
|
461
|
-
super().__init__(**kwargs)
|
|
462
|
-
self.is_multivalued = True
|
|
463
|
-
|
|
464
|
-
def prepare(self, obj):
|
|
465
|
-
return self.convert(super().prepare(obj))
|
|
466
|
-
|
|
467
|
-
def convert(self, value):
|
|
468
|
-
if value is None:
|
|
469
|
-
return None
|
|
470
|
-
|
|
471
|
-
if hasattr(value, "__iter__") and not isinstance(value, str):
|
|
472
|
-
return value
|
|
473
|
-
|
|
474
|
-
return [value]
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
class FacetField(SearchField):
|
|
478
|
-
"""
|
|
479
|
-
``FacetField`` is slightly different than the other fields because it can
|
|
480
|
-
work in conjunction with other fields as its data source.
|
|
481
|
-
|
|
482
|
-
Accepts an optional ``facet_for`` kwarg, which should be the field name
|
|
483
|
-
(not ``index_fieldname``) of the field it should pull data from.
|
|
484
|
-
"""
|
|
485
|
-
|
|
486
|
-
instance_name = None
|
|
487
|
-
|
|
488
|
-
def __init__(self, **kwargs):
|
|
489
|
-
handled_kwargs = self.handle_facet_parameters(kwargs)
|
|
490
|
-
super().__init__(**handled_kwargs)
|
|
491
|
-
|
|
492
|
-
def handle_facet_parameters(self, kwargs):
|
|
493
|
-
if kwargs.get("faceted", False):
|
|
494
|
-
raise SearchFieldError(
|
|
495
|
-
"FacetField (%s) does not accept the 'faceted' argument."
|
|
496
|
-
% self.instance_name
|
|
497
|
-
)
|
|
498
|
-
|
|
499
|
-
if not kwargs.get("null", True):
|
|
500
|
-
raise SearchFieldError(
|
|
501
|
-
"FacetField (%s) does not accept False for the 'null' argument."
|
|
502
|
-
% self.instance_name
|
|
503
|
-
)
|
|
504
|
-
|
|
505
|
-
if not kwargs.get("indexed", True):
|
|
506
|
-
raise SearchFieldError(
|
|
507
|
-
"FacetField (%s) does not accept False for the 'indexed' argument."
|
|
508
|
-
% self.instance_name
|
|
509
|
-
)
|
|
510
|
-
|
|
511
|
-
if kwargs.get("facet_class"):
|
|
512
|
-
raise SearchFieldError(
|
|
513
|
-
"FacetField (%s) does not accept the 'facet_class' argument."
|
|
514
|
-
% self.instance_name
|
|
515
|
-
)
|
|
516
|
-
|
|
517
|
-
self.facet_for = None
|
|
518
|
-
self.facet_class = None
|
|
519
|
-
|
|
520
|
-
# Make sure the field is nullable.
|
|
521
|
-
kwargs["null"] = True
|
|
522
|
-
|
|
523
|
-
if "facet_for" in kwargs:
|
|
524
|
-
self.facet_for = kwargs["facet_for"]
|
|
525
|
-
del kwargs["facet_for"]
|
|
526
|
-
|
|
527
|
-
return kwargs
|
|
528
|
-
|
|
529
|
-
def get_facet_for_name(self):
|
|
530
|
-
return self.facet_for or self.instance_name
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
class FacetCharField(FacetField, CharField):
|
|
534
|
-
pass
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
class FacetIntegerField(FacetField, IntegerField):
|
|
538
|
-
pass
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
class FacetFloatField(FacetField, FloatField):
|
|
542
|
-
pass
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
class FacetDecimalField(FacetField, DecimalField):
|
|
546
|
-
pass
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
class FacetBooleanField(FacetField, BooleanField):
|
|
550
|
-
pass
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
class FacetDateField(FacetField, DateField):
|
|
554
|
-
pass
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
class FacetDateTimeField(FacetField, DateTimeField):
|
|
558
|
-
pass
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
class FacetMultiValueField(FacetField, MultiValueField):
|
|
562
|
-
pass
|