codex 1.6.9a0__py3-none-any.whl → 1.6.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of codex might be problematic. Click here for more details.
- codex/librarian/cron/crond.py +10 -13
- codex/librarian/importer/importerd.py +19 -24
- codex/librarian/importer/moved.py +73 -176
- codex/librarian/importer/query_fks.py +11 -17
- codex/librarian/janitor/janitor.py +4 -12
- codex/librarian/janitor/status.py +0 -1
- codex/librarian/janitor/tasks.py +7 -14
- codex/librarian/janitor/update.py +2 -21
- codex/librarian/janitor/vacuum.py +2 -1
- codex/librarian/telemeter/stats.py +16 -20
- codex/librarian/telemeter/telemeter.py +7 -10
- codex/librarian/watchdog/dir_snapshot_diff.py +17 -19
- codex/librarian/watchdog/emitter.py +14 -12
- codex/librarian/watchdog/events.py +1 -1
- codex/librarian/watchdog/observers.py +4 -4
- codex/search/backend.py +2 -9
- codex/serializers/browser/mixins.py +2 -1
- codex/settings/settings.py +1 -5
- codex/signals/django_signals.py +9 -0
- codex/startup.py +3 -1
- codex/static_root/assets/VCheckbox-BoSq-Gp8.45ea578c17b0.js +1 -0
- codex/static_root/assets/VCheckbox-BoSq-Gp8.45ea578c17b0.js.br +0 -0
- codex/static_root/assets/VCheckbox-BoSq-Gp8.45ea578c17b0.js.gz +0 -0
- codex/static_root/assets/VCheckbox-BoSq-Gp8.js +1 -0
- codex/static_root/assets/VCheckbox-BoSq-Gp8.js.br +0 -0
- codex/static_root/assets/VCheckbox-BoSq-Gp8.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-k69hHqz6.a5c3131a12bf.js +1 -0
- codex/static_root/assets/VCheckboxBtn-k69hHqz6.a5c3131a12bf.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-k69hHqz6.a5c3131a12bf.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-k69hHqz6.js +1 -0
- codex/static_root/assets/VCheckboxBtn-k69hHqz6.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-k69hHqz6.js.gz +0 -0
- codex/static_root/assets/VCombobox-BksEr4D_.73429bb75f42.css +1 -0
- codex/static_root/assets/VCombobox-BksEr4D_.73429bb75f42.css.br +0 -0
- codex/static_root/assets/VCombobox-BksEr4D_.73429bb75f42.css.gz +0 -0
- codex/static_root/assets/VCombobox-BksEr4D_.css +1 -0
- codex/static_root/assets/VCombobox-BksEr4D_.css.br +0 -0
- codex/static_root/assets/VCombobox-BksEr4D_.css.gz +0 -0
- codex/static_root/assets/VCombobox-CLEC9nAk.3ed4e3a0cb6e.js +1 -0
- codex/static_root/assets/VCombobox-CLEC9nAk.3ed4e3a0cb6e.js.br +0 -0
- codex/static_root/assets/VCombobox-CLEC9nAk.3ed4e3a0cb6e.js.gz +0 -0
- codex/static_root/assets/VCombobox-CLEC9nAk.js +1 -0
- codex/static_root/assets/VCombobox-CLEC9nAk.js.br +0 -0
- codex/static_root/assets/VCombobox-CLEC9nAk.js.gz +0 -0
- codex/static_root/assets/VDialog-Dir_-l5o.5de2881bebcc.js +1 -0
- codex/static_root/assets/VDialog-Dir_-l5o.5de2881bebcc.js.br +0 -0
- codex/static_root/assets/VDialog-Dir_-l5o.5de2881bebcc.js.gz +0 -0
- codex/static_root/assets/VDialog-Dir_-l5o.js +1 -0
- codex/static_root/assets/VDialog-Dir_-l5o.js.br +0 -0
- codex/static_root/assets/VDialog-Dir_-l5o.js.gz +0 -0
- codex/static_root/assets/VDialog-lQ13FnRR.1c801ad756b2.css +1 -0
- codex/static_root/assets/VDialog-lQ13FnRR.1c801ad756b2.css.br +0 -0
- codex/static_root/assets/VDialog-lQ13FnRR.1c801ad756b2.css.gz +0 -0
- codex/static_root/assets/VDialog-lQ13FnRR.css +1 -0
- codex/static_root/assets/VDialog-lQ13FnRR.css.br +0 -0
- codex/static_root/assets/VDialog-lQ13FnRR.css.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DSywtH47.8bff92b5b38b.js +1 -0
- codex/static_root/assets/VExpansionPanels-DSywtH47.8bff92b5b38b.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-DSywtH47.8bff92b5b38b.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DSywtH47.js +1 -0
- codex/static_root/assets/VExpansionPanels-DSywtH47.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-DSywtH47.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DsEXVcCv.20b475255e66.css +1 -0
- codex/static_root/assets/VExpansionPanels-DsEXVcCv.20b475255e66.css.br +0 -0
- codex/static_root/assets/VExpansionPanels-DsEXVcCv.20b475255e66.css.gz +0 -0
- codex/static_root/assets/VExpansionPanels-DsEXVcCv.css +1 -0
- codex/static_root/assets/VExpansionPanels-DsEXVcCv.css.br +0 -0
- codex/static_root/assets/VExpansionPanels-DsEXVcCv.css.gz +0 -0
- codex/static_root/assets/VRadioGroup-BwpxWbvH.1e52b683c2bf.js +1 -0
- codex/static_root/assets/VRadioGroup-BwpxWbvH.1e52b683c2bf.js.br +0 -0
- codex/static_root/assets/VRadioGroup-BwpxWbvH.1e52b683c2bf.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-BwpxWbvH.js +1 -0
- codex/static_root/assets/VRadioGroup-BwpxWbvH.js.br +0 -0
- codex/static_root/assets/VRadioGroup-BwpxWbvH.js.gz +0 -0
- codex/static_root/assets/VSelect-ARDhJiQK.372c098fb475.css +1 -0
- codex/static_root/assets/VSelect-ARDhJiQK.372c098fb475.css.br +0 -0
- codex/static_root/assets/VSelect-ARDhJiQK.372c098fb475.css.gz +0 -0
- codex/static_root/assets/VSelect-ARDhJiQK.css +1 -0
- codex/static_root/assets/VSelect-ARDhJiQK.css.br +0 -0
- codex/static_root/assets/VSelect-ARDhJiQK.css.gz +0 -0
- codex/static_root/assets/VSelect-cGleKlm7.82f880fcf439.js +1 -0
- codex/static_root/assets/VSelect-cGleKlm7.82f880fcf439.js.br +0 -0
- codex/static_root/assets/VSelect-cGleKlm7.82f880fcf439.js.gz +0 -0
- codex/static_root/assets/VSelect-cGleKlm7.js +1 -0
- codex/static_root/assets/VSelect-cGleKlm7.js.br +0 -0
- codex/static_root/assets/VSelect-cGleKlm7.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-CiViEYoC.c77bb19a4a06.css → VSelectionControl-BFq--28I.9687c77461fc.css} +1 -1
- codex/static_root/assets/VSelectionControl-BFq--28I.9687c77461fc.css.br +0 -0
- codex/static_root/assets/VSelectionControl-BFq--28I.9687c77461fc.css.gz +0 -0
- codex/static_root/assets/{VSelectionControl-CiViEYoC.css → VSelectionControl-BFq--28I.css} +1 -1
- codex/static_root/assets/VSelectionControl-BFq--28I.css.br +0 -0
- codex/static_root/assets/VSelectionControl-BFq--28I.css.gz +0 -0
- codex/static_root/assets/VSelectionControl-_6sv90xF.74f88fc610a2.js +1 -0
- codex/static_root/assets/VSelectionControl-_6sv90xF.74f88fc610a2.js.br +0 -0
- codex/static_root/assets/VSelectionControl-_6sv90xF.74f88fc610a2.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-_6sv90xF.js +1 -0
- codex/static_root/assets/VSelectionControl-_6sv90xF.js.br +0 -0
- codex/static_root/assets/VSelectionControl-_6sv90xF.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-P_U-rmf2.ca3efe698702.js → VSlideGroup-DbQOqyzs.183374da65d9.js} +1 -1
- codex/static_root/assets/VSlideGroup-DbQOqyzs.183374da65d9.js.br +0 -0
- codex/static_root/assets/VSlideGroup-DbQOqyzs.183374da65d9.js.gz +0 -0
- codex/static_root/assets/{VSlideGroup-P_U-rmf2.js → VSlideGroup-DbQOqyzs.js} +1 -1
- codex/static_root/assets/VSlideGroup-DbQOqyzs.js.br +0 -0
- codex/static_root/assets/VSlideGroup-DbQOqyzs.js.gz +0 -0
- codex/static_root/assets/{VTable-Coq-QwtQ.2b04104cbf05.js → VTable-CF4zd2t_.3ade1377ce12.js} +1 -1
- codex/static_root/assets/VTable-CF4zd2t_.3ade1377ce12.js.br +0 -0
- codex/static_root/assets/VTable-CF4zd2t_.3ade1377ce12.js.gz +0 -0
- codex/static_root/assets/{VTable-Coq-QwtQ.js → VTable-CF4zd2t_.js} +1 -1
- codex/static_root/assets/VTable-CF4zd2t_.js.br +0 -0
- codex/static_root/assets/VTable-CF4zd2t_.js.gz +0 -0
- codex/static_root/assets/VTable-DflzroDq.160504d82195.css +1 -0
- codex/static_root/assets/VTable-DflzroDq.160504d82195.css.br +0 -0
- codex/static_root/assets/VTable-DflzroDq.160504d82195.css.gz +0 -0
- codex/static_root/assets/VTable-DflzroDq.css +1 -0
- codex/static_root/assets/VTable-DflzroDq.css.br +0 -0
- codex/static_root/assets/VTable-DflzroDq.css.gz +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.4cc388b4aa3c.css +1 -0
- codex/static_root/assets/VTextField-BssVoDhB.4cc388b4aa3c.css.br +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.4cc388b4aa3c.css.gz +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.css +1 -0
- codex/static_root/assets/VTextField-BssVoDhB.css.br +0 -0
- codex/static_root/assets/VTextField-BssVoDhB.css.gz +0 -0
- codex/static_root/assets/VTextField-DcZhRvPB.5eba90d2c45f.js +1 -0
- codex/static_root/assets/VTextField-DcZhRvPB.5eba90d2c45f.js.br +0 -0
- codex/static_root/assets/VTextField-DcZhRvPB.5eba90d2c45f.js.gz +0 -0
- codex/static_root/assets/VTextField-DcZhRvPB.js +1 -0
- codex/static_root/assets/VTextField-DcZhRvPB.js.br +0 -0
- codex/static_root/assets/VTextField-DcZhRvPB.js.gz +0 -0
- codex/static_root/assets/VWindowItem-0P4rgYDy.b96b44e20f8d.js +1 -0
- codex/static_root/assets/VWindowItem-0P4rgYDy.b96b44e20f8d.js.br +0 -0
- codex/static_root/assets/VWindowItem-0P4rgYDy.b96b44e20f8d.js.gz +0 -0
- codex/static_root/assets/VWindowItem-0P4rgYDy.js +1 -0
- codex/static_root/assets/VWindowItem-0P4rgYDy.js.br +0 -0
- codex/static_root/assets/VWindowItem-0P4rgYDy.js.gz +0 -0
- codex/static_root/assets/admin-CM5v3ffD.1889b8c1df83.js +1 -0
- codex/static_root/assets/admin-CM5v3ffD.1889b8c1df83.js.br +0 -0
- codex/static_root/assets/admin-CM5v3ffD.1889b8c1df83.js.gz +0 -0
- codex/static_root/assets/admin-CM5v3ffD.js +1 -0
- codex/static_root/assets/admin-CM5v3ffD.js.br +0 -0
- codex/static_root/assets/admin-CM5v3ffD.js.gz +0 -0
- codex/static_root/assets/{admin-CWEjaFr5.7d4523387384.css → admin-D4sw3N4T.b590f88a62cf.css} +1 -1
- codex/static_root/assets/admin-D4sw3N4T.b590f88a62cf.css.br +0 -0
- codex/static_root/assets/admin-D4sw3N4T.b590f88a62cf.css.gz +0 -0
- codex/static_root/assets/{admin-CWEjaFr5.css → admin-D4sw3N4T.css} +1 -1
- codex/static_root/assets/admin-D4sw3N4T.css.br +0 -0
- codex/static_root/assets/admin-D4sw3N4T.css.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-DOrhl9Nb.3a7af8ec4462.css +1 -0
- codex/static_root/assets/admin-drawer-panel-DOrhl9Nb.3a7af8ec4462.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-DOrhl9Nb.3a7af8ec4462.css.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-DOrhl9Nb.css +1 -0
- codex/static_root/assets/admin-drawer-panel-DOrhl9Nb.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-DOrhl9Nb.css.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-D_qGurp0.2904617d0407.js +61 -0
- codex/static_root/assets/admin-drawer-panel-D_qGurp0.2904617d0407.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-D_qGurp0.2904617d0407.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-D_qGurp0.js +61 -0
- codex/static_root/assets/admin-drawer-panel-D_qGurp0.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-D_qGurp0.js.gz +0 -0
- codex/static_root/assets/{browser-Binc3n9H.313722d27ca3.css → browser-B61tfW_K.61b1d18f4479.css} +1 -1
- codex/static_root/assets/browser-B61tfW_K.61b1d18f4479.css.br +0 -0
- codex/static_root/assets/browser-B61tfW_K.61b1d18f4479.css.gz +0 -0
- codex/static_root/assets/{browser-Binc3n9H.css → browser-B61tfW_K.css} +1 -1
- codex/static_root/assets/browser-B61tfW_K.css.br +0 -0
- codex/static_root/assets/browser-B61tfW_K.css.gz +0 -0
- codex/static_root/assets/browser-DnLOg4a-.3d16651e4daa.js +1 -0
- codex/static_root/assets/browser-DnLOg4a-.3d16651e4daa.js.br +0 -0
- codex/static_root/assets/browser-DnLOg4a-.3d16651e4daa.js.gz +0 -0
- codex/static_root/assets/browser-DnLOg4a-.js +1 -0
- codex/static_root/assets/browser-DnLOg4a-.js.br +0 -0
- codex/static_root/assets/browser-DnLOg4a-.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css +1 -0
- codex/static_root/assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css.br +0 -0
- codex/static_root/assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-0u6IJA87.css +1 -0
- codex/static_root/assets/change-password-dialog-0u6IJA87.css.br +0 -0
- codex/static_root/assets/change-password-dialog-0u6IJA87.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-B_FNP488.6009508df02f.js +1 -0
- codex/static_root/assets/change-password-dialog-B_FNP488.6009508df02f.js.br +0 -0
- codex/static_root/assets/change-password-dialog-B_FNP488.6009508df02f.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-B_FNP488.js +1 -0
- codex/static_root/assets/change-password-dialog-B_FNP488.js.br +0 -0
- codex/static_root/assets/change-password-dialog-B_FNP488.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-CEegFOPy.49243b6548c7.js +1 -0
- codex/static_root/assets/confirm-dialog-CEegFOPy.49243b6548c7.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CEegFOPy.49243b6548c7.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-CEegFOPy.js +1 -0
- codex/static_root/assets/confirm-dialog-CEegFOPy.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CEegFOPy.js.gz +0 -0
- codex/static_root/assets/{datetime-column-BRZDPl2k.f6ae3ce94da7.js → datetime-column-C10LMvbg.dd6d719d5ceb.js} +1 -1
- codex/static_root/assets/datetime-column-C10LMvbg.dd6d719d5ceb.js.br +0 -0
- codex/static_root/assets/datetime-column-C10LMvbg.dd6d719d5ceb.js.gz +0 -0
- codex/static_root/assets/{datetime-column-BRZDPl2k.js → datetime-column-C10LMvbg.js} +1 -1
- codex/static_root/assets/datetime-column-C10LMvbg.js.br +0 -0
- codex/static_root/assets/datetime-column-C10LMvbg.js.gz +0 -0
- codex/static_root/assets/{filter-Tk2N9xgO.02f23827434b.js → filter-C96Ludgn.7238da6d21fd.js} +1 -1
- codex/static_root/assets/filter-C96Ludgn.7238da6d21fd.js.br +0 -0
- codex/static_root/assets/filter-C96Ludgn.7238da6d21fd.js.gz +0 -0
- codex/static_root/assets/{filter-Tk2N9xgO.js → filter-C96Ludgn.js} +1 -1
- codex/static_root/assets/filter-C96Ludgn.js.br +0 -0
- codex/static_root/assets/filter-C96Ludgn.js.gz +0 -0
- codex/static_root/assets/flag-tab-C3MlArdN.2a06f46f4951.js +1 -0
- codex/static_root/assets/flag-tab-C3MlArdN.2a06f46f4951.js.br +0 -0
- codex/static_root/assets/flag-tab-C3MlArdN.2a06f46f4951.js.gz +0 -0
- codex/static_root/assets/flag-tab-C3MlArdN.js +1 -0
- codex/static_root/assets/flag-tab-C3MlArdN.js.br +0 -0
- codex/static_root/assets/flag-tab-C3MlArdN.js.gz +0 -0
- codex/static_root/assets/group-tab-BcQtQB5p.41780aa82feb.js +1 -0
- codex/static_root/assets/group-tab-BcQtQB5p.41780aa82feb.js.br +0 -0
- codex/static_root/assets/group-tab-BcQtQB5p.41780aa82feb.js.gz +0 -0
- codex/static_root/assets/group-tab-BcQtQB5p.js +1 -0
- codex/static_root/assets/group-tab-BcQtQB5p.js.br +0 -0
- codex/static_root/assets/group-tab-BcQtQB5p.js.gz +0 -0
- codex/static_root/assets/http-error-DskCJS4d.e51aabff2171.js +1 -0
- codex/static_root/assets/http-error-DskCJS4d.e51aabff2171.js.br +0 -0
- codex/static_root/assets/http-error-DskCJS4d.e51aabff2171.js.gz +0 -0
- codex/static_root/assets/http-error-DskCJS4d.js +1 -0
- codex/static_root/assets/http-error-DskCJS4d.js.br +0 -0
- codex/static_root/assets/http-error-DskCJS4d.js.gz +0 -0
- codex/static_root/assets/library-tab-BygwYPnO.94e92aa60bf2.css +1 -0
- codex/static_root/assets/library-tab-BygwYPnO.94e92aa60bf2.css.br +0 -0
- codex/static_root/assets/library-tab-BygwYPnO.94e92aa60bf2.css.gz +0 -0
- codex/static_root/assets/library-tab-BygwYPnO.css +1 -0
- codex/static_root/assets/library-tab-BygwYPnO.css.br +0 -0
- codex/static_root/assets/library-tab-BygwYPnO.css.gz +0 -0
- codex/static_root/assets/library-tab-ooPl8bku.bfcc0f7b4432.js +1 -0
- codex/static_root/assets/library-tab-ooPl8bku.bfcc0f7b4432.js.br +0 -0
- codex/static_root/assets/library-tab-ooPl8bku.bfcc0f7b4432.js.gz +0 -0
- codex/static_root/assets/library-tab-ooPl8bku.js +1 -0
- codex/static_root/assets/library-tab-ooPl8bku.js.br +0 -0
- codex/static_root/assets/library-tab-ooPl8bku.js.gz +0 -0
- codex/static_root/assets/main-C_v3V6g9.40fbf6d42a93.js +1 -0
- codex/static_root/assets/main-C_v3V6g9.40fbf6d42a93.js.br +0 -0
- codex/static_root/assets/main-C_v3V6g9.40fbf6d42a93.js.gz +0 -0
- codex/static_root/assets/main-C_v3V6g9.js +1 -0
- codex/static_root/assets/main-C_v3V6g9.js.br +0 -0
- codex/static_root/assets/main-C_v3V6g9.js.gz +0 -0
- codex/static_root/assets/{main-BZ73p_WW.css → main-Ztp855PW.css} +1 -1
- codex/static_root/assets/main-Ztp855PW.css.br +0 -0
- codex/static_root/assets/{main-BZ73p_WW.css.gz → main-Ztp855PW.css.gz} +0 -0
- codex/static_root/assets/{main-BZ73p_WW.d529e8b3f52a.css → main-Ztp855PW.d46d718fac45.css} +1 -1
- codex/static_root/assets/main-Ztp855PW.d46d718fac45.css.br +0 -0
- codex/static_root/assets/{main-BZ73p_WW.d529e8b3f52a.css.gz → main-Ztp855PW.d46d718fac45.css.gz} +0 -0
- codex/static_root/assets/pagination-toolbar-BA9ifTed.b4865334ee08.css +1 -0
- codex/static_root/assets/pagination-toolbar-BA9ifTed.b4865334ee08.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-BA9ifTed.b4865334ee08.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-BA9ifTed.css +1 -0
- codex/static_root/assets/pagination-toolbar-BA9ifTed.css.br +0 -0
- codex/static_root/assets/pagination-toolbar-BA9ifTed.css.gz +0 -0
- codex/static_root/assets/pagination-toolbar-DytNZNBD.be56c9194ecb.js +1 -0
- codex/static_root/assets/pagination-toolbar-DytNZNBD.be56c9194ecb.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-DytNZNBD.be56c9194ecb.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-DytNZNBD.js +1 -0
- codex/static_root/assets/pagination-toolbar-DytNZNBD.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-DytNZNBD.js.gz +0 -0
- codex/static_root/assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css +1 -0
- codex/static_root/assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css.br +0 -0
- codex/static_root/assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css.gz +0 -0
- codex/static_root/assets/pdf-doc-CMzaSV_K.css +1 -0
- codex/static_root/assets/pdf-doc-CMzaSV_K.css.br +0 -0
- codex/static_root/assets/pdf-doc-CMzaSV_K.css.gz +0 -0
- codex/static_root/assets/pdf-doc-k6Gv5nwG.22b85beec022.js +305 -0
- codex/static_root/assets/pdf-doc-k6Gv5nwG.22b85beec022.js.br +0 -0
- codex/static_root/assets/pdf-doc-k6Gv5nwG.22b85beec022.js.gz +0 -0
- codex/static_root/assets/pdf-doc-k6Gv5nwG.js +305 -0
- codex/static_root/assets/pdf-doc-k6Gv5nwG.js.br +0 -0
- codex/static_root/assets/pdf-doc-k6Gv5nwG.js.gz +0 -0
- codex/static_root/assets/reader-RcTjScAE.41459ab8f803.js +2 -0
- codex/static_root/assets/reader-RcTjScAE.41459ab8f803.js.br +0 -0
- codex/static_root/assets/reader-RcTjScAE.41459ab8f803.js.gz +0 -0
- codex/static_root/assets/reader-RcTjScAE.js +2 -0
- codex/static_root/assets/reader-RcTjScAE.js.br +0 -0
- codex/static_root/assets/reader-RcTjScAE.js.gz +0 -0
- codex/static_root/assets/reader-YbzUiD0T.css +1 -0
- codex/static_root/assets/reader-YbzUiD0T.css.br +0 -0
- codex/static_root/assets/reader-YbzUiD0T.css.gz +0 -0
- codex/static_root/assets/reader-YbzUiD0T.efb15835b39d.css +1 -0
- codex/static_root/assets/reader-YbzUiD0T.efb15835b39d.css.br +0 -0
- codex/static_root/assets/reader-YbzUiD0T.efb15835b39d.css.gz +0 -0
- codex/static_root/assets/{relation-chips-ByfWwuQc.01269a188e01.css → relation-chips-BGitp3yx.b3e7d178a615.css} +1 -1
- codex/static_root/assets/relation-chips-BGitp3yx.b3e7d178a615.css.br +0 -0
- codex/static_root/assets/relation-chips-BGitp3yx.b3e7d178a615.css.gz +0 -0
- codex/static_root/assets/{relation-chips-ByfWwuQc.css → relation-chips-BGitp3yx.css} +1 -1
- codex/static_root/assets/relation-chips-BGitp3yx.css.br +0 -0
- codex/static_root/assets/relation-chips-BGitp3yx.css.gz +0 -0
- codex/static_root/assets/relation-chips-DE08G87m.ea1b8391feff.js +1 -0
- codex/static_root/assets/relation-chips-DE08G87m.ea1b8391feff.js.br +0 -0
- codex/static_root/assets/relation-chips-DE08G87m.ea1b8391feff.js.gz +0 -0
- codex/static_root/assets/relation-chips-DE08G87m.js +1 -0
- codex/static_root/assets/relation-chips-DE08G87m.js.br +0 -0
- codex/static_root/assets/relation-chips-DE08G87m.js.gz +0 -0
- codex/static_root/assets/settings-drawer-BF5NdklY.0c3f4f51c12f.js +2 -0
- codex/static_root/assets/settings-drawer-BF5NdklY.0c3f4f51c12f.js.br +0 -0
- codex/static_root/assets/settings-drawer-BF5NdklY.0c3f4f51c12f.js.gz +0 -0
- codex/static_root/assets/settings-drawer-BF5NdklY.js +2 -0
- codex/static_root/assets/settings-drawer-BF5NdklY.js.br +0 -0
- codex/static_root/assets/settings-drawer-BF5NdklY.js.gz +0 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.01744e131806.css +1 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.01744e131806.css.br +0 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.01744e131806.css.gz +0 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.css +1 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.css.br +0 -0
- codex/static_root/assets/settings-drawer-nZ9HvKSZ.css.gz +0 -0
- codex/static_root/assets/{stats-tab-BXGisn5N.9b7a71e7fe28.css → stats-tab-BVZzfwi1.28f07f038e88.css} +1 -1
- codex/static_root/assets/stats-tab-BVZzfwi1.28f07f038e88.css.br +0 -0
- codex/static_root/assets/stats-tab-BVZzfwi1.28f07f038e88.css.gz +0 -0
- codex/static_root/assets/{stats-tab-BXGisn5N.css → stats-tab-BVZzfwi1.css} +1 -1
- codex/static_root/assets/stats-tab-BVZzfwi1.css.br +0 -0
- codex/static_root/assets/stats-tab-BVZzfwi1.css.gz +0 -0
- codex/static_root/assets/stats-tab-pGjIjQgL.f5f939abe108.js +1 -0
- codex/static_root/assets/stats-tab-pGjIjQgL.f5f939abe108.js.br +0 -0
- codex/static_root/assets/stats-tab-pGjIjQgL.f5f939abe108.js.gz +0 -0
- codex/static_root/assets/stats-tab-pGjIjQgL.js +1 -0
- codex/static_root/assets/stats-tab-pGjIjQgL.js.br +0 -0
- codex/static_root/assets/stats-tab-pGjIjQgL.js.gz +0 -0
- codex/static_root/assets/task-tab-DTZ-yJon.2000bd142ca2.js +1 -0
- codex/static_root/assets/task-tab-DTZ-yJon.2000bd142ca2.js.br +0 -0
- codex/static_root/assets/task-tab-DTZ-yJon.2000bd142ca2.js.gz +0 -0
- codex/static_root/assets/task-tab-DTZ-yJon.js +1 -0
- codex/static_root/assets/task-tab-DTZ-yJon.js.br +0 -0
- codex/static_root/assets/task-tab-DTZ-yJon.js.gz +0 -0
- codex/static_root/assets/unauthorized-BlNvdM7v.e3a8b210f100.js +1 -0
- codex/static_root/assets/unauthorized-BlNvdM7v.e3a8b210f100.js.br +0 -0
- codex/static_root/assets/unauthorized-BlNvdM7v.e3a8b210f100.js.gz +0 -0
- codex/static_root/assets/unauthorized-BlNvdM7v.js +1 -0
- codex/static_root/assets/unauthorized-BlNvdM7v.js.br +0 -0
- codex/static_root/assets/unauthorized-BlNvdM7v.js.gz +0 -0
- codex/static_root/assets/{unauthorized-muDsv-rC.2166ec8b3a32.css → unauthorized-YhYCb_lH.9b3ed0ae3331.css} +1 -1
- codex/static_root/assets/unauthorized-YhYCb_lH.9b3ed0ae3331.css.br +0 -0
- codex/static_root/assets/unauthorized-YhYCb_lH.9b3ed0ae3331.css.gz +0 -0
- codex/static_root/assets/{unauthorized-muDsv-rC.css → unauthorized-YhYCb_lH.css} +1 -1
- codex/static_root/assets/unauthorized-YhYCb_lH.css.br +0 -0
- codex/static_root/assets/unauthorized-YhYCb_lH.css.gz +0 -0
- codex/static_root/assets/user-tab-r6e-d5QN.30aebcf4898f.js +1 -0
- codex/static_root/assets/user-tab-r6e-d5QN.30aebcf4898f.js.br +0 -0
- codex/static_root/assets/user-tab-r6e-d5QN.30aebcf4898f.js.gz +0 -0
- codex/static_root/assets/user-tab-r6e-d5QN.js +1 -0
- codex/static_root/assets/user-tab-r6e-d5QN.js.br +0 -0
- codex/static_root/assets/user-tab-r6e-d5QN.js.gz +0 -0
- codex/static_root/js/choices-admin.1eca6d2c22cf.json +1 -0
- codex/static_root/js/choices-admin.1eca6d2c22cf.json.br +0 -0
- codex/static_root/js/choices-admin.1eca6d2c22cf.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.a300a8e1e4f3.json +609 -0
- codex/static_root/manifest.a300a8e1e4f3.json.br +0 -0
- codex/static_root/manifest.a300a8e1e4f3.json.gz +0 -0
- codex/static_root/manifest.json +282 -308
- codex/static_root/manifest.json.br +0 -0
- codex/static_root/manifest.json.gz +0 -0
- codex/static_root/staticfiles.json +1 -1
- codex/templates/pwa/serviceworker.js +4 -4
- codex/urls/root.py +6 -2
- codex/version.py +53 -0
- codex/views/admin/tasks.py +0 -2
- codex/views/admin/user.py +2 -4
- codex/views/bookmark.py +23 -16
- codex/views/browser/filters/annotations.py +4 -5
- codex/views/browser/validate.py +7 -4
- codex/views/const.py +2 -1
- codex/views/reader/books.py +2 -2
- codex/views/reader/init.py +2 -3
- codex/views/version.py +2 -10
- {codex-1.6.9a0.dist-info → codex-1.6.10.dist-info}/METADATA +8 -9
- {codex-1.6.9a0.dist-info → codex-1.6.10.dist-info}/RECORD +368 -375
- codex/librarian/janitor/latest_version.py +0 -54
- codex/static_root/assets/VCheckbox-BkQ2enlR.c750c7d8cecc.js +0 -1
- codex/static_root/assets/VCheckbox-BkQ2enlR.c750c7d8cecc.js.br +0 -0
- codex/static_root/assets/VCheckbox-BkQ2enlR.c750c7d8cecc.js.gz +0 -0
- codex/static_root/assets/VCheckbox-BkQ2enlR.js +0 -1
- codex/static_root/assets/VCheckbox-BkQ2enlR.js.br +0 -0
- codex/static_root/assets/VCheckbox-BkQ2enlR.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-C4qxJC_o.ff4628662392.js +0 -1
- codex/static_root/assets/VCheckboxBtn-C4qxJC_o.ff4628662392.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-C4qxJC_o.ff4628662392.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-C4qxJC_o.js +0 -1
- codex/static_root/assets/VCheckboxBtn-C4qxJC_o.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-C4qxJC_o.js.gz +0 -0
- codex/static_root/assets/VCombobox-CJYErhVj.5ae39362d05a.js +0 -1
- codex/static_root/assets/VCombobox-CJYErhVj.5ae39362d05a.js.br +0 -0
- codex/static_root/assets/VCombobox-CJYErhVj.5ae39362d05a.js.gz +0 -0
- codex/static_root/assets/VCombobox-CJYErhVj.js +0 -1
- codex/static_root/assets/VCombobox-CJYErhVj.js.br +0 -0
- codex/static_root/assets/VCombobox-CJYErhVj.js.gz +0 -0
- codex/static_root/assets/VCombobox-bwEYrXCg.9f25a34994e2.css +0 -1
- codex/static_root/assets/VCombobox-bwEYrXCg.9f25a34994e2.css.br +0 -0
- codex/static_root/assets/VCombobox-bwEYrXCg.9f25a34994e2.css.gz +0 -0
- codex/static_root/assets/VCombobox-bwEYrXCg.css +0 -1
- codex/static_root/assets/VCombobox-bwEYrXCg.css.br +0 -0
- codex/static_root/assets/VCombobox-bwEYrXCg.css.gz +0 -0
- codex/static_root/assets/VDialog-38np3TSA.5a0cb7a9e56d.css +0 -1
- codex/static_root/assets/VDialog-38np3TSA.5a0cb7a9e56d.css.br +0 -0
- codex/static_root/assets/VDialog-38np3TSA.5a0cb7a9e56d.css.gz +0 -0
- codex/static_root/assets/VDialog-38np3TSA.css +0 -1
- codex/static_root/assets/VDialog-38np3TSA.css.br +0 -0
- codex/static_root/assets/VDialog-38np3TSA.css.gz +0 -0
- codex/static_root/assets/VDialog-U73OI2x0.a74b15bb2eb4.js +0 -1
- codex/static_root/assets/VDialog-U73OI2x0.a74b15bb2eb4.js.br +0 -0
- codex/static_root/assets/VDialog-U73OI2x0.a74b15bb2eb4.js.gz +0 -0
- codex/static_root/assets/VDialog-U73OI2x0.js +0 -1
- codex/static_root/assets/VDialog-U73OI2x0.js.br +0 -0
- codex/static_root/assets/VDialog-U73OI2x0.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-6G1AUajL.5b17872981df.css +0 -1
- codex/static_root/assets/VExpansionPanels-6G1AUajL.5b17872981df.css.br +0 -0
- codex/static_root/assets/VExpansionPanels-6G1AUajL.5b17872981df.css.gz +0 -0
- codex/static_root/assets/VExpansionPanels-6G1AUajL.css +0 -1
- codex/static_root/assets/VExpansionPanels-6G1AUajL.css.br +0 -0
- codex/static_root/assets/VExpansionPanels-6G1AUajL.css.gz +0 -0
- codex/static_root/assets/VExpansionPanels-CfbnFRnp.11d5ca74c514.js +0 -1
- codex/static_root/assets/VExpansionPanels-CfbnFRnp.11d5ca74c514.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-CfbnFRnp.11d5ca74c514.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-CfbnFRnp.js +0 -1
- codex/static_root/assets/VExpansionPanels-CfbnFRnp.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-CfbnFRnp.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-Dk6ucuGh.b364223f1e2b.js +0 -1
- codex/static_root/assets/VRadioGroup-Dk6ucuGh.b364223f1e2b.js.br +0 -3
- codex/static_root/assets/VRadioGroup-Dk6ucuGh.b364223f1e2b.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-Dk6ucuGh.js +0 -1
- codex/static_root/assets/VRadioGroup-Dk6ucuGh.js.br +0 -3
- codex/static_root/assets/VRadioGroup-Dk6ucuGh.js.gz +0 -0
- codex/static_root/assets/VSelect-Ca2bIOso.6613989e4c45.css +0 -1
- codex/static_root/assets/VSelect-Ca2bIOso.6613989e4c45.css.br +0 -0
- codex/static_root/assets/VSelect-Ca2bIOso.6613989e4c45.css.gz +0 -0
- codex/static_root/assets/VSelect-Ca2bIOso.css +0 -1
- codex/static_root/assets/VSelect-Ca2bIOso.css.br +0 -0
- codex/static_root/assets/VSelect-Ca2bIOso.css.gz +0 -0
- codex/static_root/assets/VSelect-gqsRzrIv.f022ea270144.js +0 -1
- codex/static_root/assets/VSelect-gqsRzrIv.f022ea270144.js.br +0 -0
- codex/static_root/assets/VSelect-gqsRzrIv.f022ea270144.js.gz +0 -0
- codex/static_root/assets/VSelect-gqsRzrIv.js +0 -1
- codex/static_root/assets/VSelect-gqsRzrIv.js.br +0 -0
- codex/static_root/assets/VSelect-gqsRzrIv.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-BVJLEOcO.5d398b4b3b1c.js +0 -1
- codex/static_root/assets/VSelectionControl-BVJLEOcO.5d398b4b3b1c.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BVJLEOcO.5d398b4b3b1c.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-BVJLEOcO.js +0 -1
- codex/static_root/assets/VSelectionControl-BVJLEOcO.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BVJLEOcO.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-CiViEYoC.c77bb19a4a06.css.br +0 -0
- codex/static_root/assets/VSelectionControl-CiViEYoC.c77bb19a4a06.css.gz +0 -0
- codex/static_root/assets/VSelectionControl-CiViEYoC.css.br +0 -0
- codex/static_root/assets/VSelectionControl-CiViEYoC.css.gz +0 -0
- codex/static_root/assets/VSlideGroup-P_U-rmf2.ca3efe698702.js.br +0 -0
- codex/static_root/assets/VSlideGroup-P_U-rmf2.ca3efe698702.js.gz +0 -0
- codex/static_root/assets/VSlideGroup-P_U-rmf2.js.br +0 -0
- codex/static_root/assets/VSlideGroup-P_U-rmf2.js.gz +0 -0
- codex/static_root/assets/VTable-Coq-QwtQ.2b04104cbf05.js.br +0 -0
- codex/static_root/assets/VTable-Coq-QwtQ.2b04104cbf05.js.gz +0 -0
- codex/static_root/assets/VTable-Coq-QwtQ.js.br +0 -0
- codex/static_root/assets/VTable-Coq-QwtQ.js.gz +0 -0
- codex/static_root/assets/VTable-Y5Sc3hJd.c36f0a6a30cf.css +0 -1
- codex/static_root/assets/VTable-Y5Sc3hJd.c36f0a6a30cf.css.br +0 -0
- codex/static_root/assets/VTable-Y5Sc3hJd.c36f0a6a30cf.css.gz +0 -0
- codex/static_root/assets/VTable-Y5Sc3hJd.css +0 -1
- codex/static_root/assets/VTable-Y5Sc3hJd.css.br +0 -0
- codex/static_root/assets/VTable-Y5Sc3hJd.css.gz +0 -0
- codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css +0 -1
- codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css.br +0 -0
- codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css.gz +0 -0
- codex/static_root/assets/VTextField-Crc3gdNh.css +0 -1
- codex/static_root/assets/VTextField-Crc3gdNh.css.br +0 -0
- codex/static_root/assets/VTextField-Crc3gdNh.css.gz +0 -0
- codex/static_root/assets/VTextField-D8612eNs.bff65c141149.js +0 -1
- codex/static_root/assets/VTextField-D8612eNs.bff65c141149.js.br +0 -0
- codex/static_root/assets/VTextField-D8612eNs.bff65c141149.js.gz +0 -0
- codex/static_root/assets/VTextField-D8612eNs.js +0 -1
- codex/static_root/assets/VTextField-D8612eNs.js.br +0 -0
- codex/static_root/assets/VTextField-D8612eNs.js.gz +0 -0
- codex/static_root/assets/VWindowItem-BViiLFXH.70619152a4a5.js +0 -1
- codex/static_root/assets/VWindowItem-BViiLFXH.70619152a4a5.js.br +0 -0
- codex/static_root/assets/VWindowItem-BViiLFXH.70619152a4a5.js.gz +0 -0
- codex/static_root/assets/VWindowItem-BViiLFXH.js +0 -1
- codex/static_root/assets/VWindowItem-BViiLFXH.js.br +0 -0
- codex/static_root/assets/VWindowItem-BViiLFXH.js.gz +0 -0
- codex/static_root/assets/admin-CWEjaFr5.7d4523387384.css.br +0 -0
- codex/static_root/assets/admin-CWEjaFr5.7d4523387384.css.gz +0 -0
- codex/static_root/assets/admin-CWEjaFr5.css.br +0 -0
- codex/static_root/assets/admin-CWEjaFr5.css.gz +0 -0
- codex/static_root/assets/admin-RVemMSzT.fcbdca9f6b46.js +0 -1
- codex/static_root/assets/admin-RVemMSzT.fcbdca9f6b46.js.br +0 -0
- codex/static_root/assets/admin-RVemMSzT.fcbdca9f6b46.js.gz +0 -0
- codex/static_root/assets/admin-RVemMSzT.js +0 -1
- codex/static_root/assets/admin-RVemMSzT.js.br +0 -0
- codex/static_root/assets/admin-RVemMSzT.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.3cb33056e994.css +0 -1
- codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.3cb33056e994.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.3cb33056e994.css.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.css +0 -1
- codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.css.br +0 -0
- codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.css.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-Ul8BRcOp.0acaf708f24a.js +0 -30
- codex/static_root/assets/admin-drawer-panel-Ul8BRcOp.0acaf708f24a.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-Ul8BRcOp.0acaf708f24a.js.gz +0 -0
- codex/static_root/assets/admin-drawer-panel-Ul8BRcOp.js +0 -30
- codex/static_root/assets/admin-drawer-panel-Ul8BRcOp.js.br +0 -0
- codex/static_root/assets/admin-drawer-panel-Ul8BRcOp.js.gz +0 -0
- 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.br +0 -0
- codex/static_root/assets/browser-Binc3n9H.css.gz +0 -0
- codex/static_root/assets/browser-C9pnPT8U.bc239343d007.js +0 -1
- codex/static_root/assets/browser-C9pnPT8U.bc239343d007.js.br +0 -0
- codex/static_root/assets/browser-C9pnPT8U.bc239343d007.js.gz +0 -0
- codex/static_root/assets/browser-C9pnPT8U.js +0 -1
- codex/static_root/assets/browser-C9pnPT8U.js.br +0 -0
- codex/static_root/assets/browser-C9pnPT8U.js.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-DjxFqIRX.1a5ac7100192.js +0 -1
- codex/static_root/assets/change-password-dialog-DjxFqIRX.1a5ac7100192.js.br +0 -0
- codex/static_root/assets/change-password-dialog-DjxFqIRX.1a5ac7100192.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-DjxFqIRX.js +0 -1
- codex/static_root/assets/change-password-dialog-DjxFqIRX.js.br +0 -0
- codex/static_root/assets/change-password-dialog-DjxFqIRX.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-B-dLb_50.62d3ea64b93a.js +0 -1
- codex/static_root/assets/confirm-dialog-B-dLb_50.62d3ea64b93a.js.br +0 -0
- codex/static_root/assets/confirm-dialog-B-dLb_50.62d3ea64b93a.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-B-dLb_50.js +0 -1
- codex/static_root/assets/confirm-dialog-B-dLb_50.js.br +0 -0
- codex/static_root/assets/confirm-dialog-B-dLb_50.js.gz +0 -0
- codex/static_root/assets/datetime-column-BRZDPl2k.f6ae3ce94da7.js.br +0 -0
- codex/static_root/assets/datetime-column-BRZDPl2k.f6ae3ce94da7.js.gz +0 -0
- codex/static_root/assets/datetime-column-BRZDPl2k.js.br +0 -0
- codex/static_root/assets/datetime-column-BRZDPl2k.js.gz +0 -0
- codex/static_root/assets/filter-Tk2N9xgO.02f23827434b.js.br +0 -0
- codex/static_root/assets/filter-Tk2N9xgO.02f23827434b.js.gz +0 -0
- codex/static_root/assets/filter-Tk2N9xgO.js.br +0 -0
- codex/static_root/assets/filter-Tk2N9xgO.js.gz +0 -0
- codex/static_root/assets/flag-tab-C_v4CugS.928c1035d6ce.js +0 -1
- codex/static_root/assets/flag-tab-C_v4CugS.928c1035d6ce.js.br +0 -0
- codex/static_root/assets/flag-tab-C_v4CugS.928c1035d6ce.js.gz +0 -0
- codex/static_root/assets/flag-tab-C_v4CugS.js +0 -1
- codex/static_root/assets/flag-tab-C_v4CugS.js.br +0 -0
- codex/static_root/assets/flag-tab-C_v4CugS.js.gz +0 -0
- codex/static_root/assets/group-tab-Dn5N4Ebx.d2cf9c300427.js +0 -1
- codex/static_root/assets/group-tab-Dn5N4Ebx.d2cf9c300427.js.br +0 -0
- codex/static_root/assets/group-tab-Dn5N4Ebx.d2cf9c300427.js.gz +0 -0
- codex/static_root/assets/group-tab-Dn5N4Ebx.js +0 -1
- codex/static_root/assets/group-tab-Dn5N4Ebx.js.br +0 -0
- codex/static_root/assets/group-tab-Dn5N4Ebx.js.gz +0 -0
- codex/static_root/assets/http-error-DbRCRWKA.c31ec2f67f3b.js +0 -1
- codex/static_root/assets/http-error-DbRCRWKA.c31ec2f67f3b.js.br +0 -0
- codex/static_root/assets/http-error-DbRCRWKA.c31ec2f67f3b.js.gz +0 -0
- codex/static_root/assets/http-error-DbRCRWKA.js +0 -1
- codex/static_root/assets/http-error-DbRCRWKA.js.br +0 -0
- codex/static_root/assets/http-error-DbRCRWKA.js.gz +0 -0
- codex/static_root/assets/library-tab-Bh7ErAk7.7c44200ee727.css +0 -1
- codex/static_root/assets/library-tab-Bh7ErAk7.7c44200ee727.css.br +0 -2
- codex/static_root/assets/library-tab-Bh7ErAk7.7c44200ee727.css.gz +0 -0
- codex/static_root/assets/library-tab-Bh7ErAk7.css +0 -1
- codex/static_root/assets/library-tab-Bh7ErAk7.css.br +0 -2
- codex/static_root/assets/library-tab-Bh7ErAk7.css.gz +0 -0
- codex/static_root/assets/library-tab-CnvofvVA.419ab4e21896.js +0 -1
- codex/static_root/assets/library-tab-CnvofvVA.419ab4e21896.js.br +0 -0
- codex/static_root/assets/library-tab-CnvofvVA.419ab4e21896.js.gz +0 -0
- codex/static_root/assets/library-tab-CnvofvVA.js +0 -1
- codex/static_root/assets/library-tab-CnvofvVA.js.br +0 -0
- codex/static_root/assets/library-tab-CnvofvVA.js.gz +0 -0
- codex/static_root/assets/main-BHIo0ep5.6ec78d1380f0.js +0 -6
- codex/static_root/assets/main-BHIo0ep5.6ec78d1380f0.js.br +0 -0
- codex/static_root/assets/main-BHIo0ep5.6ec78d1380f0.js.gz +0 -0
- codex/static_root/assets/main-BHIo0ep5.js +0 -6
- codex/static_root/assets/main-BHIo0ep5.js.br +0 -0
- codex/static_root/assets/main-BHIo0ep5.js.gz +0 -0
- codex/static_root/assets/main-BZ73p_WW.css.br +0 -0
- codex/static_root/assets/main-BZ73p_WW.d529e8b3f52a.css.br +0 -0
- codex/static_root/assets/pager-full-pdf-DuOmJXkZ.5eaa11c55b1d.js +0 -1
- codex/static_root/assets/pager-full-pdf-DuOmJXkZ.5eaa11c55b1d.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-DuOmJXkZ.5eaa11c55b1d.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-DuOmJXkZ.js +0 -1
- codex/static_root/assets/pager-full-pdf-DuOmJXkZ.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-DuOmJXkZ.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-C45-onwe.4722195bb60b.css +0 -1
- 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 +0 -1
- 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-CzvikaTz.a025f20590fa.js +0 -1
- codex/static_root/assets/pagination-toolbar-CzvikaTz.a025f20590fa.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-CzvikaTz.a025f20590fa.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-CzvikaTz.js +0 -1
- codex/static_root/assets/pagination-toolbar-CzvikaTz.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-CzvikaTz.js.gz +0 -0
- codex/static_root/assets/pdf-doc-B5yncCrs.97ba5cf21b63.js +0 -305
- codex/static_root/assets/pdf-doc-B5yncCrs.97ba5cf21b63.js.br +0 -0
- codex/static_root/assets/pdf-doc-B5yncCrs.97ba5cf21b63.js.gz +0 -0
- codex/static_root/assets/pdf-doc-B5yncCrs.js +0 -305
- codex/static_root/assets/pdf-doc-B5yncCrs.js.br +0 -0
- codex/static_root/assets/pdf-doc-B5yncCrs.js.gz +0 -0
- codex/static_root/assets/pdf-doc-CG5-AZ2M.b94aac7e3313.css +0 -1
- codex/static_root/assets/pdf-doc-CG5-AZ2M.b94aac7e3313.css.br +0 -1
- codex/static_root/assets/pdf-doc-CG5-AZ2M.b94aac7e3313.css.gz +0 -0
- codex/static_root/assets/pdf-doc-CG5-AZ2M.css +0 -1
- codex/static_root/assets/pdf-doc-CG5-AZ2M.css.br +0 -1
- codex/static_root/assets/pdf-doc-CG5-AZ2M.css.gz +0 -0
- codex/static_root/assets/reader-BR3TSv3h.b00087748514.js +0 -2
- codex/static_root/assets/reader-BR3TSv3h.b00087748514.js.br +0 -0
- codex/static_root/assets/reader-BR3TSv3h.b00087748514.js.gz +0 -0
- codex/static_root/assets/reader-BR3TSv3h.js +0 -2
- codex/static_root/assets/reader-BR3TSv3h.js.br +0 -0
- codex/static_root/assets/reader-BR3TSv3h.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/relation-chips-ByfWwuQc.01269a188e01.css.br +0 -0
- codex/static_root/assets/relation-chips-ByfWwuQc.01269a188e01.css.gz +0 -0
- codex/static_root/assets/relation-chips-ByfWwuQc.css.br +0 -0
- codex/static_root/assets/relation-chips-ByfWwuQc.css.gz +0 -0
- codex/static_root/assets/relation-chips-C-62eg7F.d234f5d05881.js +0 -1
- codex/static_root/assets/relation-chips-C-62eg7F.d234f5d05881.js.br +0 -0
- codex/static_root/assets/relation-chips-C-62eg7F.d234f5d05881.js.gz +0 -0
- codex/static_root/assets/relation-chips-C-62eg7F.js +0 -1
- codex/static_root/assets/relation-chips-C-62eg7F.js.br +0 -0
- codex/static_root/assets/relation-chips-C-62eg7F.js.gz +0 -0
- codex/static_root/assets/settings-drawer-CpNFdMBP.e5b1af37e0a0.js +0 -2
- codex/static_root/assets/settings-drawer-CpNFdMBP.e5b1af37e0a0.js.br +0 -0
- codex/static_root/assets/settings-drawer-CpNFdMBP.e5b1af37e0a0.js.gz +0 -0
- codex/static_root/assets/settings-drawer-CpNFdMBP.js +0 -2
- codex/static_root/assets/settings-drawer-CpNFdMBP.js.br +0 -0
- codex/static_root/assets/settings-drawer-CpNFdMBP.js.gz +0 -0
- codex/static_root/assets/settings-drawer-DKncO_vX.0a2cd24cd904.css +0 -1
- codex/static_root/assets/settings-drawer-DKncO_vX.0a2cd24cd904.css.br +0 -0
- codex/static_root/assets/settings-drawer-DKncO_vX.0a2cd24cd904.css.gz +0 -0
- codex/static_root/assets/settings-drawer-DKncO_vX.css +0 -1
- codex/static_root/assets/settings-drawer-DKncO_vX.css.br +0 -0
- codex/static_root/assets/settings-drawer-DKncO_vX.css.gz +0 -0
- codex/static_root/assets/stats-tab-B0-L7btW.8f7914d5c8ac.js +0 -1
- codex/static_root/assets/stats-tab-B0-L7btW.8f7914d5c8ac.js.br +0 -0
- codex/static_root/assets/stats-tab-B0-L7btW.8f7914d5c8ac.js.gz +0 -0
- codex/static_root/assets/stats-tab-B0-L7btW.js +0 -1
- codex/static_root/assets/stats-tab-B0-L7btW.js.br +0 -0
- codex/static_root/assets/stats-tab-B0-L7btW.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/task-tab-CJEMX4mU.31d0755cc8f7.js +0 -1
- codex/static_root/assets/task-tab-CJEMX4mU.31d0755cc8f7.js.br +0 -0
- codex/static_root/assets/task-tab-CJEMX4mU.31d0755cc8f7.js.gz +0 -0
- codex/static_root/assets/task-tab-CJEMX4mU.js +0 -1
- codex/static_root/assets/task-tab-CJEMX4mU.js.br +0 -0
- codex/static_root/assets/task-tab-CJEMX4mU.js.gz +0 -0
- codex/static_root/assets/unauthorized-U1yum5qV.4a44970b19c7.js +0 -1
- codex/static_root/assets/unauthorized-U1yum5qV.4a44970b19c7.js.br +0 -0
- codex/static_root/assets/unauthorized-U1yum5qV.4a44970b19c7.js.gz +0 -0
- codex/static_root/assets/unauthorized-U1yum5qV.js +0 -1
- codex/static_root/assets/unauthorized-U1yum5qV.js.br +0 -0
- codex/static_root/assets/unauthorized-U1yum5qV.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-8DHYNhT5.3160ac8849a9.js +0 -1
- codex/static_root/assets/user-tab-8DHYNhT5.3160ac8849a9.js.br +0 -0
- codex/static_root/assets/user-tab-8DHYNhT5.3160ac8849a9.js.gz +0 -0
- codex/static_root/assets/user-tab-8DHYNhT5.js +0 -1
- codex/static_root/assets/user-tab-8DHYNhT5.js.br +0 -0
- codex/static_root/assets/user-tab-8DHYNhT5.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.c82a23abe985.json +0 -635
- codex/static_root/manifest.c82a23abe985.json.br +0 -0
- codex/static_root/manifest.c82a23abe985.json.gz +0 -0
- {codex-1.6.9a0.dist-info → codex-1.6.10.dist-info}/LICENSE +0 -0
- {codex-1.6.9a0.dist-info → codex-1.6.10.dist-info}/WHEEL +0 -0
- {codex-1.6.9a0.dist-info → codex-1.6.10.dist-info}/entry_points.txt +0 -0
codex/librarian/cron/crond.py
CHANGED
|
@@ -30,23 +30,21 @@ class CronThread(NamedThread):
|
|
|
30
30
|
self._task_times = ()
|
|
31
31
|
super().__init__(*args, name=self.__class__.__name__, daemon=True, **kwargs)
|
|
32
32
|
|
|
33
|
-
def
|
|
33
|
+
def _update_task_times(self):
|
|
34
34
|
task_times = {}
|
|
35
35
|
for task_class, func in _TASK_TIME_FUNCTION_MAP.items():
|
|
36
36
|
if dttm := func(self.log):
|
|
37
37
|
task_times[dttm] = task_class
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
task_tuple = tuple(sorted(task_times.items()))
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return 60
|
|
41
|
+
# There's always at least the janitor job
|
|
42
|
+
self._next_time = task_tuple[0][0]
|
|
43
|
+
self._task_times = task_tuple
|
|
45
44
|
|
|
46
|
-
|
|
45
|
+
def _get_timeout(self):
|
|
47
46
|
now = django_timezone.now()
|
|
48
|
-
delta =
|
|
49
|
-
self.log.debug(f"Next scheduled job at {next_time} in {delta}.")
|
|
47
|
+
delta = self._next_time - now
|
|
50
48
|
return max(0, int(delta.total_seconds()))
|
|
51
49
|
|
|
52
50
|
def _run_expired_jobs(self):
|
|
@@ -55,7 +53,6 @@ class CronThread(NamedThread):
|
|
|
55
53
|
if dttm < now:
|
|
56
54
|
self.librarian_queue.put(task_class())
|
|
57
55
|
else:
|
|
58
|
-
# Times are always ordered so stop checking at the first future job.
|
|
59
56
|
break
|
|
60
57
|
|
|
61
58
|
def run(self):
|
|
@@ -65,13 +62,13 @@ class CronThread(NamedThread):
|
|
|
65
62
|
with self._cond:
|
|
66
63
|
while not self._stop_event.is_set():
|
|
67
64
|
self._run_expired_jobs()
|
|
68
|
-
self.
|
|
69
|
-
sleep(2) # try to fix double jobs
|
|
65
|
+
self._update_task_times()
|
|
70
66
|
timeout = self._get_timeout()
|
|
67
|
+
self.log.debug(f"Next scheduled job at {self._next_time}.")
|
|
71
68
|
self._cond.wait(timeout=timeout)
|
|
72
69
|
if self._stop_event.is_set():
|
|
73
70
|
break
|
|
74
|
-
sleep(2) #
|
|
71
|
+
sleep(2) # fixes any time rounding problems
|
|
75
72
|
except Exception:
|
|
76
73
|
self.log.exception(f"In {self.__class__.__name__}")
|
|
77
74
|
self.log.debug(f"Stopped {self.__class__.__name__}.")
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""Bulk import and move comics and folders."""
|
|
2
2
|
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
3
|
from django.utils import timezone
|
|
6
4
|
|
|
7
5
|
from codex.librarian.importer.importer import ComicImporter
|
|
@@ -48,15 +46,6 @@ class ComicImporterThread(QueuedThread):
|
|
|
48
46
|
)
|
|
49
47
|
self._import(task)
|
|
50
48
|
|
|
51
|
-
def _update_groups(self, task):
|
|
52
|
-
pks = Library.objects.filter(covers_only=False).values_list("pk", flat=True)
|
|
53
|
-
start_time = task.start_time if task.start_time else timezone.now()
|
|
54
|
-
for pk in pks:
|
|
55
|
-
task = ImportDBDiffTask(library_id=pk)
|
|
56
|
-
importer = self._create_importer(task)
|
|
57
|
-
importer.update_all_groups({}, start_time)
|
|
58
|
-
self.librarian_queue.put(LIBRARY_CHANGED_TASK)
|
|
59
|
-
|
|
60
49
|
def _adopt_orphan_folders_for_library(self, library):
|
|
61
50
|
"""Adopt orphan folders for one library."""
|
|
62
51
|
orphan_folder_paths = (
|
|
@@ -64,20 +53,17 @@ class ComicImporterThread(QueuedThread):
|
|
|
64
53
|
.exclude(path=library.path)
|
|
65
54
|
.values_list("path", flat=True)
|
|
66
55
|
)
|
|
67
|
-
|
|
68
|
-
# Exclude deleted folders
|
|
69
|
-
folders_moved = {
|
|
70
|
-
path: path for path in orphan_folder_paths if Path(path).is_dir()
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if folders_moved:
|
|
74
|
-
self.log.debug(
|
|
75
|
-
f"{len(folders_moved)} orphan folders found in {library.path}"
|
|
76
|
-
)
|
|
77
|
-
else:
|
|
56
|
+
if not orphan_folder_paths:
|
|
78
57
|
self.log.debug(f"No orphan folders in {library.path}")
|
|
79
58
|
return False
|
|
80
59
|
|
|
60
|
+
self.log.debug(
|
|
61
|
+
f"{len(orphan_folder_paths)} orphan folders found in {library.path}"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Move in place
|
|
65
|
+
folders_moved = {path: path for path in orphan_folder_paths}
|
|
66
|
+
|
|
81
67
|
# An abridged import task.
|
|
82
68
|
task = ImportDBDiffTask(
|
|
83
69
|
library_id=library.pk,
|
|
@@ -103,6 +89,15 @@ class ComicImporterThread(QueuedThread):
|
|
|
103
89
|
|
|
104
90
|
self.status_controller.finish_many((moved_status, status))
|
|
105
91
|
|
|
92
|
+
def _update_groups(self, task):
|
|
93
|
+
pks = Library.objects.filter(covers_only=False).values_list("pk", flat=True)
|
|
94
|
+
start_time = task.start_time if task.start_time else timezone.now()
|
|
95
|
+
for pk in pks:
|
|
96
|
+
task = ImportDBDiffTask(library_id=pk)
|
|
97
|
+
importer = self._create_importer(task)
|
|
98
|
+
importer.update_all_groups({}, start_time)
|
|
99
|
+
self.librarian_queue.put(LIBRARY_CHANGED_TASK)
|
|
100
|
+
|
|
106
101
|
def process_item(self, item):
|
|
107
102
|
"""Run the updater."""
|
|
108
103
|
task = item
|
|
@@ -110,9 +105,9 @@ class ComicImporterThread(QueuedThread):
|
|
|
110
105
|
self._import(task)
|
|
111
106
|
elif isinstance(task, LazyImportComicsTask):
|
|
112
107
|
self._lazy_import_metadata(task)
|
|
113
|
-
elif isinstance(task, UpdateGroupsTask):
|
|
114
|
-
self._update_groups(task)
|
|
115
108
|
elif isinstance(task, AdoptOrphanFoldersTask):
|
|
116
109
|
self._adopt_orphan_folders()
|
|
110
|
+
elif isinstance(task, UpdateGroupsTask):
|
|
111
|
+
self._update_groups(task)
|
|
117
112
|
else:
|
|
118
113
|
self.log.warning(f"Bad task sent to library updater {task}")
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
-
from bidict import bidict
|
|
6
5
|
from django.db.models.functions import Now
|
|
7
6
|
|
|
8
7
|
from codex.librarian.importer.aggregate import AggregateMetadataImporter
|
|
@@ -24,42 +23,20 @@ from codex.status import Status
|
|
|
24
23
|
class MovedImporter(AggregateMetadataImporter):
|
|
25
24
|
"""Methods for moving comics and folders."""
|
|
26
25
|
|
|
27
|
-
def
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
if not
|
|
31
|
-
return
|
|
32
|
-
# Not sending statues to the controller for now.
|
|
33
|
-
status = Status(ImportStatusTypes.QUERY_MISSING_FKS)
|
|
34
|
-
create_folder_paths = self.query_missing_folder_paths(dest_comic_paths, status)
|
|
35
|
-
if not create_folder_paths:
|
|
26
|
+
def _bulk_comics_moved(self):
|
|
27
|
+
"""Move comcis."""
|
|
28
|
+
num_files_moved = len(self.task.files_moved)
|
|
29
|
+
if not num_files_moved:
|
|
36
30
|
return
|
|
37
|
-
status = Status(ImportStatusTypes.
|
|
38
|
-
self.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
status = Status(ImportStatusTypes.FILES_MOVED, 0, num_files_moved)
|
|
32
|
+
self.status_controller.start(status)
|
|
33
|
+
|
|
34
|
+
# Prepare FKs
|
|
35
|
+
create_folder_paths = set()
|
|
36
|
+
self.query_missing_folder_paths(create_folder_paths, status)
|
|
37
|
+
self.bulk_folders_create(frozenset(create_folder_paths), status)
|
|
42
38
|
|
|
43
|
-
|
|
44
|
-
"""Prepare one comic for bulk update."""
|
|
45
|
-
try:
|
|
46
|
-
new_path = self.task.files_moved[comic.path]
|
|
47
|
-
comic.path = new_path
|
|
48
|
-
new_path = Path(new_path)
|
|
49
|
-
comic.parent_folder = Folder.objects.get( # type: ignore
|
|
50
|
-
path=new_path.parent
|
|
51
|
-
)
|
|
52
|
-
comic.updated_at = Now()
|
|
53
|
-
comic.presave()
|
|
54
|
-
folder_m2m_links[comic.pk] = Folder.objects.filter(
|
|
55
|
-
path__in=new_path.parents
|
|
56
|
-
).values_list("pk", flat=True)
|
|
57
|
-
updated_comics.append(comic)
|
|
58
|
-
except Exception:
|
|
59
|
-
self.log.exception(f"moving {comic.path}")
|
|
60
|
-
|
|
61
|
-
def _bulk_comics_move_prepare(self):
|
|
62
|
-
"""Prepare Update Comics."""
|
|
39
|
+
# Update Comics
|
|
63
40
|
comics = Comic.objects.filter(
|
|
64
41
|
library=self.library, path__in=self.task.files_moved.keys()
|
|
65
42
|
).only("pk", "path", PARENT_FOLDER, FOLDERS_FIELD)
|
|
@@ -67,29 +44,29 @@ class MovedImporter(AggregateMetadataImporter):
|
|
|
67
44
|
folder_m2m_links = {}
|
|
68
45
|
updated_comics = []
|
|
69
46
|
for comic in comics.iterator():
|
|
70
|
-
|
|
47
|
+
try:
|
|
48
|
+
new_path = self.task.files_moved[comic.path]
|
|
49
|
+
comic.path = new_path
|
|
50
|
+
new_path = Path(new_path)
|
|
51
|
+
comic.parent_folder = Folder.objects.get( # type: ignore
|
|
52
|
+
path=new_path.parent
|
|
53
|
+
)
|
|
54
|
+
comic.updated_at = Now()
|
|
55
|
+
comic.presave()
|
|
56
|
+
folder_m2m_links[comic.pk] = Folder.objects.filter(
|
|
57
|
+
path__in=new_path.parents
|
|
58
|
+
).values_list("pk", flat=True)
|
|
59
|
+
updated_comics.append(comic)
|
|
60
|
+
except Exception:
|
|
61
|
+
self.log.exception(f"moving {comic.path}")
|
|
71
62
|
self.task.files_moved = {}
|
|
72
|
-
self.log.debug(f"Prepared {len(updated_comics)} for move...")
|
|
73
|
-
return updated_comics, folder_m2m_links
|
|
74
|
-
|
|
75
|
-
def _bulk_comics_moved(self):
|
|
76
|
-
"""Move comcis."""
|
|
77
|
-
num_files_moved = len(self.task.files_moved)
|
|
78
|
-
if not num_files_moved:
|
|
79
|
-
return
|
|
80
|
-
status = Status(ImportStatusTypes.FILES_MOVED, 0, num_files_moved)
|
|
81
|
-
self.status_controller.start(status)
|
|
82
63
|
|
|
83
|
-
# Prepare
|
|
84
|
-
self._bulk_comics_moved_ensure_folders()
|
|
85
|
-
updated_comics, folder_m2m_links = self._bulk_comics_move_prepare()
|
|
86
|
-
|
|
87
|
-
# Update comics
|
|
88
64
|
Comic.objects.bulk_update(updated_comics, MOVED_BULK_COMIC_UPDATE_FIELDS)
|
|
65
|
+
|
|
66
|
+
# Update m2m field
|
|
89
67
|
if folder_m2m_links:
|
|
90
68
|
self.bulk_fix_comic_m2m_field(FOLDERS_FIELD, folder_m2m_links, status)
|
|
91
|
-
|
|
92
|
-
count = len(updated_comics)
|
|
69
|
+
count = len(comics)
|
|
93
70
|
if count:
|
|
94
71
|
self.log.info(f"Moved {count} comics.")
|
|
95
72
|
|
|
@@ -163,32 +140,60 @@ class MovedImporter(AggregateMetadataImporter):
|
|
|
163
140
|
self.changed += count
|
|
164
141
|
self.status_controller.finish(status)
|
|
165
142
|
|
|
166
|
-
def
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
143
|
+
def _get_parent_folders(self, dest_folder_paths, status):
|
|
144
|
+
"""Get destination parent folders."""
|
|
145
|
+
# Determine parent folder paths.
|
|
146
|
+
dest_parent_folder_paths = set()
|
|
147
|
+
for dest_folder_path in dest_folder_paths:
|
|
148
|
+
dest_parent_path = str(Path(dest_folder_path).parent)
|
|
149
|
+
if dest_parent_path not in dest_folder_paths:
|
|
150
|
+
dest_parent_folder_paths.add(dest_parent_path)
|
|
151
|
+
|
|
152
|
+
# Create only intermediate subfolders.
|
|
153
|
+
existing_folder_paths = Folder.objects.filter(
|
|
154
|
+
library=self.library, path__in=dest_parent_folder_paths
|
|
155
|
+
).values_list("path", flat=True)
|
|
156
|
+
create_folder_paths = frozenset(
|
|
157
|
+
dest_parent_folder_paths - frozenset(existing_folder_paths)
|
|
174
158
|
)
|
|
159
|
+
self.bulk_folders_create(create_folder_paths, status)
|
|
175
160
|
|
|
176
|
-
#
|
|
161
|
+
# get parent folders path to model obj dict
|
|
162
|
+
dest_parent_folders_objs = Folder.objects.filter(
|
|
163
|
+
path__in=dest_parent_folder_paths
|
|
164
|
+
).only("path", "pk")
|
|
165
|
+
dest_parent_folders = {}
|
|
166
|
+
for folder in dest_parent_folders_objs.iterator():
|
|
167
|
+
dest_parent_folders[folder.path] = folder
|
|
168
|
+
return dest_parent_folders
|
|
169
|
+
|
|
170
|
+
def bulk_folders_moved(self):
|
|
171
|
+
"""Move folders in the database instead of recreating them."""
|
|
172
|
+
num_dirs_moved = len(self.task.dirs_moved)
|
|
173
|
+
if not num_dirs_moved:
|
|
174
|
+
return
|
|
175
|
+
status = Status(ImportStatusTypes.DIRS_MOVED, None, num_dirs_moved)
|
|
176
|
+
self.status_controller.start(status)
|
|
177
|
+
|
|
178
|
+
dest_folder_paths = frozenset(self.task.dirs_moved.values())
|
|
179
|
+
dest_parent_folders = self._get_parent_folders(dest_folder_paths, status)
|
|
180
|
+
|
|
181
|
+
src_folder_paths = frozenset(self.task.dirs_moved.keys())
|
|
182
|
+
folders_to_move = Folder.objects.filter(
|
|
183
|
+
library=self.library, path__in=src_folder_paths
|
|
184
|
+
).order_by("path")
|
|
177
185
|
|
|
178
|
-
new_paths = set()
|
|
179
186
|
update_folders = []
|
|
180
187
|
for folder in folders_to_move.iterator():
|
|
181
|
-
new_path = dirs_moved[folder.path]
|
|
182
|
-
new_paths.add(new_path)
|
|
188
|
+
new_path = self.task.dirs_moved[folder.path]
|
|
183
189
|
folder.name = Path(new_path).name
|
|
184
190
|
folder.path = new_path
|
|
185
191
|
parent_path_str = str(Path(new_path).parent)
|
|
186
|
-
folder.parent_folder =
|
|
192
|
+
folder.parent_folder = dest_parent_folders.get(parent_path_str)
|
|
187
193
|
folder.presave()
|
|
188
194
|
folder.updated_at = Now()
|
|
189
195
|
update_folders.append(folder)
|
|
190
|
-
|
|
191
|
-
# delete_folders = Folder.objects.filter(library=self.library, path__in=new_paths)
|
|
196
|
+
self.task.dirs_moved = {}
|
|
192
197
|
|
|
193
198
|
update_folders = sorted(update_folders, key=lambda x: len(Path(x.path).parts))
|
|
194
199
|
|
|
@@ -197,112 +202,6 @@ class MovedImporter(AggregateMetadataImporter):
|
|
|
197
202
|
if count:
|
|
198
203
|
self.log.info(f"Moved {count} folders.")
|
|
199
204
|
self.changed += count
|
|
200
|
-
status.add_complete(count)
|
|
201
|
-
self.status_controller.update(status, notify=False)
|
|
202
|
-
|
|
203
|
-
def _bulk_move_folders_under_existing_parents(
|
|
204
|
-
self, dest_parent_folder_paths_map, dirs_moved, status
|
|
205
|
-
):
|
|
206
|
-
"""Move folders under existing folders."""
|
|
207
|
-
while True:
|
|
208
|
-
# Get existing parent folders
|
|
209
|
-
# dest_parent_paths = tuple(str(path) for path in dest_parent_folder_paths_map)
|
|
210
|
-
dest_parent_paths = tuple(dest_parent_folder_paths_map.keys())
|
|
211
|
-
extant_parent_folders = Folder.objects.filter(
|
|
212
|
-
library=self.library, path__in=dest_parent_paths
|
|
213
|
-
).only("path")
|
|
214
|
-
|
|
215
|
-
# Create a list of folders than can be moved under existing folders.
|
|
216
|
-
dest_parent_folders_map = {}
|
|
217
|
-
src_folder_paths = []
|
|
218
|
-
for extant_parent_folder in extant_parent_folders:
|
|
219
|
-
dest_parent_folders_map[extant_parent_folder.path] = (
|
|
220
|
-
extant_parent_folder
|
|
221
|
-
)
|
|
222
|
-
if dest_folder_paths := dest_parent_folder_paths_map.pop(
|
|
223
|
-
extant_parent_folder.path
|
|
224
|
-
):
|
|
225
|
-
for dest_folder_path in dest_folder_paths:
|
|
226
|
-
src_path = dirs_moved.inverse[dest_folder_path]
|
|
227
|
-
src_folder_paths.append(src_path)
|
|
228
|
-
|
|
229
|
-
if not src_folder_paths:
|
|
230
|
-
return
|
|
231
|
-
src_folder_paths = sorted(src_folder_paths)
|
|
232
|
-
self.log.debug(f"Moving folders under existing parents: {src_folder_paths}")
|
|
233
|
-
|
|
234
|
-
self._bulk_move_folders(
|
|
235
|
-
src_folder_paths, dest_parent_folders_map, dirs_moved, status
|
|
236
|
-
)
|
|
237
|
-
|
|
238
|
-
def _get_move_create_folders_one_layer(self, dest_parent_folder_paths_map):
|
|
239
|
-
"""Find the next layer of folder paths to create."""
|
|
240
|
-
create_folder_paths_one_layer = set()
|
|
241
|
-
library_parts_len = len(Path(self.library.path).parts)
|
|
242
|
-
for parent_path_str in sorted(dest_parent_folder_paths_map.keys()):
|
|
243
|
-
parts = Path(parent_path_str).parts
|
|
244
|
-
# Get one layer of folders from existing layers.
|
|
245
|
-
possible_create_folder_path = ""
|
|
246
|
-
for index in range(library_parts_len, len(parts) + 1):
|
|
247
|
-
layer_parts = parts[:index]
|
|
248
|
-
possible_create_folder_path = str(Path(*layer_parts))
|
|
249
|
-
if (
|
|
250
|
-
possible_create_folder_path in create_folder_paths_one_layer
|
|
251
|
-
or not Folder.objects.filter(
|
|
252
|
-
library=self.library, path=possible_create_folder_path
|
|
253
|
-
).exists()
|
|
254
|
-
):
|
|
255
|
-
break
|
|
256
|
-
else:
|
|
257
|
-
possible_create_folder_path = ""
|
|
258
|
-
if possible_create_folder_path:
|
|
259
|
-
create_folder_paths_one_layer.add(possible_create_folder_path)
|
|
260
|
-
|
|
261
|
-
return frozenset(create_folder_paths_one_layer)
|
|
262
|
-
|
|
263
|
-
def _bulk_move_folders_and_create_parents(self, status):
|
|
264
|
-
"""Find folders that can be moved without creating parents."""
|
|
265
|
-
dirs_moved = bidict(self.task.dirs_moved)
|
|
266
|
-
|
|
267
|
-
dest_parent_folder_paths_map = {}
|
|
268
|
-
for dest_path in sorted(set(dirs_moved.values())):
|
|
269
|
-
parent = str(Path(dest_path).parent)
|
|
270
|
-
if parent not in dest_parent_folder_paths_map:
|
|
271
|
-
dest_parent_folder_paths_map[parent] = set()
|
|
272
|
-
dest_parent_folder_paths_map[parent].add(dest_path)
|
|
273
|
-
|
|
274
|
-
create_status = Status(ImportStatusTypes.CREATE_FKS)
|
|
275
|
-
layer = 1
|
|
276
|
-
while True:
|
|
277
|
-
self._bulk_move_folders_under_existing_parents(
|
|
278
|
-
dest_parent_folder_paths_map, dirs_moved, status
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
# All folders movable without creation have moved.
|
|
282
|
-
if not dest_parent_folder_paths_map:
|
|
283
|
-
break
|
|
284
|
-
self.log.debug(
|
|
285
|
-
f"Creating intermediate folder layer {layer} to move folders."
|
|
286
|
-
)
|
|
287
|
-
create_folder_paths_one_layer = self._get_move_create_folders_one_layer(
|
|
288
|
-
dest_parent_folder_paths_map
|
|
289
|
-
)
|
|
290
|
-
|
|
291
|
-
# Create one layer of folders
|
|
292
|
-
self.bulk_folders_create(create_folder_paths_one_layer, create_status)
|
|
293
|
-
layer += 1
|
|
294
|
-
|
|
295
|
-
def bulk_folders_moved(self):
|
|
296
|
-
"""Move folders in the database instead of recreating them."""
|
|
297
|
-
num_dirs_moved = len(self.task.dirs_moved)
|
|
298
|
-
if not num_dirs_moved:
|
|
299
|
-
return
|
|
300
|
-
status = Status(ImportStatusTypes.DIRS_MOVED, None, num_dirs_moved)
|
|
301
|
-
self.status_controller.start(status)
|
|
302
|
-
|
|
303
|
-
self._bulk_move_folders_and_create_parents(status)
|
|
304
|
-
self.task.dirs_moved = {}
|
|
305
|
-
|
|
306
205
|
self.status_controller.finish(status)
|
|
307
206
|
|
|
308
207
|
def _bulk_folders_modified(self):
|
|
@@ -334,8 +233,6 @@ class MovedImporter(AggregateMetadataImporter):
|
|
|
334
233
|
|
|
335
234
|
def move_and_modify_dirs(self):
|
|
336
235
|
"""Move files and dirs and modify dirs."""
|
|
337
|
-
# It would be nice to move folders instead of recreating them but it would require
|
|
338
|
-
# an inode map from the snapshots to do correctly.
|
|
339
236
|
self.bulk_folders_moved()
|
|
340
237
|
self._bulk_comics_moved()
|
|
341
238
|
self._bulk_covers_moved()
|
|
@@ -544,22 +544,19 @@ class QueryForeignKeysImporter(QueryCustomCoversImporter):
|
|
|
544
544
|
base_cls = Comic
|
|
545
545
|
fk_data = self.metadata[FK_CREATE][FKC_CREATE_FKS], base_cls, fk_field, "name"
|
|
546
546
|
names = self.metadata[FKS].pop(fk_field)
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
547
|
+
status.add_complete(
|
|
548
|
+
self._query_missing_simple_models(
|
|
549
|
+
names,
|
|
550
|
+
fk_data,
|
|
551
|
+
status,
|
|
552
|
+
)
|
|
551
553
|
)
|
|
552
|
-
status.add_complete(count)
|
|
553
554
|
self.status_controller.update(status, notify=False)
|
|
554
555
|
|
|
555
556
|
###########
|
|
556
557
|
# FOLDERS #
|
|
557
558
|
###########
|
|
558
|
-
def query_missing_folder_paths(
|
|
559
|
-
self,
|
|
560
|
-
comic_paths,
|
|
561
|
-
status,
|
|
562
|
-
):
|
|
559
|
+
def query_missing_folder_paths(self, comic_paths, status):
|
|
563
560
|
"""Find missing folder paths."""
|
|
564
561
|
# Get the proposed folder_paths
|
|
565
562
|
library_path = Path(self.library.path)
|
|
@@ -578,18 +575,15 @@ class QueryForeignKeysImporter(QueryCustomCoversImporter):
|
|
|
578
575
|
status,
|
|
579
576
|
)
|
|
580
577
|
create_folder_paths = create_folder_paths_dict.get(Folder, set())
|
|
581
|
-
return frozenset(create_folder_paths)
|
|
582
|
-
|
|
583
|
-
def _add_missing_folder_paths(self, comic_paths, status):
|
|
584
|
-
create_folder_paths = self.query_missing_folder_paths(comic_paths, status)
|
|
585
|
-
"""Add missing folder_paths to create fks."""
|
|
586
578
|
if FK_CREATE not in self.metadata:
|
|
587
579
|
self.metadata[FK_CREATE] = {}
|
|
588
580
|
if FKC_FOLDER_PATHS not in self.metadata[FK_CREATE]:
|
|
589
581
|
self.metadata[FK_CREATE][FKC_FOLDER_PATHS] = set()
|
|
590
582
|
self.metadata[FK_CREATE][FKC_FOLDER_PATHS] |= create_folder_paths
|
|
591
|
-
|
|
583
|
+
count = len(create_folder_paths)
|
|
584
|
+
if count:
|
|
592
585
|
self.log.info(f"Prepared {count} new Folders.")
|
|
586
|
+
return count
|
|
593
587
|
|
|
594
588
|
def _get_create_fks_totals(self):
|
|
595
589
|
fkc = self.metadata[FK_CREATE]
|
|
@@ -640,7 +634,7 @@ class QueryForeignKeysImporter(QueryCustomCoversImporter):
|
|
|
640
634
|
status,
|
|
641
635
|
)
|
|
642
636
|
|
|
643
|
-
self.
|
|
637
|
+
self.query_missing_folder_paths(
|
|
644
638
|
self.metadata[FKS].pop(COMIC_PATHS, ()), status
|
|
645
639
|
)
|
|
646
640
|
|
|
@@ -8,7 +8,6 @@ from codex.librarian.importer.tasks import (
|
|
|
8
8
|
)
|
|
9
9
|
from codex.librarian.janitor.cleanup import TOTAL_NUM_FK_CLASSES, CleanupMixin
|
|
10
10
|
from codex.librarian.janitor.failed_imports import UpdateFailedImportsMixin
|
|
11
|
-
from codex.librarian.janitor.latest_version import LatestVersionMixin
|
|
12
11
|
from codex.librarian.janitor.status import JanitorStatusTypes
|
|
13
12
|
from codex.librarian.janitor.tasks import (
|
|
14
13
|
ForceUpdateAllFailedImportsTask,
|
|
@@ -17,7 +16,6 @@ from codex.librarian.janitor.tasks import (
|
|
|
17
16
|
JanitorCleanFKsTask,
|
|
18
17
|
JanitorCleanupSessionsTask,
|
|
19
18
|
JanitorClearStatusTask,
|
|
20
|
-
JanitorLatestVersionTask,
|
|
21
19
|
JanitorNightlyTask,
|
|
22
20
|
JanitorRestartTask,
|
|
23
21
|
JanitorShutdownTask,
|
|
@@ -49,13 +47,10 @@ _JANITOR_STATII = (
|
|
|
49
47
|
Status(SearchIndexStatusTypes.SEARCH_INDEX_UPDATE),
|
|
50
48
|
Status(SearchIndexStatusTypes.SEARCH_INDEX_REMOVE),
|
|
51
49
|
Status(SearchIndexStatusTypes.SEARCH_INDEX_MERGE),
|
|
52
|
-
Status(JanitorStatusTypes.CODEX_LATEST_VERSION),
|
|
53
50
|
)
|
|
54
51
|
|
|
55
52
|
|
|
56
|
-
class Janitor(
|
|
57
|
-
CleanupMixin, LatestVersionMixin, UpdateMixin, UpdateFailedImportsMixin, VacuumMixin
|
|
58
|
-
):
|
|
53
|
+
class Janitor(CleanupMixin, UpdateMixin, VacuumMixin, UpdateFailedImportsMixin):
|
|
59
54
|
"""Janitor inline task runner."""
|
|
60
55
|
|
|
61
56
|
def __init__(self, log_queue, librarian_queue):
|
|
@@ -70,15 +65,14 @@ class Janitor(
|
|
|
70
65
|
).on
|
|
71
66
|
self.status_controller.start_many(_JANITOR_STATII)
|
|
72
67
|
tasks = (
|
|
73
|
-
JanitorLatestVersionTask(),
|
|
74
|
-
JanitorUpdateTask(force=False),
|
|
75
68
|
SearchIndexAbortTask(),
|
|
76
69
|
JanitorCleanFKsTask(),
|
|
77
70
|
JanitorCleanCoversTask(),
|
|
78
71
|
JanitorCleanupSessionsTask(),
|
|
79
|
-
AdoptOrphanFoldersTask(),
|
|
80
72
|
JanitorVacuumTask(),
|
|
81
73
|
JanitorBackupTask(),
|
|
74
|
+
JanitorUpdateTask(force=False),
|
|
75
|
+
AdoptOrphanFoldersTask(),
|
|
82
76
|
CoverRemoveOrphansTask(),
|
|
83
77
|
SearchIndexUpdateTask(False),
|
|
84
78
|
SearchIndexMergeTask(optimize),
|
|
@@ -97,10 +91,8 @@ class Janitor(
|
|
|
97
91
|
self.vacuum_db()
|
|
98
92
|
case JanitorBackupTask():
|
|
99
93
|
self.backup_db()
|
|
100
|
-
case JanitorLatestVersionTask():
|
|
101
|
-
self.update_latest_version(task.force)
|
|
102
94
|
case JanitorUpdateTask():
|
|
103
|
-
self.update_codex(
|
|
95
|
+
self.update_codex()
|
|
104
96
|
case JanitorRestartTask():
|
|
105
97
|
self.restart_codex()
|
|
106
98
|
case JanitorShutdownTask():
|
codex/librarian/janitor/tasks.py
CHANGED
|
@@ -8,20 +8,6 @@ class JanitorTask:
|
|
|
8
8
|
"""Tasks for the janitor."""
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
@dataclass
|
|
12
|
-
class JanitorLatestVersionTask(JanitorTask):
|
|
13
|
-
"""Get the latest version."""
|
|
14
|
-
|
|
15
|
-
force: bool = False
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@dataclass
|
|
19
|
-
class JanitorUpdateTask(JanitorTask):
|
|
20
|
-
"""Task for updater."""
|
|
21
|
-
|
|
22
|
-
force: bool = False
|
|
23
|
-
|
|
24
|
-
|
|
25
11
|
@dataclass
|
|
26
12
|
class JanitorBackupTask(JanitorTask):
|
|
27
13
|
"""Backup the database."""
|
|
@@ -37,6 +23,13 @@ class JanitorShutdownTask(JanitorTask):
|
|
|
37
23
|
"""for shutdown."""
|
|
38
24
|
|
|
39
25
|
|
|
26
|
+
@dataclass
|
|
27
|
+
class JanitorUpdateTask(JanitorTask):
|
|
28
|
+
"""Task for updater."""
|
|
29
|
+
|
|
30
|
+
force: bool
|
|
31
|
+
|
|
32
|
+
|
|
40
33
|
@dataclass
|
|
41
34
|
class JanitorVacuumTask(JanitorTask):
|
|
42
35
|
"""Vacuum the database."""
|
|
@@ -5,36 +5,17 @@ import signal
|
|
|
5
5
|
import subprocess
|
|
6
6
|
import sys
|
|
7
7
|
|
|
8
|
-
from versio.version import Version
|
|
9
|
-
|
|
10
8
|
from codex.librarian.janitor.status import JanitorStatusTypes
|
|
11
9
|
from codex.librarian.tasks import LibrarianShutdownTask
|
|
12
10
|
from codex.models import AdminFlag
|
|
13
|
-
from codex.models.admin import Timestamp
|
|
14
11
|
from codex.status import Status
|
|
15
|
-
from codex.version import VERSION, get_version
|
|
12
|
+
from codex.version import PACKAGE_NAME, VERSION, get_version, is_outdated
|
|
16
13
|
from codex.worker_base import WorkerBaseMixin
|
|
17
14
|
|
|
18
15
|
|
|
19
16
|
class UpdateMixin(WorkerBaseMixin):
|
|
20
17
|
"""Update codex methods for janitor."""
|
|
21
18
|
|
|
22
|
-
def _is_outdated(self):
|
|
23
|
-
"""Is codex outdated."""
|
|
24
|
-
result = False
|
|
25
|
-
ts = Timestamp.objects.get(key=Timestamp.TimestampChoices.CODEX_VERSION.value)
|
|
26
|
-
latest_version = ts.version
|
|
27
|
-
versio_latest_version = Version(latest_version)
|
|
28
|
-
|
|
29
|
-
installed_versio_version = Version(VERSION)
|
|
30
|
-
if versio_latest_version.parts[1] and not installed_versio_version.parts[1]: # type: ignore
|
|
31
|
-
pre_blurb = "latest version is a prerelease. But installed version is not."
|
|
32
|
-
else:
|
|
33
|
-
result = versio_latest_version > installed_versio_version
|
|
34
|
-
pre_blurb = ""
|
|
35
|
-
self.log.info(f"{latest_version=} > {VERSION=} = {result}{pre_blurb}")
|
|
36
|
-
return result
|
|
37
|
-
|
|
38
19
|
def update_codex(self, force=False):
|
|
39
20
|
"""Update the package and restart everything if the version changed."""
|
|
40
21
|
status = Status(JanitorStatusTypes.CODEX_UPDATE)
|
|
@@ -46,7 +27,7 @@ class UpdateMixin(WorkerBaseMixin):
|
|
|
46
27
|
eau = AdminFlag.objects.only("on").get(
|
|
47
28
|
key=AdminFlag.FlagChoices.AUTO_UPDATE.value
|
|
48
29
|
)
|
|
49
|
-
if not eau.on or not
|
|
30
|
+
if not eau.on or not is_outdated(PACKAGE_NAME):
|
|
50
31
|
self.log.info("Codex is up to date.")
|
|
51
32
|
return
|
|
52
33
|
|
|
@@ -21,7 +21,8 @@ class VacuumMixin(WorkerBaseMixin):
|
|
|
21
21
|
self.status_controller.start(status)
|
|
22
22
|
old_size = DB_PATH.stat().st_size
|
|
23
23
|
with connection.cursor() as cursor:
|
|
24
|
-
cursor.execute("PRAGMA
|
|
24
|
+
cursor.execute("PRAGMA analysis_limit=400;")
|
|
25
|
+
cursor.execute("PRAGMA optimize;")
|
|
25
26
|
cursor.execute("VACUUM")
|
|
26
27
|
cursor.execute("PRAGMA wal_checkpoint(TRUNCATE)")
|
|
27
28
|
new_size = DB_PATH.stat().st_size
|