codex 1.8.5__py3-none-any.whl → 1.8.8__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/choices/admin.py +1 -0
- codex/librarian/scribe/importer/const.py +7 -3
- codex/librarian/scribe/importer/create/comics.py +0 -3
- codex/librarian/scribe/importer/delete/comics.py +7 -4
- codex/librarian/scribe/importer/delete/folders.py +2 -1
- codex/librarian/scribe/importer/read/aggregate_path.py +53 -13
- codex/librarian/scribe/importer/read/extract.py +16 -13
- codex/librarian/scribe/importer/search/prepare.py +0 -7
- codex/librarian/scribe/importer/search/sync_m2m.py +2 -1
- codex/librarian/scribe/importer/search/update.py +18 -81
- codex/librarian/scribe/scribed.py +2 -13
- codex/librarian/scribe/{importer/search → search}/const.py +1 -13
- codex/librarian/scribe/search/prepare.py +162 -0
- codex/librarian/scribe/search/remove.py +22 -2
- codex/librarian/scribe/search/sync.py +88 -179
- codex/librarian/status_controller.py +25 -27
- codex/librarian/watchdog/event_batcherd.py +1 -1
- codex/migrations/0035_fts_optmize.py +136 -0
- codex/models/comic.py +0 -16
- codex/models/functions.py +3 -1
- codex/serializers/admin/tasks.py +1 -1
- codex/settings/__init__.py +26 -11
- codex/static_root/assets/VCheckbox-MwE_xq11.b2e2086608d9.js +1 -0
- codex/static_root/assets/VCheckbox-MwE_xq11.b2e2086608d9.js.br +0 -0
- codex/static_root/assets/VCheckbox-MwE_xq11.b2e2086608d9.js.gz +0 -0
- codex/static_root/assets/VCheckbox-MwE_xq11.js +1 -0
- codex/static_root/assets/VCheckbox-MwE_xq11.js.br +0 -0
- codex/static_root/assets/VCheckbox-MwE_xq11.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-BE6yrQ80.4a42f2c068f5.js → VCheckboxBtn-HUjl2ti_.f3e7b85503c6.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-HUjl2ti_.f3e7b85503c6.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-HUjl2ti_.f3e7b85503c6.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-BE6yrQ80.js → VCheckboxBtn-HUjl2ti_.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-HUjl2ti_.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-HUjl2ti_.js.gz +0 -0
- codex/static_root/assets/VCombobox-C1Osy24P.73168f28d07b.js +1 -0
- codex/static_root/assets/VCombobox-C1Osy24P.73168f28d07b.js.br +0 -0
- codex/static_root/assets/VCombobox-C1Osy24P.73168f28d07b.js.gz +0 -0
- codex/static_root/assets/VCombobox-C1Osy24P.js +1 -0
- codex/static_root/assets/VCombobox-C1Osy24P.js.br +0 -0
- codex/static_root/assets/VCombobox-C1Osy24P.js.gz +0 -0
- codex/static_root/assets/VDialog-c2XXqNJH.a4156ca20133.js +1 -0
- codex/static_root/assets/VDialog-c2XXqNJH.a4156ca20133.js.br +0 -0
- codex/static_root/assets/VDialog-c2XXqNJH.a4156ca20133.js.gz +0 -0
- codex/static_root/assets/VDialog-c2XXqNJH.js +1 -0
- codex/static_root/assets/VDialog-c2XXqNJH.js.br +0 -0
- codex/static_root/assets/VDialog-c2XXqNJH.js.gz +0 -0
- codex/static_root/assets/{VDivider-BEpvozL4.c9fd95940cb5.js → VDivider-C06z3Tn-.d5e3ed421a68.js} +1 -1
- codex/static_root/assets/VDivider-C06z3Tn-.d5e3ed421a68.js.br +0 -0
- codex/static_root/assets/VDivider-C06z3Tn-.d5e3ed421a68.js.gz +0 -0
- codex/static_root/assets/{VDivider-BEpvozL4.js → VDivider-C06z3Tn-.js} +1 -1
- codex/static_root/assets/VDivider-C06z3Tn-.js.br +0 -0
- codex/static_root/assets/VDivider-C06z3Tn-.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-BzyHQUL4.7e54cedf021c.js → VExpansionPanels-B8gzbonk.3532c6d08817.js} +1 -1
- codex/static_root/assets/VExpansionPanels-B8gzbonk.3532c6d08817.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-B8gzbonk.3532c6d08817.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-BzyHQUL4.js → VExpansionPanels-B8gzbonk.js} +1 -1
- codex/static_root/assets/VExpansionPanels-B8gzbonk.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-B8gzbonk.js.gz +0 -0
- codex/static_root/assets/{VForm-CmVlbmJK.887eb47d3534.js → VForm-Chf0FU2x.3e8425bff3d0.js} +1 -1
- codex/static_root/assets/VForm-Chf0FU2x.3e8425bff3d0.js.br +0 -0
- codex/static_root/assets/VForm-Chf0FU2x.3e8425bff3d0.js.gz +0 -0
- codex/static_root/assets/{VForm-CmVlbmJK.js → VForm-Chf0FU2x.js} +1 -1
- codex/static_root/assets/VForm-Chf0FU2x.js.br +0 -0
- codex/static_root/assets/VForm-Chf0FU2x.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-DWzKkq9W.daaabd353889.js → VRadioGroup-CHteIFqx.23cb51ee43e1.js} +1 -1
- codex/static_root/assets/VRadioGroup-CHteIFqx.23cb51ee43e1.js.br +0 -0
- codex/static_root/assets/VRadioGroup-CHteIFqx.23cb51ee43e1.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-DWzKkq9W.js → VRadioGroup-CHteIFqx.js} +1 -1
- codex/static_root/assets/VRadioGroup-CHteIFqx.js.br +0 -0
- codex/static_root/assets/VRadioGroup-CHteIFqx.js.gz +0 -0
- codex/static_root/assets/VSelect-BqS1Prvd.36bbebae4f0d.js +1 -0
- codex/static_root/assets/VSelect-BqS1Prvd.36bbebae4f0d.js.br +0 -0
- codex/static_root/assets/VSelect-BqS1Prvd.36bbebae4f0d.js.gz +0 -0
- codex/static_root/assets/VSelect-BqS1Prvd.js +1 -0
- codex/static_root/assets/VSelect-BqS1Prvd.js.br +0 -0
- codex/static_root/assets/VSelect-BqS1Prvd.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-BRWozKsT.d10531c1a243.js +1 -0
- codex/static_root/assets/VSelectionControl-BRWozKsT.d10531c1a243.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BRWozKsT.d10531c1a243.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-BRWozKsT.js +1 -0
- codex/static_root/assets/VSelectionControl-BRWozKsT.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BRWozKsT.js.gz +0 -0
- codex/static_root/assets/VTable-BT6w_ifJ.ee6b710fb398.js +1 -0
- codex/static_root/assets/VTable-BT6w_ifJ.ee6b710fb398.js.br +0 -0
- codex/static_root/assets/VTable-BT6w_ifJ.ee6b710fb398.js.gz +0 -0
- codex/static_root/assets/VTable-BT6w_ifJ.js +1 -0
- codex/static_root/assets/VTable-BT6w_ifJ.js.br +0 -0
- codex/static_root/assets/VTable-BT6w_ifJ.js.gz +0 -0
- codex/static_root/assets/VTable-BsI6FsWH.css +1 -0
- codex/static_root/assets/VTable-BsI6FsWH.css.br +0 -0
- codex/static_root/assets/VTable-BsI6FsWH.css.gz +0 -0
- codex/static_root/assets/VTable-BsI6FsWH.d4c54d44a5ab.css +1 -0
- codex/static_root/assets/VTable-BsI6FsWH.d4c54d44a5ab.css.br +0 -0
- codex/static_root/assets/VTable-BsI6FsWH.d4c54d44a5ab.css.gz +0 -0
- codex/static_root/assets/VWindowItem-QQWUVqMX.c22e707ac99c.css +1 -0
- codex/static_root/assets/VWindowItem-QQWUVqMX.c22e707ac99c.css.br +5 -0
- codex/static_root/assets/VWindowItem-QQWUVqMX.c22e707ac99c.css.gz +0 -0
- codex/static_root/assets/VWindowItem-QQWUVqMX.css +1 -0
- codex/static_root/assets/VWindowItem-QQWUVqMX.css.br +5 -0
- codex/static_root/assets/VWindowItem-QQWUVqMX.css.gz +0 -0
- codex/static_root/assets/{VWindowItem-DBU8ce0X.4bbcffa75b9a.js → VWindowItem-sfdsG_YK.ee17f6723988.js} +1 -1
- codex/static_root/assets/VWindowItem-sfdsG_YK.ee17f6723988.js.br +0 -0
- codex/static_root/assets/VWindowItem-sfdsG_YK.ee17f6723988.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-DBU8ce0X.js → VWindowItem-sfdsG_YK.js} +1 -1
- codex/static_root/assets/VWindowItem-sfdsG_YK.js.br +0 -0
- codex/static_root/assets/VWindowItem-sfdsG_YK.js.gz +0 -0
- codex/static_root/assets/{admin-CfqMNEyt.bebc609836d0.js → admin-DuEKXO1g.5c6bfe166705.js} +1 -1
- codex/static_root/assets/admin-DuEKXO1g.5c6bfe166705.js.br +0 -0
- codex/static_root/assets/admin-DuEKXO1g.5c6bfe166705.js.gz +0 -0
- codex/static_root/assets/{admin-CfqMNEyt.js → admin-DuEKXO1g.js} +1 -1
- codex/static_root/assets/admin-DuEKXO1g.js.br +0 -0
- codex/static_root/assets/admin-DuEKXO1g.js.gz +0 -0
- codex/static_root/assets/admin-menu-DBce75Uy.be45a0a53c1a.js +1 -0
- codex/static_root/assets/admin-menu-DBce75Uy.be45a0a53c1a.js.br +0 -0
- codex/static_root/assets/admin-menu-DBce75Uy.be45a0a53c1a.js.gz +0 -0
- codex/static_root/assets/admin-menu-DBce75Uy.js +1 -0
- codex/static_root/assets/admin-menu-DBce75Uy.js.br +0 -0
- codex/static_root/assets/admin-menu-DBce75Uy.js.gz +0 -0
- codex/static_root/assets/{admin-Bt81XU3H.ca36b1a1b799.js → admin-pnPIiLQj.b791e7869cf5.js} +1 -1
- codex/static_root/assets/admin-pnPIiLQj.b791e7869cf5.js.br +0 -0
- codex/static_root/assets/admin-pnPIiLQj.b791e7869cf5.js.gz +0 -0
- codex/static_root/assets/{admin-Bt81XU3H.js → admin-pnPIiLQj.js} +1 -1
- codex/static_root/assets/admin-pnPIiLQj.js.br +0 -0
- codex/static_root/assets/admin-pnPIiLQj.js.gz +0 -0
- codex/static_root/assets/{admin-settings-button-progress-BPQGNinn.53e05963f557.js → admin-settings-button-progress-C4VmW80I.c8d9033b8bc5.js} +1 -1
- codex/static_root/assets/admin-settings-button-progress-C4VmW80I.c8d9033b8bc5.js.br +0 -0
- codex/static_root/assets/admin-settings-button-progress-C4VmW80I.c8d9033b8bc5.js.gz +0 -0
- codex/static_root/assets/{admin-settings-button-progress-BPQGNinn.js → admin-settings-button-progress-C4VmW80I.js} +1 -1
- codex/static_root/assets/admin-settings-button-progress-C4VmW80I.js.br +0 -0
- codex/static_root/assets/admin-settings-button-progress-C4VmW80I.js.gz +0 -0
- codex/static_root/assets/browser-DOuRKBxy.c9a72e4f9498.js +1 -0
- codex/static_root/assets/browser-DOuRKBxy.c9a72e4f9498.js.br +0 -0
- codex/static_root/assets/browser-DOuRKBxy.c9a72e4f9498.js.gz +0 -0
- codex/static_root/assets/browser-DOuRKBxy.js +1 -0
- codex/static_root/assets/browser-DOuRKBxy.js.br +0 -0
- codex/static_root/assets/browser-DOuRKBxy.js.gz +0 -0
- codex/static_root/assets/{browser-Cdi7U5ku.bab9fccf0326.css → browser-TRzEFz_k.css} +1 -1
- codex/static_root/assets/browser-TRzEFz_k.css.br +0 -0
- codex/static_root/assets/browser-TRzEFz_k.css.gz +0 -0
- codex/static_root/assets/{browser-Cdi7U5ku.css → browser-TRzEFz_k.e8ae750c4a41.css} +1 -1
- codex/static_root/assets/browser-TRzEFz_k.e8ae750c4a41.css.br +0 -0
- codex/static_root/assets/browser-TRzEFz_k.e8ae750c4a41.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-B4tB0bVX.5b476ac6a873.js +1 -0
- codex/static_root/assets/change-password-dialog-B4tB0bVX.5b476ac6a873.js.br +0 -0
- codex/static_root/assets/change-password-dialog-B4tB0bVX.5b476ac6a873.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-B4tB0bVX.js +1 -0
- codex/static_root/assets/change-password-dialog-B4tB0bVX.js.br +0 -0
- codex/static_root/assets/change-password-dialog-B4tB0bVX.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-CgSU27R5.0127ce62d24c.js → confirm-dialog-C0DHEcnB.e2d9968f6fea.js} +1 -1
- codex/static_root/assets/confirm-dialog-C0DHEcnB.e2d9968f6fea.js.br +0 -0
- codex/static_root/assets/confirm-dialog-C0DHEcnB.e2d9968f6fea.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-CgSU27R5.js → confirm-dialog-C0DHEcnB.js} +1 -1
- codex/static_root/assets/confirm-dialog-C0DHEcnB.js.br +0 -0
- codex/static_root/assets/confirm-dialog-C0DHEcnB.js.gz +0 -0
- codex/static_root/assets/{datetime-column-Dw9zxZLR.cd8791cda91b.js → datetime-column-j_CRGEuQ.cc499deb52f7.js} +1 -1
- codex/static_root/assets/datetime-column-j_CRGEuQ.cc499deb52f7.js.br +4 -0
- codex/static_root/assets/datetime-column-j_CRGEuQ.cc499deb52f7.js.gz +0 -0
- codex/static_root/assets/{datetime-column-Dw9zxZLR.js → datetime-column-j_CRGEuQ.js} +1 -1
- codex/static_root/assets/datetime-column-j_CRGEuQ.js.br +4 -0
- codex/static_root/assets/datetime-column-j_CRGEuQ.js.gz +0 -0
- codex/static_root/assets/{filter-BNTCrH8l.c00298a8fccf.js → filter-Baea_DNH.985ef541d6af.js} +1 -1
- codex/static_root/assets/filter-Baea_DNH.985ef541d6af.js.br +0 -0
- codex/static_root/assets/filter-Baea_DNH.985ef541d6af.js.gz +0 -0
- codex/static_root/assets/{filter-BNTCrH8l.js → filter-Baea_DNH.js} +1 -1
- codex/static_root/assets/filter-Baea_DNH.js.br +0 -0
- codex/static_root/assets/filter-Baea_DNH.js.gz +0 -0
- codex/static_root/assets/{flag-tab-Xpq_xAF5.3f14de61afcc.js → flag-tab-DefdNLmr.0cf5a73c1c8c.js} +1 -1
- codex/static_root/assets/flag-tab-DefdNLmr.0cf5a73c1c8c.js.br +0 -0
- codex/static_root/assets/flag-tab-DefdNLmr.0cf5a73c1c8c.js.gz +0 -0
- codex/static_root/assets/{flag-tab-Xpq_xAF5.js → flag-tab-DefdNLmr.js} +1 -1
- codex/static_root/assets/flag-tab-DefdNLmr.js.br +0 -0
- codex/static_root/assets/flag-tab-DefdNLmr.js.gz +0 -0
- codex/static_root/assets/forwardRefs-Bvy6478W.409df679a82f.js +1 -0
- codex/static_root/assets/forwardRefs-Bvy6478W.409df679a82f.js.br +0 -0
- codex/static_root/assets/forwardRefs-Bvy6478W.409df679a82f.js.gz +0 -0
- codex/static_root/assets/forwardRefs-Bvy6478W.js +1 -0
- codex/static_root/assets/forwardRefs-Bvy6478W.js.br +0 -0
- codex/static_root/assets/forwardRefs-Bvy6478W.js.gz +0 -0
- codex/static_root/assets/{forwardRefs-B_sUWZn6.5114f206ca9c.css → forwardRefs-C3Z4qL85.48fb131ece85.css} +1 -1
- codex/static_root/assets/forwardRefs-C3Z4qL85.48fb131ece85.css.br +0 -0
- codex/static_root/assets/forwardRefs-C3Z4qL85.48fb131ece85.css.gz +0 -0
- codex/static_root/assets/{forwardRefs-B_sUWZn6.css → forwardRefs-C3Z4qL85.css} +1 -1
- codex/static_root/assets/forwardRefs-C3Z4qL85.css.br +0 -0
- codex/static_root/assets/forwardRefs-C3Z4qL85.css.gz +0 -0
- codex/static_root/assets/{group-tab-E_R0glEI.82e1d92be747.js → group-tab-C71MBY7x.483482eaaf8c.js} +1 -1
- codex/static_root/assets/group-tab-C71MBY7x.483482eaaf8c.js.br +0 -0
- codex/static_root/assets/group-tab-C71MBY7x.483482eaaf8c.js.gz +0 -0
- codex/static_root/assets/{group-tab-E_R0glEI.js → group-tab-C71MBY7x.js} +1 -1
- codex/static_root/assets/group-tab-C71MBY7x.js.br +0 -0
- codex/static_root/assets/group-tab-C71MBY7x.js.gz +0 -0
- codex/static_root/assets/http-error-mPrHO762.70c41cde5ee1.js +1 -0
- codex/static_root/assets/http-error-mPrHO762.70c41cde5ee1.js.br +0 -0
- codex/static_root/assets/http-error-mPrHO762.70c41cde5ee1.js.gz +0 -0
- codex/static_root/assets/http-error-mPrHO762.js +1 -0
- codex/static_root/assets/http-error-mPrHO762.js.br +0 -0
- codex/static_root/assets/http-error-mPrHO762.js.gz +0 -0
- codex/static_root/assets/{index-j9jeRHe0.294b614eaea1.js → index-Bxqss4CY.5f797cedb404.js} +1 -1
- codex/static_root/assets/index-Bxqss4CY.5f797cedb404.js.br +0 -0
- codex/static_root/assets/index-Bxqss4CY.5f797cedb404.js.gz +0 -0
- codex/static_root/assets/{index-j9jeRHe0.js → index-Bxqss4CY.js} +1 -1
- codex/static_root/assets/index-Bxqss4CY.js.br +0 -0
- codex/static_root/assets/index-Bxqss4CY.js.gz +0 -0
- codex/static_root/assets/library-tab-DG2bhQ_A.e831e11418e2.js +1 -0
- codex/static_root/assets/library-tab-DG2bhQ_A.e831e11418e2.js.br +0 -0
- codex/static_root/assets/library-tab-DG2bhQ_A.e831e11418e2.js.gz +0 -0
- codex/static_root/assets/library-tab-DG2bhQ_A.js +1 -0
- codex/static_root/assets/library-tab-DG2bhQ_A.js.br +0 -0
- codex/static_root/assets/library-tab-DG2bhQ_A.js.gz +0 -0
- codex/static_root/assets/main-RxUHaWll.d7d671319f8d.js +39 -0
- codex/static_root/assets/main-RxUHaWll.d7d671319f8d.js.br +0 -0
- codex/static_root/assets/main-RxUHaWll.d7d671319f8d.js.gz +0 -0
- codex/static_root/assets/main-RxUHaWll.js +39 -0
- codex/static_root/assets/main-RxUHaWll.js.br +0 -0
- codex/static_root/assets/main-RxUHaWll.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-DYbA0-qc.b66019cafd05.js +1 -0
- codex/static_root/assets/pager-full-pdf-DYbA0-qc.b66019cafd05.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-DYbA0-qc.b66019cafd05.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-DYbA0-qc.js +1 -0
- codex/static_root/assets/pager-full-pdf-DYbA0-qc.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-DYbA0-qc.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-ChW-jj1Q.0cf6985b630e.js +1 -0
- codex/static_root/assets/pagination-toolbar-ChW-jj1Q.0cf6985b630e.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-ChW-jj1Q.0cf6985b630e.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-ChW-jj1Q.js +1 -0
- codex/static_root/assets/pagination-toolbar-ChW-jj1Q.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-ChW-jj1Q.js.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-741OafNw.4f9155469274.css → pagination-toolbar-rUdD4-Qi.3a224c7806a5.css} +1 -1
- codex/static_root/assets/pagination-toolbar-rUdD4-Qi.3a224c7806a5.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-rUdD4-Qi.3a224c7806a5.css.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-741OafNw.css → pagination-toolbar-rUdD4-Qi.css} +1 -1
- codex/static_root/assets/pagination-toolbar-rUdD4-Qi.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-rUdD4-Qi.css.gz +0 -0
- codex/static_root/assets/{pdf-doc-XAg2nqnS.5a33f918a28a.js → pdf-doc-CfiAAYT8.c4fb1945d1c5.js} +1 -1
- codex/static_root/assets/pdf-doc-CfiAAYT8.c4fb1945d1c5.js.br +0 -0
- codex/static_root/assets/{pdf-doc-XAg2nqnS.5a33f918a28a.js.gz → pdf-doc-CfiAAYT8.c4fb1945d1c5.js.gz} +0 -0
- codex/static_root/assets/{pdf-doc-XAg2nqnS.js → pdf-doc-CfiAAYT8.js} +1 -1
- codex/static_root/assets/pdf-doc-CfiAAYT8.js.br +0 -0
- codex/static_root/assets/{pdf-doc-XAg2nqnS.js.gz → pdf-doc-CfiAAYT8.js.gz} +0 -0
- codex/static_root/assets/reader-BNwsMjad.78e4ad034141.js +2 -0
- codex/static_root/assets/reader-BNwsMjad.78e4ad034141.js.br +0 -0
- codex/static_root/assets/reader-BNwsMjad.78e4ad034141.js.gz +0 -0
- codex/static_root/assets/reader-BNwsMjad.js +2 -0
- codex/static_root/assets/reader-BNwsMjad.js.br +0 -0
- codex/static_root/assets/reader-BNwsMjad.js.gz +0 -0
- codex/static_root/assets/relation-chips-Cfk3FVE5.eadbc380a353.js +1 -0
- codex/static_root/assets/relation-chips-Cfk3FVE5.eadbc380a353.js.br +0 -0
- codex/static_root/assets/relation-chips-Cfk3FVE5.eadbc380a353.js.gz +0 -0
- codex/static_root/assets/relation-chips-Cfk3FVE5.js +1 -0
- codex/static_root/assets/relation-chips-Cfk3FVE5.js.br +0 -0
- codex/static_root/assets/relation-chips-Cfk3FVE5.js.gz +0 -0
- codex/static_root/assets/{relation-chips-CcFgPQOM.0b468249b62e.css → relation-chips-CpiT_4k-.b72d78f512e6.css} +1 -1
- codex/static_root/assets/relation-chips-CpiT_4k-.b72d78f512e6.css.br +0 -0
- codex/static_root/assets/relation-chips-CpiT_4k-.b72d78f512e6.css.gz +0 -0
- codex/static_root/assets/{relation-chips-CcFgPQOM.css → relation-chips-CpiT_4k-.css} +1 -1
- codex/static_root/assets/relation-chips-CpiT_4k-.css.br +0 -0
- codex/static_root/assets/relation-chips-CpiT_4k-.css.gz +0 -0
- codex/static_root/assets/{settings-drawer-CpS_aX4Z.9d4d9533d033.css → settings-drawer-B-pwZRSy.8fc8b237bb52.css} +1 -1
- codex/static_root/assets/settings-drawer-B-pwZRSy.8fc8b237bb52.css.br +0 -0
- codex/static_root/assets/settings-drawer-B-pwZRSy.8fc8b237bb52.css.gz +0 -0
- codex/static_root/assets/{settings-drawer-CpS_aX4Z.css → settings-drawer-B-pwZRSy.css} +1 -1
- codex/static_root/assets/settings-drawer-B-pwZRSy.css.br +0 -0
- codex/static_root/assets/settings-drawer-B-pwZRSy.css.gz +0 -0
- codex/static_root/assets/settings-drawer-BvHMmEFL.6b6d9bf0e2ad.js +2 -0
- codex/static_root/assets/settings-drawer-BvHMmEFL.6b6d9bf0e2ad.js.br +0 -0
- codex/static_root/assets/settings-drawer-BvHMmEFL.6b6d9bf0e2ad.js.gz +0 -0
- codex/static_root/assets/settings-drawer-BvHMmEFL.js +2 -0
- codex/static_root/assets/settings-drawer-BvHMmEFL.js.br +0 -0
- codex/static_root/assets/settings-drawer-BvHMmEFL.js.gz +0 -0
- codex/static_root/assets/{ssrBoot-CoIsTnhp.ab2c4669478d.js → ssrBoot-BBuVfjys.ee6df7695a63.js} +1 -1
- codex/static_root/assets/ssrBoot-BBuVfjys.ee6df7695a63.js.br +0 -0
- codex/static_root/assets/ssrBoot-BBuVfjys.ee6df7695a63.js.gz +0 -0
- codex/static_root/assets/{ssrBoot-CoIsTnhp.js → ssrBoot-BBuVfjys.js} +1 -1
- codex/static_root/assets/ssrBoot-BBuVfjys.js.br +0 -0
- codex/static_root/assets/ssrBoot-BBuVfjys.js.gz +0 -0
- codex/static_root/assets/{stats-tab-Bncgetpc.94f90b6a111b.js → stats-tab-BW725H_T.61e34db4cc39.js} +1 -1
- codex/static_root/assets/stats-tab-BW725H_T.61e34db4cc39.js.br +0 -0
- codex/static_root/assets/stats-tab-BW725H_T.61e34db4cc39.js.gz +0 -0
- codex/static_root/assets/{stats-tab-Bncgetpc.js → stats-tab-BW725H_T.js} +1 -1
- codex/static_root/assets/stats-tab-BW725H_T.js.br +0 -0
- codex/static_root/assets/stats-tab-BW725H_T.js.gz +0 -0
- codex/static_root/assets/task-tab-P3x-M3d5.59e0479f2f1e.js +1 -0
- codex/static_root/assets/task-tab-P3x-M3d5.59e0479f2f1e.js.br +0 -0
- codex/static_root/assets/task-tab-P3x-M3d5.59e0479f2f1e.js.gz +0 -0
- codex/static_root/assets/task-tab-P3x-M3d5.js +1 -0
- codex/static_root/assets/task-tab-P3x-M3d5.js.br +0 -0
- codex/static_root/assets/task-tab-P3x-M3d5.js.gz +0 -0
- codex/static_root/assets/{unauthorized-IXAh-oLS.be484d21eb2a.js → unauthorized-CC6sHmUB.394dffd78457.js} +1 -1
- codex/static_root/assets/unauthorized-CC6sHmUB.394dffd78457.js.br +0 -0
- codex/static_root/assets/unauthorized-CC6sHmUB.394dffd78457.js.gz +0 -0
- codex/static_root/assets/{unauthorized-IXAh-oLS.js → unauthorized-CC6sHmUB.js} +1 -1
- codex/static_root/assets/unauthorized-CC6sHmUB.js.br +0 -0
- codex/static_root/assets/unauthorized-CC6sHmUB.js.gz +0 -0
- codex/static_root/assets/user-tab-OaDKeq2f.ac3d682c35f1.js +1 -0
- codex/static_root/assets/user-tab-OaDKeq2f.ac3d682c35f1.js.br +0 -0
- codex/static_root/assets/user-tab-OaDKeq2f.ac3d682c35f1.js.gz +0 -0
- codex/static_root/assets/user-tab-OaDKeq2f.js +1 -0
- codex/static_root/assets/user-tab-OaDKeq2f.js.br +0 -0
- codex/static_root/assets/user-tab-OaDKeq2f.js.gz +0 -0
- codex/static_root/{manifest.92b1b461eee2.json → manifest.d51267c3637d.json} +310 -310
- codex/static_root/manifest.d51267c3637d.json.br +0 -0
- codex/static_root/manifest.d51267c3637d.json.gz +0 -0
- codex/static_root/manifest.json +310 -310
- codex/static_root/manifest.json.br +0 -0
- codex/static_root/manifest.json.gz +0 -0
- codex/static_root/staticfiles.json +1 -1
- codex/views/browser/filters/filter.py +1 -1
- codex/views/browser/filters/search/field/column.py +3 -3
- codex/views/browser/filters/search/parse.py +15 -10
- {codex-1.8.5.dist-info → codex-1.8.8.dist-info}/METADATA +5 -5
- {codex-1.8.5.dist-info → codex-1.8.8.dist-info}/RECORD +314 -312
- codex/static_root/assets/VCheckbox-DxJUMufz.9a175cfa72c8.js +0 -1
- codex/static_root/assets/VCheckbox-DxJUMufz.9a175cfa72c8.js.br +0 -0
- codex/static_root/assets/VCheckbox-DxJUMufz.9a175cfa72c8.js.gz +0 -0
- codex/static_root/assets/VCheckbox-DxJUMufz.js +0 -1
- codex/static_root/assets/VCheckbox-DxJUMufz.js.br +0 -0
- codex/static_root/assets/VCheckbox-DxJUMufz.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-BE6yrQ80.4a42f2c068f5.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-BE6yrQ80.4a42f2c068f5.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-BE6yrQ80.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-BE6yrQ80.js.gz +0 -0
- codex/static_root/assets/VCombobox-Bfyp0szs.b51553d29c8c.js +0 -1
- codex/static_root/assets/VCombobox-Bfyp0szs.b51553d29c8c.js.br +0 -0
- codex/static_root/assets/VCombobox-Bfyp0szs.b51553d29c8c.js.gz +0 -0
- codex/static_root/assets/VCombobox-Bfyp0szs.js +0 -1
- codex/static_root/assets/VCombobox-Bfyp0szs.js.br +0 -0
- codex/static_root/assets/VCombobox-Bfyp0szs.js.gz +0 -0
- codex/static_root/assets/VDialog-Cy6wFjb9.9253a3f54f22.js +0 -1
- codex/static_root/assets/VDialog-Cy6wFjb9.9253a3f54f22.js.br +0 -0
- codex/static_root/assets/VDialog-Cy6wFjb9.9253a3f54f22.js.gz +0 -0
- codex/static_root/assets/VDialog-Cy6wFjb9.js +0 -1
- codex/static_root/assets/VDialog-Cy6wFjb9.js.br +0 -0
- codex/static_root/assets/VDialog-Cy6wFjb9.js.gz +0 -0
- codex/static_root/assets/VDivider-BEpvozL4.c9fd95940cb5.js.br +0 -0
- codex/static_root/assets/VDivider-BEpvozL4.c9fd95940cb5.js.gz +0 -0
- codex/static_root/assets/VDivider-BEpvozL4.js.br +0 -0
- codex/static_root/assets/VDivider-BEpvozL4.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-BzyHQUL4.7e54cedf021c.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-BzyHQUL4.7e54cedf021c.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-BzyHQUL4.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-BzyHQUL4.js.gz +0 -0
- codex/static_root/assets/VForm-CmVlbmJK.887eb47d3534.js.br +0 -0
- codex/static_root/assets/VForm-CmVlbmJK.887eb47d3534.js.gz +0 -0
- codex/static_root/assets/VForm-CmVlbmJK.js.br +0 -0
- codex/static_root/assets/VForm-CmVlbmJK.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-DWzKkq9W.daaabd353889.js.br +0 -0
- codex/static_root/assets/VRadioGroup-DWzKkq9W.daaabd353889.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-DWzKkq9W.js.br +0 -0
- codex/static_root/assets/VRadioGroup-DWzKkq9W.js.gz +0 -0
- codex/static_root/assets/VSelect-Cqjdw0PV.ab01020c5ef4.js +0 -1
- codex/static_root/assets/VSelect-Cqjdw0PV.ab01020c5ef4.js.br +0 -0
- codex/static_root/assets/VSelect-Cqjdw0PV.ab01020c5ef4.js.gz +0 -0
- codex/static_root/assets/VSelect-Cqjdw0PV.js +0 -1
- codex/static_root/assets/VSelect-Cqjdw0PV.js.br +0 -0
- codex/static_root/assets/VSelect-Cqjdw0PV.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-Dk52iIPb.fe2504c50db4.js +0 -1
- codex/static_root/assets/VSelectionControl-Dk52iIPb.fe2504c50db4.js.br +0 -0
- codex/static_root/assets/VSelectionControl-Dk52iIPb.fe2504c50db4.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-Dk52iIPb.js +0 -1
- codex/static_root/assets/VSelectionControl-Dk52iIPb.js.br +0 -0
- codex/static_root/assets/VSelectionControl-Dk52iIPb.js.gz +0 -0
- codex/static_root/assets/VTable-CQyv0wyO.1740239d481b.css +0 -1
- codex/static_root/assets/VTable-CQyv0wyO.1740239d481b.css.br +0 -0
- codex/static_root/assets/VTable-CQyv0wyO.1740239d481b.css.gz +0 -0
- codex/static_root/assets/VTable-CQyv0wyO.css +0 -1
- codex/static_root/assets/VTable-CQyv0wyO.css.br +0 -0
- codex/static_root/assets/VTable-CQyv0wyO.css.gz +0 -0
- codex/static_root/assets/VTable-Ch5ZSNsk.c38a2cb589fa.js +0 -1
- codex/static_root/assets/VTable-Ch5ZSNsk.c38a2cb589fa.js.br +0 -0
- codex/static_root/assets/VTable-Ch5ZSNsk.c38a2cb589fa.js.gz +0 -0
- codex/static_root/assets/VTable-Ch5ZSNsk.js +0 -1
- codex/static_root/assets/VTable-Ch5ZSNsk.js.br +0 -0
- codex/static_root/assets/VTable-Ch5ZSNsk.js.gz +0 -0
- codex/static_root/assets/VWindowItem-ChYLiXSE.a9c679a2977e.css +0 -1
- codex/static_root/assets/VWindowItem-ChYLiXSE.a9c679a2977e.css.br +0 -0
- codex/static_root/assets/VWindowItem-ChYLiXSE.a9c679a2977e.css.gz +0 -0
- codex/static_root/assets/VWindowItem-ChYLiXSE.css +0 -1
- codex/static_root/assets/VWindowItem-ChYLiXSE.css.br +0 -0
- codex/static_root/assets/VWindowItem-ChYLiXSE.css.gz +0 -0
- codex/static_root/assets/VWindowItem-DBU8ce0X.4bbcffa75b9a.js.br +0 -0
- codex/static_root/assets/VWindowItem-DBU8ce0X.4bbcffa75b9a.js.gz +0 -0
- codex/static_root/assets/VWindowItem-DBU8ce0X.js.br +0 -0
- codex/static_root/assets/VWindowItem-DBU8ce0X.js.gz +0 -0
- codex/static_root/assets/admin-Bt81XU3H.ca36b1a1b799.js.br +0 -0
- codex/static_root/assets/admin-Bt81XU3H.ca36b1a1b799.js.gz +0 -0
- codex/static_root/assets/admin-Bt81XU3H.js.br +0 -0
- codex/static_root/assets/admin-Bt81XU3H.js.gz +0 -0
- codex/static_root/assets/admin-CfqMNEyt.bebc609836d0.js.br +0 -0
- codex/static_root/assets/admin-CfqMNEyt.bebc609836d0.js.gz +0 -0
- codex/static_root/assets/admin-CfqMNEyt.js.br +0 -0
- codex/static_root/assets/admin-CfqMNEyt.js.gz +0 -0
- codex/static_root/assets/admin-menu-Db5b3nba.09d034934b88.js +0 -1
- codex/static_root/assets/admin-menu-Db5b3nba.09d034934b88.js.br +0 -0
- codex/static_root/assets/admin-menu-Db5b3nba.09d034934b88.js.gz +0 -0
- codex/static_root/assets/admin-menu-Db5b3nba.js +0 -1
- codex/static_root/assets/admin-menu-Db5b3nba.js.br +0 -0
- codex/static_root/assets/admin-menu-Db5b3nba.js.gz +0 -0
- codex/static_root/assets/admin-settings-button-progress-BPQGNinn.53e05963f557.js.br +0 -0
- codex/static_root/assets/admin-settings-button-progress-BPQGNinn.53e05963f557.js.gz +0 -0
- codex/static_root/assets/admin-settings-button-progress-BPQGNinn.js.br +0 -0
- codex/static_root/assets/admin-settings-button-progress-BPQGNinn.js.gz +0 -0
- codex/static_root/assets/browser-C19hTg9r.9b5d0eadd6d4.js +0 -1
- codex/static_root/assets/browser-C19hTg9r.9b5d0eadd6d4.js.br +0 -0
- codex/static_root/assets/browser-C19hTg9r.9b5d0eadd6d4.js.gz +0 -0
- codex/static_root/assets/browser-C19hTg9r.js +0 -1
- codex/static_root/assets/browser-C19hTg9r.js.br +0 -0
- codex/static_root/assets/browser-C19hTg9r.js.gz +0 -0
- codex/static_root/assets/browser-Cdi7U5ku.bab9fccf0326.css.br +0 -0
- codex/static_root/assets/browser-Cdi7U5ku.bab9fccf0326.css.gz +0 -0
- codex/static_root/assets/browser-Cdi7U5ku.css.br +0 -0
- codex/static_root/assets/browser-Cdi7U5ku.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-DPAIPGJa.7c4c436e259e.js +0 -1
- codex/static_root/assets/change-password-dialog-DPAIPGJa.7c4c436e259e.js.br +0 -0
- codex/static_root/assets/change-password-dialog-DPAIPGJa.7c4c436e259e.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-DPAIPGJa.js +0 -1
- codex/static_root/assets/change-password-dialog-DPAIPGJa.js.br +0 -0
- codex/static_root/assets/change-password-dialog-DPAIPGJa.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-CgSU27R5.0127ce62d24c.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CgSU27R5.0127ce62d24c.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-CgSU27R5.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CgSU27R5.js.gz +0 -0
- codex/static_root/assets/datetime-column-Dw9zxZLR.cd8791cda91b.js.br +0 -0
- codex/static_root/assets/datetime-column-Dw9zxZLR.cd8791cda91b.js.gz +0 -0
- codex/static_root/assets/datetime-column-Dw9zxZLR.js.br +0 -0
- codex/static_root/assets/datetime-column-Dw9zxZLR.js.gz +0 -0
- codex/static_root/assets/filter-BNTCrH8l.c00298a8fccf.js.br +0 -0
- codex/static_root/assets/filter-BNTCrH8l.c00298a8fccf.js.gz +0 -0
- codex/static_root/assets/filter-BNTCrH8l.js.br +0 -0
- codex/static_root/assets/filter-BNTCrH8l.js.gz +0 -0
- codex/static_root/assets/flag-tab-Xpq_xAF5.3f14de61afcc.js.br +0 -0
- codex/static_root/assets/flag-tab-Xpq_xAF5.3f14de61afcc.js.gz +0 -0
- codex/static_root/assets/flag-tab-Xpq_xAF5.js.br +0 -0
- codex/static_root/assets/flag-tab-Xpq_xAF5.js.gz +0 -0
- codex/static_root/assets/forwardRefs-B_sUWZn6.5114f206ca9c.css.br +0 -0
- codex/static_root/assets/forwardRefs-B_sUWZn6.5114f206ca9c.css.gz +0 -0
- codex/static_root/assets/forwardRefs-B_sUWZn6.css.br +0 -0
- codex/static_root/assets/forwardRefs-B_sUWZn6.css.gz +0 -0
- codex/static_root/assets/forwardRefs-fUake9mW.12c1018cd1e3.js +0 -1
- codex/static_root/assets/forwardRefs-fUake9mW.12c1018cd1e3.js.br +0 -0
- codex/static_root/assets/forwardRefs-fUake9mW.12c1018cd1e3.js.gz +0 -0
- codex/static_root/assets/forwardRefs-fUake9mW.js +0 -1
- codex/static_root/assets/forwardRefs-fUake9mW.js.br +0 -0
- codex/static_root/assets/forwardRefs-fUake9mW.js.gz +0 -0
- codex/static_root/assets/group-tab-E_R0glEI.82e1d92be747.js.br +0 -0
- codex/static_root/assets/group-tab-E_R0glEI.82e1d92be747.js.gz +0 -0
- codex/static_root/assets/group-tab-E_R0glEI.js.br +0 -0
- codex/static_root/assets/group-tab-E_R0glEI.js.gz +0 -0
- codex/static_root/assets/http-error-C6bKTzfv.168d047d5219.js +0 -1
- codex/static_root/assets/http-error-C6bKTzfv.168d047d5219.js.br +0 -5
- codex/static_root/assets/http-error-C6bKTzfv.168d047d5219.js.gz +0 -0
- codex/static_root/assets/http-error-C6bKTzfv.js +0 -1
- codex/static_root/assets/http-error-C6bKTzfv.js.br +0 -5
- codex/static_root/assets/http-error-C6bKTzfv.js.gz +0 -0
- codex/static_root/assets/index-j9jeRHe0.294b614eaea1.js.br +0 -0
- codex/static_root/assets/index-j9jeRHe0.294b614eaea1.js.gz +0 -0
- codex/static_root/assets/index-j9jeRHe0.js.br +0 -0
- codex/static_root/assets/index-j9jeRHe0.js.gz +0 -0
- codex/static_root/assets/library-tab-DPYjRIWp.58e434354594.js +0 -1
- codex/static_root/assets/library-tab-DPYjRIWp.58e434354594.js.br +0 -0
- codex/static_root/assets/library-tab-DPYjRIWp.58e434354594.js.gz +0 -0
- codex/static_root/assets/library-tab-DPYjRIWp.js +0 -1
- codex/static_root/assets/library-tab-DPYjRIWp.js.br +0 -0
- codex/static_root/assets/library-tab-DPYjRIWp.js.gz +0 -0
- codex/static_root/assets/main-Cnq2ldv_.1c0766500281.js +0 -39
- codex/static_root/assets/main-Cnq2ldv_.1c0766500281.js.br +0 -0
- codex/static_root/assets/main-Cnq2ldv_.1c0766500281.js.gz +0 -0
- codex/static_root/assets/main-Cnq2ldv_.js +0 -39
- codex/static_root/assets/main-Cnq2ldv_.js.br +0 -0
- codex/static_root/assets/main-Cnq2ldv_.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-CdHAL6P3.cb6bc541ca5c.js +0 -1
- codex/static_root/assets/pager-full-pdf-CdHAL6P3.cb6bc541ca5c.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-CdHAL6P3.cb6bc541ca5c.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-CdHAL6P3.js +0 -1
- codex/static_root/assets/pager-full-pdf-CdHAL6P3.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-CdHAL6P3.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-741OafNw.4f9155469274.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-741OafNw.4f9155469274.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-741OafNw.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-741OafNw.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BFBKOWOc.3355103910ff.js +0 -1
- codex/static_root/assets/pagination-toolbar-BFBKOWOc.3355103910ff.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-BFBKOWOc.3355103910ff.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BFBKOWOc.js +0 -1
- codex/static_root/assets/pagination-toolbar-BFBKOWOc.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-BFBKOWOc.js.gz +0 -0
- codex/static_root/assets/pdf-doc-XAg2nqnS.5a33f918a28a.js.br +0 -0
- codex/static_root/assets/pdf-doc-XAg2nqnS.js.br +0 -0
- codex/static_root/assets/reader-BZ4Dp-_5.ecd9d42077af.js +0 -2
- codex/static_root/assets/reader-BZ4Dp-_5.ecd9d42077af.js.br +0 -0
- codex/static_root/assets/reader-BZ4Dp-_5.ecd9d42077af.js.gz +0 -0
- codex/static_root/assets/reader-BZ4Dp-_5.js +0 -2
- codex/static_root/assets/reader-BZ4Dp-_5.js.br +0 -0
- codex/static_root/assets/reader-BZ4Dp-_5.js.gz +0 -0
- codex/static_root/assets/relation-chips-B_z9ixOK.8f144f1cf119.js +0 -1
- codex/static_root/assets/relation-chips-B_z9ixOK.8f144f1cf119.js.br +0 -0
- codex/static_root/assets/relation-chips-B_z9ixOK.8f144f1cf119.js.gz +0 -0
- codex/static_root/assets/relation-chips-B_z9ixOK.js +0 -1
- codex/static_root/assets/relation-chips-B_z9ixOK.js.br +0 -0
- codex/static_root/assets/relation-chips-B_z9ixOK.js.gz +0 -0
- codex/static_root/assets/relation-chips-CcFgPQOM.0b468249b62e.css.br +0 -0
- codex/static_root/assets/relation-chips-CcFgPQOM.0b468249b62e.css.gz +0 -0
- codex/static_root/assets/relation-chips-CcFgPQOM.css.br +0 -0
- codex/static_root/assets/relation-chips-CcFgPQOM.css.gz +0 -0
- codex/static_root/assets/settings-drawer-Cd3M0s-h.c5216209feb4.js +0 -2
- codex/static_root/assets/settings-drawer-Cd3M0s-h.c5216209feb4.js.br +0 -0
- codex/static_root/assets/settings-drawer-Cd3M0s-h.c5216209feb4.js.gz +0 -0
- codex/static_root/assets/settings-drawer-Cd3M0s-h.js +0 -2
- codex/static_root/assets/settings-drawer-Cd3M0s-h.js.br +0 -0
- codex/static_root/assets/settings-drawer-Cd3M0s-h.js.gz +0 -0
- codex/static_root/assets/settings-drawer-CpS_aX4Z.9d4d9533d033.css.br +0 -0
- codex/static_root/assets/settings-drawer-CpS_aX4Z.9d4d9533d033.css.gz +0 -0
- codex/static_root/assets/settings-drawer-CpS_aX4Z.css.br +0 -0
- codex/static_root/assets/settings-drawer-CpS_aX4Z.css.gz +0 -0
- codex/static_root/assets/ssrBoot-CoIsTnhp.ab2c4669478d.js.br +0 -0
- codex/static_root/assets/ssrBoot-CoIsTnhp.ab2c4669478d.js.gz +0 -0
- codex/static_root/assets/ssrBoot-CoIsTnhp.js.br +0 -0
- codex/static_root/assets/ssrBoot-CoIsTnhp.js.gz +0 -0
- codex/static_root/assets/stats-tab-Bncgetpc.94f90b6a111b.js.br +0 -0
- codex/static_root/assets/stats-tab-Bncgetpc.94f90b6a111b.js.gz +0 -0
- codex/static_root/assets/stats-tab-Bncgetpc.js.br +0 -0
- codex/static_root/assets/stats-tab-Bncgetpc.js.gz +0 -0
- codex/static_root/assets/task-tab-BWkw24-u.0e981a767773.js +0 -1
- codex/static_root/assets/task-tab-BWkw24-u.0e981a767773.js.br +0 -0
- codex/static_root/assets/task-tab-BWkw24-u.0e981a767773.js.gz +0 -0
- codex/static_root/assets/task-tab-BWkw24-u.js +0 -1
- codex/static_root/assets/task-tab-BWkw24-u.js.br +0 -0
- codex/static_root/assets/task-tab-BWkw24-u.js.gz +0 -0
- codex/static_root/assets/unauthorized-IXAh-oLS.be484d21eb2a.js.br +0 -0
- codex/static_root/assets/unauthorized-IXAh-oLS.be484d21eb2a.js.gz +0 -0
- codex/static_root/assets/unauthorized-IXAh-oLS.js.br +0 -0
- codex/static_root/assets/unauthorized-IXAh-oLS.js.gz +0 -0
- codex/static_root/assets/user-tab-CtQh6PJE.6b9a1d0e733a.js +0 -1
- codex/static_root/assets/user-tab-CtQh6PJE.6b9a1d0e733a.js.br +0 -0
- codex/static_root/assets/user-tab-CtQh6PJE.6b9a1d0e733a.js.gz +0 -0
- codex/static_root/assets/user-tab-CtQh6PJE.js +0 -1
- codex/static_root/assets/user-tab-CtQh6PJE.js.br +0 -0
- codex/static_root/assets/user-tab-CtQh6PJE.js.gz +0 -0
- codex/static_root/manifest.92b1b461eee2.json.br +0 -0
- codex/static_root/manifest.92b1b461eee2.json.gz +0 -0
- /codex/librarian/{watchdog/memory.py → memory.py} +0 -0
- {codex-1.8.5.dist-info → codex-1.8.8.dist-info}/WHEEL +0 -0
- {codex-1.8.5.dist-info → codex-1.8.8.dist-info}/entry_points.txt +0 -0
- {codex-1.8.5.dist-info → codex-1.8.8.dist-info}/licenses/LICENSE +0 -0
codex/choices/admin.py
CHANGED
|
@@ -109,6 +109,7 @@ ADMIN_TASK_GROUPS: MappingProxyType[
|
|
|
109
109
|
"value": "search_index_clear",
|
|
110
110
|
"title": "Clear Search Index",
|
|
111
111
|
"desc": "of all entries",
|
|
112
|
+
"confirm": "Are you sure? Resyncing the search index can take a while.",
|
|
112
113
|
},
|
|
113
114
|
{
|
|
114
115
|
"value": "db_fts_integrity_check",
|
|
@@ -52,24 +52,29 @@ PARENT_FOLDER_FIELD_NAME = "parent_folder"
|
|
|
52
52
|
VOLUME_COUNT_FIELD_NAME = "volume_count"
|
|
53
53
|
ISSUE_COUNT_FIELD_NAME = "issue_count"
|
|
54
54
|
PATH_FIELD_NAME = "path"
|
|
55
|
+
IDENTIFIERS_FIELD_NAME = "identifiers"
|
|
55
56
|
NON_FTS_FIELDS = frozenset(
|
|
56
57
|
{
|
|
57
58
|
# Attributes
|
|
58
59
|
"critical_rating",
|
|
59
60
|
"day",
|
|
61
|
+
"file_type",
|
|
62
|
+
"issue_number",
|
|
63
|
+
"issue_suffix",
|
|
60
64
|
"metadata_mtime",
|
|
61
65
|
"monochrome",
|
|
62
66
|
"month",
|
|
67
|
+
"notes",
|
|
63
68
|
"page_count",
|
|
64
69
|
"path",
|
|
70
|
+
"reading_direction",
|
|
65
71
|
"year",
|
|
66
|
-
"issue_number",
|
|
67
|
-
"issue_suffix",
|
|
68
72
|
# FKs
|
|
69
73
|
PARENT_FOLDER_FIELD_NAME,
|
|
70
74
|
VOLUME_FIELD_NAME,
|
|
71
75
|
# M2Ms
|
|
72
76
|
FOLDERS_FIELD_NAME,
|
|
77
|
+
IDENTIFIERS_FIELD_NAME,
|
|
73
78
|
}
|
|
74
79
|
)
|
|
75
80
|
|
|
@@ -127,7 +132,6 @@ CREDIT_ROLE_FIELD_NAME = "role"
|
|
|
127
132
|
STORY_ARC_NUMBERS_FIELD_NAME = "story_arc_numbers"
|
|
128
133
|
STORY_ARC_FIELD_NAME = "story_arc"
|
|
129
134
|
NUMBER_FIELD_NAME = "number"
|
|
130
|
-
IDENTIFIERS_FIELD_NAME = "identifiers"
|
|
131
135
|
IDENTIFIER_SOURCE_FIELD_NAME = "source"
|
|
132
136
|
IDENTIFIER_TYPE_FIELD_NAME = "id_type"
|
|
133
137
|
IDENTIFIER_ID_KEY_FIELD_NAME = "key"
|
|
@@ -34,9 +34,6 @@ class CreateComicsImporter(CreateForeignKeyLinksImporter):
|
|
|
34
34
|
if field_name not in NON_FTS_FIELDS:
|
|
35
35
|
self.metadata[key][sub_key][field_name] = (value,)
|
|
36
36
|
|
|
37
|
-
issue = (str(md.get("issue_number", "")) + md.get("issue_suffix", ""),)
|
|
38
|
-
self.metadata[key][sub_key]["issue"] = issue
|
|
39
|
-
|
|
40
37
|
def _update_comic_values(self, comic: Comic, update_comics: list, comic_pks: list):
|
|
41
38
|
md = self.metadata[UPDATE_COMICS].pop(comic.pk, {})
|
|
42
39
|
for field_name, value in md.items():
|
|
@@ -4,7 +4,7 @@ from codex.librarian.scribe.importer.const import ALL_COMIC_GROUP_FIELD_NAMES
|
|
|
4
4
|
from codex.librarian.scribe.importer.delete.covers import DeletedCoversImporter
|
|
5
5
|
from codex.librarian.scribe.importer.statii.delete import ImporterRemoveComicsStatus
|
|
6
6
|
from codex.models import Comic, Folder, StoryArc
|
|
7
|
-
from codex.settings import
|
|
7
|
+
from codex.settings import DELETE_MAX_CHUNK_SIZE
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class DeletedComicsImporter(DeletedCoversImporter):
|
|
@@ -29,7 +29,7 @@ class DeletedComicsImporter(DeletedCoversImporter):
|
|
|
29
29
|
comics_deleted_qs = delete_qs.only(
|
|
30
30
|
*ALL_COMIC_GROUP_FIELD_NAMES
|
|
31
31
|
).prefetch_related("story_arc_numbers__story_arc")
|
|
32
|
-
for comic in comics_deleted_qs.iterator(chunk_size=
|
|
32
|
+
for comic in comics_deleted_qs.iterator(chunk_size=DELETE_MAX_CHUNK_SIZE):
|
|
33
33
|
for field_name in ALL_COMIC_GROUP_FIELD_NAMES:
|
|
34
34
|
if field_name == "story_arc_numbers":
|
|
35
35
|
for san in comic.story_arc_numbers.select_related("story_arc").only(
|
|
@@ -47,10 +47,12 @@ class DeletedComicsImporter(DeletedCoversImporter):
|
|
|
47
47
|
|
|
48
48
|
def bulk_comics_deleted(self, **kwargs) -> tuple[int, dict]:
|
|
49
49
|
"""Bulk delete comics found missing from the filesystem."""
|
|
50
|
+
count = 0
|
|
51
|
+
deleted_comic_groups = {}
|
|
50
52
|
status = ImporterRemoveComicsStatus(0, len(self.task.files_deleted))
|
|
51
53
|
try:
|
|
52
54
|
if not self.task.files_deleted:
|
|
53
|
-
return
|
|
55
|
+
return count, deleted_comic_groups
|
|
54
56
|
self.status_controller.start(status)
|
|
55
57
|
delete_qs = Comic.objects.filter(
|
|
56
58
|
library=self.library, path__in=self.task.files_deleted
|
|
@@ -60,7 +62,8 @@ class DeletedComicsImporter(DeletedCoversImporter):
|
|
|
60
62
|
deleted_comic_groups = self._populate_deleted_comic_groups(delete_qs)
|
|
61
63
|
|
|
62
64
|
delete_comic_pks = frozenset(delete_qs.values_list("pk", flat=True))
|
|
63
|
-
|
|
65
|
+
delete_qs.delete()
|
|
66
|
+
count = len(delete_comic_pks)
|
|
64
67
|
|
|
65
68
|
self.remove_covers(delete_comic_pks, custom=False)
|
|
66
69
|
finally:
|
|
@@ -25,7 +25,8 @@ class DeletedFoldersImporter(DeletedComicsImporter):
|
|
|
25
25
|
.distinct()
|
|
26
26
|
.values_list("pk", flat=True)
|
|
27
27
|
)
|
|
28
|
-
|
|
28
|
+
folders.delete()
|
|
29
|
+
count = len(delete_comic_pks)
|
|
29
30
|
|
|
30
31
|
self.remove_covers(delete_comic_pks, custom=False)
|
|
31
32
|
finally:
|
|
@@ -23,17 +23,56 @@ from codex.librarian.scribe.importer.statii.failed import (
|
|
|
23
23
|
)
|
|
24
24
|
from codex.librarian.scribe.importer.statii.read import ImporterAggregateStatus
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
_USED_COMICBOX_FIELDS = frozenset(
|
|
27
|
+
{
|
|
28
|
+
# "alternate_images",
|
|
29
|
+
"age_rating",
|
|
30
|
+
"arcs",
|
|
31
|
+
# "bookmark",
|
|
32
|
+
"characters",
|
|
33
|
+
"collection_title",
|
|
34
|
+
"country",
|
|
35
|
+
"credits",
|
|
36
|
+
# "credit_primaries",
|
|
37
|
+
"critical_rating",
|
|
38
|
+
"date",
|
|
39
|
+
# "ext",
|
|
40
|
+
"file_type", # extra
|
|
41
|
+
"genres",
|
|
42
|
+
"identifiers",
|
|
43
|
+
# "identifier_primary_source",
|
|
44
|
+
"imprint",
|
|
45
|
+
"issue",
|
|
46
|
+
"language",
|
|
47
|
+
"locations",
|
|
48
|
+
"metadata_mtime", # extra
|
|
49
|
+
"monochrome",
|
|
50
|
+
"notes",
|
|
51
|
+
"original_format",
|
|
52
|
+
"path", # extra
|
|
53
|
+
# "pages",
|
|
54
|
+
"page_count",
|
|
55
|
+
"protagonist",
|
|
56
|
+
# "prices",
|
|
57
|
+
"publisher",
|
|
58
|
+
"reading_direction",
|
|
59
|
+
# "remainders",
|
|
60
|
+
# "reprints",
|
|
61
|
+
"review",
|
|
62
|
+
# "rights",
|
|
63
|
+
"scan_info",
|
|
64
|
+
"series",
|
|
65
|
+
"series_groups",
|
|
66
|
+
"stories",
|
|
67
|
+
"summary",
|
|
68
|
+
"tagger",
|
|
69
|
+
"tags",
|
|
70
|
+
"teams",
|
|
71
|
+
"title",
|
|
72
|
+
"universes",
|
|
73
|
+
# "updated_at",
|
|
74
|
+
"volume",
|
|
75
|
+
}
|
|
37
76
|
)
|
|
38
77
|
|
|
39
78
|
|
|
@@ -42,8 +81,9 @@ class AggregateMetadataImporter(AggregatePathMetadataImporter):
|
|
|
42
81
|
|
|
43
82
|
@staticmethod
|
|
44
83
|
def _transform_metadata(md):
|
|
45
|
-
for key in
|
|
46
|
-
|
|
84
|
+
for key in tuple(md.keys()):
|
|
85
|
+
if key not in _USED_COMICBOX_FIELDS:
|
|
86
|
+
md.pop(key, None)
|
|
47
87
|
|
|
48
88
|
if date := md.pop(DATE_KEY, None):
|
|
49
89
|
date.pop(COVER_DATE_KEY, None)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Extract metadata from comic archive."""
|
|
2
2
|
|
|
3
|
-
from datetime import datetime
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
4
|
from tarfile import TarError
|
|
5
5
|
from zipfile import BadZipFile, LargeZipFile
|
|
6
6
|
|
|
@@ -29,7 +29,10 @@ class ExtractMetadataImporter(AggregateMetadataImporter):
|
|
|
29
29
|
comic = Comic.objects.get(path=path)
|
|
30
30
|
except Comic.DoesNotExist:
|
|
31
31
|
return None
|
|
32
|
-
|
|
32
|
+
mtime = comic.metadata_mtime
|
|
33
|
+
if mtime and (mtime.tzinfo is None or mtime.tzinfo.utcoffset(mtime) is None):
|
|
34
|
+
mtime = mtime.replace(tzinfo=timezone.utc)
|
|
35
|
+
return mtime
|
|
33
36
|
|
|
34
37
|
def _set_import_metadata_flag(self):
|
|
35
38
|
"""Set import_metadata flag."""
|
|
@@ -50,17 +53,17 @@ class ExtractMetadataImporter(AggregateMetadataImporter):
|
|
|
50
53
|
with Comicbox(path, config=COMICBOX_CONFIG, logger=self.log) as cb:
|
|
51
54
|
if import_metadata:
|
|
52
55
|
new_md_mtime = cb.get_metadata_mtime()
|
|
53
|
-
if
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
if (
|
|
57
|
+
not self.task.check_metadata_mtime
|
|
58
|
+
or not new_md_mtime
|
|
59
|
+
or not (old_md_mtime := self._metadata_mtime(path))
|
|
60
|
+
or (new_md_mtime > old_md_mtime)
|
|
61
|
+
):
|
|
62
|
+
md = cb.to_dict()
|
|
63
|
+
md = md.get("comicbox", {})
|
|
64
|
+
md["metadata_mtime"] = new_md_mtime
|
|
65
|
+
else:
|
|
66
|
+
md["page_count"] = cb.get_page_count()
|
|
64
67
|
else:
|
|
65
68
|
md["page_count"] = cb.get_page_count()
|
|
66
69
|
md["file_type"] = cb.get_file_type()
|
|
@@ -6,7 +6,6 @@ from codex.librarian.scribe.importer.const import (
|
|
|
6
6
|
FTS_CREATED_M2MS,
|
|
7
7
|
FTS_EXISTING_M2MS,
|
|
8
8
|
FTS_UPDATE,
|
|
9
|
-
IDENTIFIERS_FIELD_NAME,
|
|
10
9
|
NON_FTS_FIELDS,
|
|
11
10
|
STORY_ARC_FIELD_NAME,
|
|
12
11
|
STORY_ARC_NUMBERS_FIELD_NAME,
|
|
@@ -25,8 +24,6 @@ class SearchIndexPrepareImporter(SearchIndexCreateUpdateImporter):
|
|
|
25
24
|
"""Only store the fts relevant parts of complex links."""
|
|
26
25
|
if field_name == CREDITS_FIELD_NAME:
|
|
27
26
|
values = tuple(subvalues[0] for subvalues in values)
|
|
28
|
-
if field_name == IDENTIFIERS_FIELD_NAME:
|
|
29
|
-
values = tuple(subvalues[-1] for subvalues in values)
|
|
30
27
|
elif field_name == STORY_ARC_NUMBERS_FIELD_NAME:
|
|
31
28
|
field_name = STORY_ARC_FIELD_NAME + "s"
|
|
32
29
|
return field_name, tuple(values)
|
|
@@ -41,10 +38,6 @@ class SearchIndexPrepareImporter(SearchIndexCreateUpdateImporter):
|
|
|
41
38
|
"""Add the existing values for creating a changed search entry."""
|
|
42
39
|
if field_name in NON_FTS_FIELDS or not values:
|
|
43
40
|
return
|
|
44
|
-
if field_name == IDENTIFIERS_FIELD_NAME:
|
|
45
|
-
# sources extracton must come before identifiers is minified
|
|
46
|
-
sources = tuple(subvalues[0] for subvalues in values)
|
|
47
|
-
self.add_to_fts_existing(pk, "sources", sources)
|
|
48
41
|
field_name, values = self.minify_complex_link_to_fts_tuple(field_name, values)
|
|
49
42
|
fts_values = self._to_fts_tuple(values)
|
|
50
43
|
if not fts_values:
|
|
@@ -52,7 +52,8 @@ class SearchIndexSyncManyToManyImporter(FinishImporter):
|
|
|
52
52
|
.only(*update_fields)
|
|
53
53
|
)
|
|
54
54
|
for comicfts in comicftss:
|
|
55
|
-
|
|
55
|
+
value = comicfts.fts_value.strip(",") # pyright: ignore[reportAttributeAccessIssue]
|
|
56
|
+
setattr(comicfts, field_name, value)
|
|
56
57
|
comicfts.updated_at = Now()
|
|
57
58
|
update_objs.append(comicfts)
|
|
58
59
|
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
"""Search Index update."""
|
|
2
2
|
|
|
3
|
-
from contextlib import suppress
|
|
4
3
|
from time import time
|
|
5
4
|
|
|
6
|
-
from comicbox.enums.comicbox import IdSources
|
|
7
|
-
from comicbox.enums.maps.identifiers import ID_SOURCE_NAME_MAP
|
|
8
|
-
from django.db.models.functions.datetime import Now
|
|
9
5
|
from humanize import naturaldelta
|
|
10
6
|
|
|
11
7
|
from codex.librarian.scribe.importer.const import (
|
|
@@ -13,10 +9,6 @@ from codex.librarian.scribe.importer.const import (
|
|
|
13
9
|
FTS_EXISTING_M2MS,
|
|
14
10
|
FTS_UPDATE,
|
|
15
11
|
)
|
|
16
|
-
from codex.librarian.scribe.importer.search.const import (
|
|
17
|
-
COMICFTS_UPDATE_FIELDS,
|
|
18
|
-
PYCOUNTRY_FIELDS,
|
|
19
|
-
)
|
|
20
12
|
from codex.librarian.scribe.importer.search.sync_m2m import (
|
|
21
13
|
SearchIndexSyncManyToManyImporter,
|
|
22
14
|
)
|
|
@@ -25,6 +17,8 @@ from codex.librarian.scribe.importer.statii.search import (
|
|
|
25
17
|
ImporterFTSStatus,
|
|
26
18
|
ImporterFTSUpdateStatus,
|
|
27
19
|
)
|
|
20
|
+
from codex.librarian.scribe.search.const import COMICFTS_UPDATE_FIELDS
|
|
21
|
+
from codex.librarian.scribe.search.prepare import SearchEntryPrepare
|
|
28
22
|
from codex.librarian.status import Status
|
|
29
23
|
from codex.models.comic import ComicFTS
|
|
30
24
|
|
|
@@ -32,73 +26,17 @@ from codex.models.comic import ComicFTS
|
|
|
32
26
|
class SearchIndexCreateUpdateImporter(SearchIndexSyncManyToManyImporter):
|
|
33
27
|
"""Search Index update methods."""
|
|
34
28
|
|
|
35
|
-
@staticmethod
|
|
36
|
-
def _get_pycountry_fts_field(entry, field_name) -> str:
|
|
37
|
-
iso_code = entry.get(field_name)
|
|
38
|
-
if not iso_code:
|
|
39
|
-
return ""
|
|
40
|
-
field = PYCOUNTRY_FIELDS[field_name]
|
|
41
|
-
return ",".join((iso_code, field.to_representation(iso_code)))
|
|
42
|
-
|
|
43
|
-
@staticmethod
|
|
44
|
-
def _get_sources_fts_field(entry) -> tuple[str, ...]:
|
|
45
|
-
sources = entry.get("sources", ())
|
|
46
|
-
names = []
|
|
47
|
-
for source_str in sources:
|
|
48
|
-
names.append(source_str)
|
|
49
|
-
with suppress(ValueError):
|
|
50
|
-
id_source = IdSources(source_str)
|
|
51
|
-
if long_name := ID_SOURCE_NAME_MAP.get(id_source):
|
|
52
|
-
names.append(long_name)
|
|
53
|
-
return tuple(names)
|
|
54
|
-
|
|
55
|
-
@staticmethod
|
|
56
|
-
def _create_comicfts_entry_attributes(entry, *, create: bool):
|
|
57
|
-
now = Now()
|
|
58
|
-
entry["updated_at"] = now
|
|
59
|
-
if create:
|
|
60
|
-
entry["created_at"] = now
|
|
61
|
-
|
|
62
|
-
@classmethod
|
|
63
|
-
def _create_comicfts_entry_fks(cls, entry):
|
|
64
|
-
entry["country"] = cls._get_pycountry_fts_field(entry, "country")
|
|
65
|
-
entry["language"] = cls._get_pycountry_fts_field(entry, "language")
|
|
66
|
-
|
|
67
|
-
@staticmethod
|
|
68
|
-
def _to_fts_values(value):
|
|
69
|
-
"""Create a tuple of fts value strings."""
|
|
70
|
-
return tuple(
|
|
71
|
-
subvalue
|
|
72
|
-
for values_tuple in value
|
|
73
|
-
for subvalue in values_tuple
|
|
74
|
-
if isinstance(subvalue, str)
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
def _create_comicfts_entry_m2ms(self, pk: int, entry):
|
|
78
|
-
if sources := self._get_sources_fts_field(entry):
|
|
79
|
-
entry["sources"] = sources
|
|
80
|
-
if existing_values := self.metadata[FTS_EXISTING_M2MS].get(pk):
|
|
81
|
-
for field_name in tuple(existing_values.keys()):
|
|
82
|
-
if values := existing_values.get(field_name):
|
|
83
|
-
entry[field_name] = entry.get(field_name, ()) + values
|
|
84
|
-
|
|
85
29
|
def _create_comicfts_entry(
|
|
86
30
|
self,
|
|
87
|
-
pk,
|
|
88
|
-
entry,
|
|
31
|
+
pk: int,
|
|
32
|
+
entry: dict,
|
|
89
33
|
obj_list: list[ComicFTS],
|
|
90
34
|
status: Status,
|
|
91
35
|
):
|
|
92
|
-
self.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
entry[field_name] = ",".join(sorted(value))
|
|
97
|
-
self._create_comicfts_entry_attributes(entry, create=True)
|
|
98
|
-
self._create_comicfts_entry_fks(entry)
|
|
99
|
-
comicfts = ComicFTS(comic_id=pk, **entry)
|
|
100
|
-
obj_list.append(comicfts)
|
|
101
|
-
status.increment_complete()
|
|
36
|
+
existing_m2m_values = self.metadata[FTS_EXISTING_M2MS].get(pk)
|
|
37
|
+
SearchEntryPrepare.prepare_import_fts_entry(
|
|
38
|
+
pk, entry, existing_m2m_values, None, obj_list, status, create=True
|
|
39
|
+
)
|
|
102
40
|
self.status_controller.update(status)
|
|
103
41
|
|
|
104
42
|
def _update_comicfts_entry(
|
|
@@ -109,17 +47,16 @@ class SearchIndexCreateUpdateImporter(SearchIndexSyncManyToManyImporter):
|
|
|
109
47
|
):
|
|
110
48
|
comic_id = comicfts.comic_id # pyright:ignore[reportAttributeAccessIssue], # ty: ignore[unresolved-attribute]
|
|
111
49
|
entry = self.metadata[FTS_UPDATE].pop(comic_id)
|
|
112
|
-
self.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
status.increment_complete()
|
|
50
|
+
existing_m2m_values = self.metadata[FTS_EXISTING_M2MS].get(comic_id)
|
|
51
|
+
SearchEntryPrepare.prepare_import_fts_entry(
|
|
52
|
+
comic_id,
|
|
53
|
+
entry,
|
|
54
|
+
existing_m2m_values,
|
|
55
|
+
comicfts,
|
|
56
|
+
obj_list,
|
|
57
|
+
status,
|
|
58
|
+
create=False,
|
|
59
|
+
)
|
|
123
60
|
self.status_controller.update(status)
|
|
124
61
|
|
|
125
62
|
def _update_search_index_operate_get_status(
|
|
@@ -29,23 +29,12 @@ from codex.librarian.scribe.tasks import (
|
|
|
29
29
|
)
|
|
30
30
|
from codex.librarian.scribe.timestamp_update import TimestampUpdater
|
|
31
31
|
from codex.librarian.threads import QueuedThread
|
|
32
|
-
from codex.settings import SEARCH_INDEX_BATCH_SIZE
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
ABORT_SEARCH_UPDATE_TASKS = (
|
|
35
34
|
SearchIndexClearTask,
|
|
36
35
|
SearchIndexSyncAbortTask,
|
|
37
36
|
JanitorFTSRebuildTask,
|
|
38
37
|
)
|
|
39
|
-
_ABORT_SEARCH_UPDATE_ON_IMPORT_TASKS = (
|
|
40
|
-
ImportTask,
|
|
41
|
-
JanitorAdoptOrphanFoldersTask,
|
|
42
|
-
)
|
|
43
|
-
_ABORT_SEARCH_UPDATE_ON_IMPORT_BATCH_SIZE = 1000
|
|
44
|
-
ABORT_SEARCH_UPDATE_TASKS = (
|
|
45
|
-
_ABORT_SEARCH_UPDATE_TASKS + _ABORT_SEARCH_UPDATE_ON_IMPORT_TASKS
|
|
46
|
-
if SEARCH_INDEX_BATCH_SIZE <= _ABORT_SEARCH_UPDATE_ON_IMPORT_BATCH_SIZE
|
|
47
|
-
else _ABORT_SEARCH_UPDATE_TASKS
|
|
48
|
-
)
|
|
49
38
|
|
|
50
39
|
|
|
51
40
|
class ScribeThread(QueuedThread):
|
|
@@ -118,7 +107,7 @@ class ScribeThread(QueuedThread):
|
|
|
118
107
|
self.log.debug("Abort cleanup db signal given.")
|
|
119
108
|
elif isinstance(task, SearchIndexSyncAbortTask):
|
|
120
109
|
self.log.debug(
|
|
121
|
-
"Search Index
|
|
110
|
+
"Search Index Sync abort signal given. It may take a while for the current import chunk to finish."
|
|
122
111
|
)
|
|
123
112
|
return
|
|
124
113
|
elif isinstance(task, ImportAbortTask):
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
from types import MappingProxyType
|
|
4
|
-
|
|
5
|
-
from codex.serializers.fields.browser import CountryField, LanguageField
|
|
1
|
+
"""FTS constants."""
|
|
6
2
|
|
|
7
3
|
_COMICFTS_ATTRIBUTES = (
|
|
8
4
|
"collection_title",
|
|
9
|
-
"file_type",
|
|
10
|
-
"issue",
|
|
11
5
|
"name",
|
|
12
|
-
"notes",
|
|
13
|
-
"reading_direction",
|
|
14
6
|
"review",
|
|
15
7
|
"summary",
|
|
16
8
|
"updated_at",
|
|
@@ -30,7 +22,6 @@ _COMICFTS_M2MS = (
|
|
|
30
22
|
"characters",
|
|
31
23
|
"credits",
|
|
32
24
|
"genres",
|
|
33
|
-
"identifiers",
|
|
34
25
|
"locations",
|
|
35
26
|
"series_groups",
|
|
36
27
|
"sources",
|
|
@@ -45,6 +36,3 @@ COMICFTS_UPDATE_FIELDS = (
|
|
|
45
36
|
*_COMICFTS_FKS,
|
|
46
37
|
*_COMICFTS_M2MS,
|
|
47
38
|
)
|
|
48
|
-
PYCOUNTRY_FIELDS = MappingProxyType(
|
|
49
|
-
{"country": CountryField(), "language": LanguageField()}
|
|
50
|
-
)
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""Prepare ComicFTS objects."""
|
|
2
|
+
|
|
3
|
+
from contextlib import suppress
|
|
4
|
+
from types import MappingProxyType
|
|
5
|
+
|
|
6
|
+
from comicbox.enums.comicbox import IdSources
|
|
7
|
+
from comicbox.enums.maps.identifiers import ID_SOURCE_NAME_MAP
|
|
8
|
+
from django.db.models.functions.datetime import Now
|
|
9
|
+
|
|
10
|
+
from codex.librarian.status import Status
|
|
11
|
+
from codex.models.comic import ComicFTS
|
|
12
|
+
from codex.serializers.fields.browser import CountryField, LanguageField
|
|
13
|
+
|
|
14
|
+
_PYCOUNTRY_FIELDS = MappingProxyType(
|
|
15
|
+
{"country": CountryField(), "language": LanguageField()}
|
|
16
|
+
)
|
|
17
|
+
_COMIC_KEYS = (
|
|
18
|
+
"collection_title",
|
|
19
|
+
"country",
|
|
20
|
+
"language",
|
|
21
|
+
"name",
|
|
22
|
+
"review",
|
|
23
|
+
"summary",
|
|
24
|
+
"fts_publisher",
|
|
25
|
+
"fts_imprint",
|
|
26
|
+
"fts_series",
|
|
27
|
+
"fts_age_rating",
|
|
28
|
+
"fts_original_format",
|
|
29
|
+
"fts_scan_info",
|
|
30
|
+
"fts_tagger",
|
|
31
|
+
"fts_characters",
|
|
32
|
+
"fts_credits",
|
|
33
|
+
"fts_country",
|
|
34
|
+
"fts_genres",
|
|
35
|
+
"fts_sources",
|
|
36
|
+
"fts_language",
|
|
37
|
+
"fts_locations",
|
|
38
|
+
"fts_series_groups",
|
|
39
|
+
"fts_stories",
|
|
40
|
+
"fts_story_arcs",
|
|
41
|
+
"fts_tags",
|
|
42
|
+
"fts_teams",
|
|
43
|
+
"fts_universes",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class SearchEntryPrepare:
|
|
48
|
+
"""Prepare ComicFTS objects."""
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def _get_entry_str_value(entry: dict, key: str) -> str:
|
|
52
|
+
value = entry.get(key)
|
|
53
|
+
if not value:
|
|
54
|
+
return ""
|
|
55
|
+
if isinstance(value, tuple):
|
|
56
|
+
value = value[0]
|
|
57
|
+
if not value:
|
|
58
|
+
return ""
|
|
59
|
+
return value
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def _get_sources_fts_field(entry: dict) -> str:
|
|
63
|
+
sources = entry.get("sources", ())
|
|
64
|
+
if not sources:
|
|
65
|
+
return ""
|
|
66
|
+
if isinstance(sources, str):
|
|
67
|
+
sources = (sources,)
|
|
68
|
+
names = set()
|
|
69
|
+
for source_str in sources:
|
|
70
|
+
if not source_str:
|
|
71
|
+
continue
|
|
72
|
+
names.add(source_str)
|
|
73
|
+
with suppress(ValueError):
|
|
74
|
+
id_source = IdSources(source_str)
|
|
75
|
+
if long_name := ID_SOURCE_NAME_MAP.get(id_source):
|
|
76
|
+
names.add(long_name)
|
|
77
|
+
return ",".join(sorted(names))
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def _get_pycountry_fts_field(cls, entry, field_name) -> str:
|
|
81
|
+
iso_code = cls._get_entry_str_value(entry, field_name)
|
|
82
|
+
if not iso_code:
|
|
83
|
+
return ""
|
|
84
|
+
field = _PYCOUNTRY_FIELDS[field_name]
|
|
85
|
+
return ",".join((iso_code, field.to_representation(iso_code)))
|
|
86
|
+
|
|
87
|
+
@classmethod
|
|
88
|
+
def _create_comicfts_entry_attributes(cls, entry, *, create: bool):
|
|
89
|
+
now = Now()
|
|
90
|
+
entry["updated_at"] = now
|
|
91
|
+
if create:
|
|
92
|
+
entry["created_at"] = now
|
|
93
|
+
|
|
94
|
+
@classmethod
|
|
95
|
+
def _create_comicfts_entry_fks(cls, entry):
|
|
96
|
+
entry["country"] = cls._get_pycountry_fts_field(entry, "country")
|
|
97
|
+
entry["language"] = cls._get_pycountry_fts_field(entry, "language")
|
|
98
|
+
|
|
99
|
+
@classmethod
|
|
100
|
+
def _create_comicfts_entry_m2ms(cls, entry, existing_values: dict | None):
|
|
101
|
+
if sources := cls._get_sources_fts_field(entry):
|
|
102
|
+
entry["sources"] = sources
|
|
103
|
+
if existing_values:
|
|
104
|
+
for field_name in tuple(existing_values.keys()):
|
|
105
|
+
if values := existing_values.get(field_name):
|
|
106
|
+
entry[field_name] = entry.get(field_name, ()) + values
|
|
107
|
+
|
|
108
|
+
@classmethod
|
|
109
|
+
def prepare_import_fts_entry( # noqa: PLR0913
|
|
110
|
+
cls,
|
|
111
|
+
comic_id: int,
|
|
112
|
+
entry: dict,
|
|
113
|
+
existing_m2m_values: dict | None,
|
|
114
|
+
comicfts: ComicFTS | None,
|
|
115
|
+
obj_list: list[ComicFTS],
|
|
116
|
+
status: Status,
|
|
117
|
+
*,
|
|
118
|
+
create: bool,
|
|
119
|
+
):
|
|
120
|
+
"""Prepare ComicFTS object from import data."""
|
|
121
|
+
cls._create_comicfts_entry_m2ms(entry, existing_m2m_values)
|
|
122
|
+
cls._create_comicfts_entry_fks(entry)
|
|
123
|
+
for field_name in entry: # noqa: PLC0206
|
|
124
|
+
value = entry[field_name]
|
|
125
|
+
if isinstance(value, tuple):
|
|
126
|
+
entry[field_name] = ",".join(sorted(value))
|
|
127
|
+
|
|
128
|
+
cls._create_comicfts_entry_attributes(entry, create=create)
|
|
129
|
+
|
|
130
|
+
if comicfts:
|
|
131
|
+
for field_name, value in entry.items():
|
|
132
|
+
setattr(comicfts, field_name, value)
|
|
133
|
+
else:
|
|
134
|
+
entry["comic_id"] = comic_id
|
|
135
|
+
comicfts = ComicFTS(**entry)
|
|
136
|
+
|
|
137
|
+
obj_list.append(comicfts)
|
|
138
|
+
status.increment_complete()
|
|
139
|
+
|
|
140
|
+
@classmethod
|
|
141
|
+
def prepare_sync_fts_entry(
|
|
142
|
+
cls,
|
|
143
|
+
comic: dict,
|
|
144
|
+
obj_list: list[ComicFTS],
|
|
145
|
+
*,
|
|
146
|
+
create: bool,
|
|
147
|
+
):
|
|
148
|
+
"""Prepare ComicFTS object from sync query data."""
|
|
149
|
+
entry = {
|
|
150
|
+
key.removeprefix("fts_"): comic.get(key, "")
|
|
151
|
+
for key in _COMIC_KEYS
|
|
152
|
+
if comic.get(key)
|
|
153
|
+
}
|
|
154
|
+
if sources := cls._get_sources_fts_field(entry):
|
|
155
|
+
entry["sources"] = sources
|
|
156
|
+
cls._create_comicfts_entry_fks(entry)
|
|
157
|
+
entry["universes"] = entry["universes"].strip(",")
|
|
158
|
+
cls._create_comicfts_entry_attributes(entry, create=create)
|
|
159
|
+
entry["comic_id"] = comic["id"]
|
|
160
|
+
|
|
161
|
+
comicfts: ComicFTS = ComicFTS(**entry)
|
|
162
|
+
obj_list.append(comicfts)
|