codex 1.7.3a1__py3-none-any.whl → 1.7.4__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/asgi.py +2 -1
- codex/choices.py +12 -12
- codex/choices_to_json.py +8 -8
- codex/db.py +2 -2
- codex/exceptions.py +6 -7
- codex/librarian/bookmark/bookmarkd.py +8 -4
- codex/librarian/bookmark/update.py +82 -48
- codex/librarian/covers/create.py +10 -8
- codex/librarian/covers/path.py +6 -5
- codex/librarian/covers/purge.py +2 -2
- codex/librarian/importer/aggregate.py +2 -2
- codex/librarian/importer/cache.py +1 -4
- codex/librarian/importer/create_comics.py +2 -2
- codex/librarian/importer/create_covers.py +1 -1
- codex/librarian/importer/create_fks.py +4 -3
- codex/librarian/importer/deleted.py +3 -3
- codex/librarian/importer/extract.py +56 -37
- codex/librarian/importer/failed_imports.py +1 -1
- codex/librarian/importer/importer.py +3 -1
- codex/librarian/importer/importerd.py +3 -3
- codex/librarian/importer/link_comics.py +2 -1
- codex/librarian/importer/moved.py +2 -7
- codex/librarian/importer/query_fks.py +1 -4
- codex/librarian/importer/tasks.py +1 -1
- codex/librarian/janitor/integrity.py +27 -20
- codex/librarian/janitor/janitor.py +1 -1
- codex/librarian/janitor/latest_version.py +1 -1
- codex/librarian/janitor/update.py +2 -2
- codex/librarian/janitor/vacuum.py +1 -1
- codex/librarian/librariand.py +3 -2
- codex/librarian/notifier/notifierd.py +2 -1
- codex/librarian/search/optimize.py +1 -1
- codex/librarian/search/remove.py +1 -1
- codex/librarian/search/update.py +4 -4
- codex/librarian/telemeter/stats.py +7 -6
- codex/librarian/telemeter/telemeter.py +0 -1
- codex/librarian/watchdog/db_snapshot.py +3 -3
- codex/librarian/watchdog/dir_snapshot_diff.py +3 -4
- codex/librarian/watchdog/emitter.py +4 -4
- codex/librarian/watchdog/event_batcherd.py +2 -1
- codex/librarian/watchdog/events.py +1 -2
- codex/librarian/watchdog/observers.py +15 -10
- codex/logger/logging.py +1 -1
- codex/memory.py +3 -2
- codex/migrations/0001_init.py +1 -2
- codex/migrations/0014_pdf_issue_suffix_remove_cover_image_sort_name.py +1 -2
- codex/migrations/0018_rename_userbookmark_bookmark.py +1 -2
- codex/migrations/0028_telemeter.py +1 -5
- codex/migrations/0031_adminflag_banner.py +1 -1
- codex/models/admin.py +1 -1
- codex/models/base.py +3 -1
- codex/models/bookmark.py +4 -7
- codex/models/comic.py +2 -2
- codex/models/functions.py +12 -5
- codex/models/groups.py +1 -1
- codex/models/library.py +1 -1
- codex/models/paths.py +4 -4
- codex/models/query.py +8 -4
- codex/models/util.py +1 -1
- codex/permissions.py +1 -1
- codex/run.py +1 -1
- codex/serializers/admin/libraries.py +1 -3
- codex/serializers/admin/stats.py +4 -4
- codex/serializers/auth.py +4 -2
- codex/serializers/browser/choices.py +87 -9
- codex/serializers/browser/filters.py +9 -37
- codex/serializers/browser/metadata.py +2 -1
- codex/serializers/browser/mixins.py +7 -3
- codex/serializers/browser/mtime.py +3 -5
- codex/serializers/browser/page.py +5 -4
- codex/serializers/browser/settings.py +7 -5
- codex/serializers/fields/__init__.py +37 -0
- codex/serializers/fields/auth.py +45 -0
- codex/serializers/fields/browser.py +85 -0
- codex/serializers/fields/group.py +13 -0
- codex/serializers/fields/reader.py +22 -0
- codex/serializers/fields/sanitized.py +13 -0
- codex/serializers/fields/session.py +15 -0
- codex/serializers/fields/stats.py +36 -0
- codex/serializers/fields/vuetify.py +62 -0
- codex/serializers/models/base.py +1 -1
- codex/serializers/models/comic.py +2 -2
- codex/serializers/models/groups.py +0 -2
- codex/serializers/models/named.py +1 -1
- codex/serializers/models/pycountry.py +1 -1
- codex/serializers/opds/authentication.py +4 -2
- codex/serializers/opds/urls.py +2 -1
- codex/serializers/opds/v1.py +4 -3
- codex/serializers/opds/v2/feed.py +2 -1
- codex/serializers/opds/v2/links.py +23 -21
- codex/serializers/opds/v2/metadata.py +4 -8
- codex/serializers/opds/v2/progression.py +5 -3
- codex/serializers/opds/v2/publication.py +16 -18
- codex/serializers/opds/v2/unused.py +15 -8
- codex/serializers/reader.py +16 -14
- codex/serializers/redirect.py +2 -1
- codex/serializers/route.py +6 -4
- codex/serializers/settings.py +5 -3
- codex/serializers/versions.py +2 -1
- codex/settings/settings.py +4 -3
- codex/signals/django_signals.py +1 -1
- codex/static_root/assets/{VCheckbox-BV02IXFk.7b1ac0cc0c68.js → VCheckbox-CtTi6T7d.87331fa7e77f.js} +1 -1
- codex/static_root/assets/VCheckbox-CtTi6T7d.87331fa7e77f.js.br +0 -0
- codex/static_root/assets/VCheckbox-CtTi6T7d.87331fa7e77f.js.gz +0 -0
- codex/static_root/assets/{VCheckbox-BV02IXFk.js → VCheckbox-CtTi6T7d.js} +1 -1
- codex/static_root/assets/VCheckbox-CtTi6T7d.js.br +0 -0
- codex/static_root/assets/VCheckbox-CtTi6T7d.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-DRCMElDO.e3bc3b165786.js → VCheckboxBtn-DQafuWTH.dada5e0634ef.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-DQafuWTH.dada5e0634ef.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-DQafuWTH.dada5e0634ef.js.gz +0 -0
- codex/static_root/assets/{VCheckboxBtn-DRCMElDO.js → VCheckboxBtn-DQafuWTH.js} +1 -1
- codex/static_root/assets/VCheckboxBtn-DQafuWTH.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-DQafuWTH.js.gz +0 -0
- codex/static_root/assets/{VCombobox-BUzWpAvZ.ec97d55d18d6.js → VCombobox-C6TX3Dhp.e619423a6463.js} +1 -1
- codex/static_root/assets/VCombobox-C6TX3Dhp.e619423a6463.js.br +0 -0
- codex/static_root/assets/VCombobox-C6TX3Dhp.e619423a6463.js.gz +0 -0
- codex/static_root/assets/{VCombobox-BUzWpAvZ.js → VCombobox-C6TX3Dhp.js} +1 -1
- codex/static_root/assets/VCombobox-C6TX3Dhp.js.br +0 -0
- codex/static_root/assets/VCombobox-C6TX3Dhp.js.gz +0 -0
- codex/static_root/assets/{VDialog-CvyPs47z.06bd89160727.js → VDialog-CknWq2kd.b2d301ec6ac5.js} +1 -1
- codex/static_root/assets/VDialog-CknWq2kd.b2d301ec6ac5.js.br +0 -0
- codex/static_root/assets/VDialog-CknWq2kd.b2d301ec6ac5.js.gz +0 -0
- codex/static_root/assets/{VDialog-CvyPs47z.js → VDialog-CknWq2kd.js} +1 -1
- codex/static_root/assets/VDialog-CknWq2kd.js.br +0 -0
- codex/static_root/assets/VDialog-CknWq2kd.js.gz +0 -0
- codex/static_root/assets/{VDivider-DxA4gr8D.a62a378b1691.js → VDivider-F4DUgr74.62bc92cab97d.js} +1 -1
- codex/static_root/assets/VDivider-F4DUgr74.62bc92cab97d.js.br +0 -0
- codex/static_root/assets/VDivider-F4DUgr74.62bc92cab97d.js.gz +0 -0
- codex/static_root/assets/{VDivider-DxA4gr8D.js → VDivider-F4DUgr74.js} +1 -1
- codex/static_root/assets/VDivider-F4DUgr74.js.br +0 -0
- codex/static_root/assets/VDivider-F4DUgr74.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-_Hd_Icpj.4670cf36fda0.js → VExpansionPanels-CprYUTGT.39b8a50cde43.js} +1 -1
- codex/static_root/assets/VExpansionPanels-CprYUTGT.39b8a50cde43.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-CprYUTGT.39b8a50cde43.js.gz +0 -0
- codex/static_root/assets/{VExpansionPanels-_Hd_Icpj.js → VExpansionPanels-CprYUTGT.js} +1 -1
- codex/static_root/assets/VExpansionPanels-CprYUTGT.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-CprYUTGT.js.gz +0 -0
- codex/static_root/assets/{VForm-B4doHkrL.1f48583f2de6.js → VForm-DnWAUsrl.4ab0786d658e.js} +1 -1
- codex/static_root/assets/VForm-DnWAUsrl.4ab0786d658e.js.br +0 -0
- codex/static_root/assets/VForm-DnWAUsrl.4ab0786d658e.js.gz +0 -0
- codex/static_root/assets/{VForm-B4doHkrL.js → VForm-DnWAUsrl.js} +1 -1
- codex/static_root/assets/VForm-DnWAUsrl.js.br +0 -0
- codex/static_root/assets/VForm-DnWAUsrl.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-DT7JWkoW.28cd429e5a15.js → VRadioGroup-D71Rszum.befc87b0c476.js} +1 -1
- codex/static_root/assets/VRadioGroup-D71Rszum.befc87b0c476.js.br +0 -0
- codex/static_root/assets/VRadioGroup-D71Rszum.befc87b0c476.js.gz +0 -0
- codex/static_root/assets/{VRadioGroup-DT7JWkoW.js → VRadioGroup-D71Rszum.js} +1 -1
- codex/static_root/assets/VRadioGroup-D71Rszum.js.br +0 -0
- codex/static_root/assets/VRadioGroup-D71Rszum.js.gz +0 -0
- codex/static_root/assets/{VSelect-DtYhH7Mk.67eae5723992.js → VSelect-CbPDrHNj.4809fbbf00f0.js} +1 -1
- codex/static_root/assets/VSelect-CbPDrHNj.4809fbbf00f0.js.br +0 -0
- codex/static_root/assets/VSelect-CbPDrHNj.4809fbbf00f0.js.gz +0 -0
- codex/static_root/assets/{VSelect-DtYhH7Mk.js → VSelect-CbPDrHNj.js} +1 -1
- codex/static_root/assets/VSelect-CbPDrHNj.js.br +0 -0
- codex/static_root/assets/VSelect-CbPDrHNj.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-BJm6ORIw.efe501dcf742.js → VSelectionControl-It389cbo.ac75aee480a0.js} +1 -1
- codex/static_root/assets/VSelectionControl-It389cbo.ac75aee480a0.js.br +0 -0
- codex/static_root/assets/VSelectionControl-It389cbo.ac75aee480a0.js.gz +0 -0
- codex/static_root/assets/{VSelectionControl-BJm6ORIw.js → VSelectionControl-It389cbo.js} +1 -1
- codex/static_root/assets/VSelectionControl-It389cbo.js.br +0 -0
- codex/static_root/assets/VSelectionControl-It389cbo.js.gz +0 -0
- codex/static_root/assets/{VTable-Bpr_wGHh.65e8b5288ad7.js → VTable-D9e3lKk6.7cd0760008c7.js} +1 -1
- codex/static_root/assets/VTable-D9e3lKk6.7cd0760008c7.js.br +0 -0
- codex/static_root/assets/VTable-D9e3lKk6.7cd0760008c7.js.gz +0 -0
- codex/static_root/assets/{VTable-Bpr_wGHh.js → VTable-D9e3lKk6.js} +1 -1
- codex/static_root/assets/VTable-D9e3lKk6.js.br +0 -0
- codex/static_root/assets/VTable-D9e3lKk6.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-C1nqmRqv.aa75e27fc15e.js → VWindowItem-B4VZ37cq.e45c5018cc73.js} +1 -1
- codex/static_root/assets/VWindowItem-B4VZ37cq.e45c5018cc73.js.br +0 -0
- codex/static_root/assets/VWindowItem-B4VZ37cq.e45c5018cc73.js.gz +0 -0
- codex/static_root/assets/{VWindowItem-C1nqmRqv.js → VWindowItem-B4VZ37cq.js} +1 -1
- codex/static_root/assets/VWindowItem-B4VZ37cq.js.br +0 -0
- codex/static_root/assets/VWindowItem-B4VZ37cq.js.gz +0 -0
- codex/static_root/assets/{admin-Do4UwPej.6beffbe88dd0.js → admin-Bkd8zuSF.2a29386f3488.js} +1 -1
- codex/static_root/assets/admin-Bkd8zuSF.2a29386f3488.js.br +0 -0
- codex/static_root/assets/admin-Bkd8zuSF.2a29386f3488.js.gz +0 -0
- codex/static_root/assets/{admin-Do4UwPej.js → admin-Bkd8zuSF.js} +1 -1
- codex/static_root/assets/admin-Bkd8zuSF.js.br +0 -0
- codex/static_root/assets/admin-Bkd8zuSF.js.gz +0 -0
- codex/static_root/assets/{admin-BYCwfr2h.581e490b1ec8.js → admin-CFTKGwmx.18915c5df4d3.js} +1 -1
- codex/static_root/assets/admin-CFTKGwmx.18915c5df4d3.js.br +0 -0
- codex/static_root/assets/admin-CFTKGwmx.18915c5df4d3.js.gz +0 -0
- codex/static_root/assets/{admin-BYCwfr2h.js → admin-CFTKGwmx.js} +1 -1
- codex/static_root/assets/admin-CFTKGwmx.js.br +0 -0
- codex/static_root/assets/admin-CFTKGwmx.js.gz +0 -0
- codex/static_root/assets/{admin-menu-DyaS3ZkH.34c055460f79.js → admin-menu-CxZqtPES.7b3a06ce4b92.js} +1 -1
- codex/static_root/assets/admin-menu-CxZqtPES.7b3a06ce4b92.js.br +0 -0
- codex/static_root/assets/admin-menu-CxZqtPES.7b3a06ce4b92.js.gz +0 -0
- codex/static_root/assets/{admin-menu-DyaS3ZkH.js → admin-menu-CxZqtPES.js} +1 -1
- codex/static_root/assets/admin-menu-CxZqtPES.js.br +0 -0
- codex/static_root/assets/admin-menu-CxZqtPES.js.gz +0 -0
- codex/static_root/assets/{admin-settings-button-progress-BKp0yruZ.550d96596ce5.js → admin-settings-button-progress-D2TfW_5T.8a9d411ee79d.js} +1 -1
- codex/static_root/assets/admin-settings-button-progress-D2TfW_5T.8a9d411ee79d.js.br +0 -0
- codex/static_root/assets/admin-settings-button-progress-D2TfW_5T.8a9d411ee79d.js.gz +0 -0
- codex/static_root/assets/{admin-settings-button-progress-BKp0yruZ.js → admin-settings-button-progress-D2TfW_5T.js} +1 -1
- codex/static_root/assets/admin-settings-button-progress-D2TfW_5T.js.br +0 -0
- codex/static_root/assets/admin-settings-button-progress-D2TfW_5T.js.gz +0 -0
- codex/static_root/assets/browser-Br2DgAdi.433cca495d61.js +1 -0
- codex/static_root/assets/browser-Br2DgAdi.433cca495d61.js.br +0 -0
- codex/static_root/assets/browser-Br2DgAdi.433cca495d61.js.gz +0 -0
- codex/static_root/assets/browser-Br2DgAdi.js +1 -0
- codex/static_root/assets/browser-Br2DgAdi.js.br +0 -0
- codex/static_root/assets/browser-Br2DgAdi.js.gz +0 -0
- codex/static_root/assets/{browser-CReWGhn_.521193ab0710.css → browser-DNzQvgkY.aea8b7d7ca40.css} +1 -1
- codex/static_root/assets/browser-DNzQvgkY.aea8b7d7ca40.css.br +0 -0
- codex/static_root/assets/browser-DNzQvgkY.aea8b7d7ca40.css.gz +0 -0
- codex/static_root/assets/{browser-CReWGhn_.css → browser-DNzQvgkY.css} +1 -1
- codex/static_root/assets/browser-DNzQvgkY.css.br +0 -0
- codex/static_root/assets/browser-DNzQvgkY.css.gz +0 -0
- codex/static_root/assets/{change-password-dialog-DB0tGBYA.8712454eb2b5.js → change-password-dialog-CSylx5Qb.319466c891c9.js} +1 -1
- codex/static_root/assets/change-password-dialog-CSylx5Qb.319466c891c9.js.br +0 -0
- codex/static_root/assets/change-password-dialog-CSylx5Qb.319466c891c9.js.gz +0 -0
- codex/static_root/assets/{change-password-dialog-DB0tGBYA.js → change-password-dialog-CSylx5Qb.js} +1 -1
- codex/static_root/assets/change-password-dialog-CSylx5Qb.js.br +0 -0
- codex/static_root/assets/change-password-dialog-CSylx5Qb.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-CUfR1UVh.d59ed57fbf3c.js → confirm-dialog-Bx2R2vgR.d42b6449c495.js} +1 -1
- codex/static_root/assets/confirm-dialog-Bx2R2vgR.d42b6449c495.js.br +0 -0
- codex/static_root/assets/confirm-dialog-Bx2R2vgR.d42b6449c495.js.gz +0 -0
- codex/static_root/assets/{confirm-dialog-CUfR1UVh.js → confirm-dialog-Bx2R2vgR.js} +1 -1
- codex/static_root/assets/confirm-dialog-Bx2R2vgR.js.br +0 -0
- codex/static_root/assets/confirm-dialog-Bx2R2vgR.js.gz +0 -0
- codex/static_root/assets/{datetime-column-DWwCltHX.be3a30e165e2.js → datetime-column-sOrWMDcU.9ad225af18db.js} +1 -1
- codex/static_root/assets/datetime-column-sOrWMDcU.9ad225af18db.js.br +2 -0
- codex/static_root/assets/datetime-column-sOrWMDcU.9ad225af18db.js.gz +0 -0
- codex/static_root/assets/{datetime-column-DWwCltHX.js → datetime-column-sOrWMDcU.js} +1 -1
- codex/static_root/assets/datetime-column-sOrWMDcU.js.br +2 -0
- codex/static_root/assets/datetime-column-sOrWMDcU.js.gz +0 -0
- codex/static_root/assets/{filter-DUzmOcWQ.62e2578018fc.js → filter-SgjvoAvL.094069d6978d.js} +1 -1
- codex/static_root/assets/filter-SgjvoAvL.094069d6978d.js.br +0 -0
- codex/static_root/assets/filter-SgjvoAvL.094069d6978d.js.gz +0 -0
- codex/static_root/assets/{filter-DUzmOcWQ.js → filter-SgjvoAvL.js} +1 -1
- codex/static_root/assets/filter-SgjvoAvL.js.br +0 -0
- codex/static_root/assets/filter-SgjvoAvL.js.gz +0 -0
- codex/static_root/assets/flag-tab-B_0tGWPg.e46d1782b327.js +1 -0
- codex/static_root/assets/flag-tab-B_0tGWPg.e46d1782b327.js.br +0 -0
- codex/static_root/assets/flag-tab-B_0tGWPg.e46d1782b327.js.gz +0 -0
- codex/static_root/assets/flag-tab-B_0tGWPg.js +1 -0
- codex/static_root/assets/flag-tab-B_0tGWPg.js.br +0 -0
- codex/static_root/assets/flag-tab-B_0tGWPg.js.gz +0 -0
- codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css +1 -0
- codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css.br +0 -0
- codex/static_root/assets/flag-tab-D2MYXCHk.0f57e109c01b.css.gz +0 -0
- codex/static_root/assets/flag-tab-D2MYXCHk.css +1 -0
- codex/static_root/assets/flag-tab-D2MYXCHk.css.br +0 -0
- codex/static_root/assets/flag-tab-D2MYXCHk.css.gz +0 -0
- codex/static_root/assets/{forwardRefs-hLICxMEm.fd43ec456950.js → forwardRefs-DqbPK1-k.bb9d6863ac16.js} +1 -1
- codex/static_root/assets/forwardRefs-DqbPK1-k.bb9d6863ac16.js.br +0 -0
- codex/static_root/assets/forwardRefs-DqbPK1-k.bb9d6863ac16.js.gz +0 -0
- codex/static_root/assets/{forwardRefs-hLICxMEm.js → forwardRefs-DqbPK1-k.js} +1 -1
- codex/static_root/assets/forwardRefs-DqbPK1-k.js.br +0 -0
- codex/static_root/assets/forwardRefs-DqbPK1-k.js.gz +0 -0
- codex/static_root/assets/{group-tab-Ch6sd19Y.15f92ebc959d.js → group-tab-DXxQUa6C.f1f12f39b167.js} +1 -1
- codex/static_root/assets/group-tab-DXxQUa6C.f1f12f39b167.js.br +0 -0
- codex/static_root/assets/group-tab-DXxQUa6C.f1f12f39b167.js.gz +0 -0
- codex/static_root/assets/{group-tab-Ch6sd19Y.js → group-tab-DXxQUa6C.js} +1 -1
- codex/static_root/assets/group-tab-DXxQUa6C.js.br +0 -0
- codex/static_root/assets/group-tab-DXxQUa6C.js.gz +0 -0
- codex/static_root/assets/{http-error-BQoj78jv.fc5280352b17.js → http-error-BVMwwrFo.a7be6a26c9eb.js} +1 -1
- codex/static_root/assets/http-error-BVMwwrFo.a7be6a26c9eb.js.br +0 -0
- codex/static_root/assets/http-error-BVMwwrFo.a7be6a26c9eb.js.gz +0 -0
- codex/static_root/assets/{http-error-BQoj78jv.js → http-error-BVMwwrFo.js} +1 -1
- codex/static_root/assets/http-error-BVMwwrFo.js.br +0 -0
- codex/static_root/assets/http-error-BVMwwrFo.js.gz +0 -0
- codex/static_root/assets/{index-DtVx0ej4.9ca3e3d32eb8.js → index-DK0lSHDP.86f18c078fa9.js} +1 -1
- codex/static_root/assets/index-DK0lSHDP.86f18c078fa9.js.br +0 -0
- codex/static_root/assets/index-DK0lSHDP.86f18c078fa9.js.gz +0 -0
- codex/static_root/assets/{index-DtVx0ej4.js → index-DK0lSHDP.js} +1 -1
- codex/static_root/assets/index-DK0lSHDP.js.br +0 -0
- codex/static_root/assets/index-DK0lSHDP.js.gz +0 -0
- codex/static_root/assets/{library-tab-DEvrF6PF.c7a68c22664c.js → library-tab-NhXuvZ4F.1e8ac3b7c168.js} +1 -1
- codex/static_root/assets/library-tab-NhXuvZ4F.1e8ac3b7c168.js.br +0 -0
- codex/static_root/assets/library-tab-NhXuvZ4F.1e8ac3b7c168.js.gz +0 -0
- codex/static_root/assets/{library-tab-DEvrF6PF.js → library-tab-NhXuvZ4F.js} +1 -1
- codex/static_root/assets/library-tab-NhXuvZ4F.js.br +0 -0
- codex/static_root/assets/library-tab-NhXuvZ4F.js.gz +0 -0
- codex/static_root/assets/{main-DTplblFl.b8e4b708287f.js → main-CYgubU7H.50aa39cf9565.js} +3 -3
- codex/static_root/assets/main-CYgubU7H.50aa39cf9565.js.br +0 -0
- codex/static_root/assets/main-CYgubU7H.50aa39cf9565.js.gz +0 -0
- codex/static_root/assets/{main-DTplblFl.js → main-CYgubU7H.js} +3 -3
- codex/static_root/assets/main-CYgubU7H.js.br +0 -0
- codex/static_root/assets/main-CYgubU7H.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf---TZiAf5.a6269ab85085.js +1 -0
- codex/static_root/assets/pager-full-pdf---TZiAf5.a6269ab85085.js.br +0 -0
- codex/static_root/assets/pager-full-pdf---TZiAf5.a6269ab85085.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf---TZiAf5.js +1 -0
- codex/static_root/assets/pager-full-pdf---TZiAf5.js.br +0 -0
- codex/static_root/assets/pager-full-pdf---TZiAf5.js.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-DHVJWGeE.c70de5ca6915.js → pagination-toolbar-CeWXU_qA.abe0805da1cc.js} +1 -1
- codex/static_root/assets/pagination-toolbar-CeWXU_qA.abe0805da1cc.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-CeWXU_qA.abe0805da1cc.js.gz +0 -0
- codex/static_root/assets/{pagination-toolbar-DHVJWGeE.js → pagination-toolbar-CeWXU_qA.js} +1 -1
- codex/static_root/assets/pagination-toolbar-CeWXU_qA.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-CeWXU_qA.js.gz +0 -0
- codex/static_root/assets/{pdf-doc-DjtoQWxA.2c9fd3017300.js → pdf-doc-Dws_otkd.d215eca27da5.js} +1 -1
- codex/static_root/assets/pdf-doc-Dws_otkd.d215eca27da5.js.br +0 -0
- codex/static_root/assets/{pdf-doc-DjtoQWxA.js.gz → pdf-doc-Dws_otkd.d215eca27da5.js.gz} +0 -0
- codex/static_root/assets/{pdf-doc-DjtoQWxA.js → pdf-doc-Dws_otkd.js} +1 -1
- codex/static_root/assets/pdf-doc-Dws_otkd.js.br +0 -0
- codex/static_root/assets/{pdf-doc-DjtoQWxA.2c9fd3017300.js.gz → pdf-doc-Dws_otkd.js.gz} +0 -0
- codex/static_root/assets/{reader-DIjUh67D.js → reader-BCxYgZHF.dde3c4ac39a5.js} +2 -2
- codex/static_root/assets/reader-BCxYgZHF.dde3c4ac39a5.js.br +0 -0
- codex/static_root/assets/reader-BCxYgZHF.dde3c4ac39a5.js.gz +0 -0
- codex/static_root/assets/{reader-DIjUh67D.061a8b501e35.js → reader-BCxYgZHF.js} +2 -2
- codex/static_root/assets/reader-BCxYgZHF.js.br +0 -0
- codex/static_root/assets/reader-BCxYgZHF.js.gz +0 -0
- codex/static_root/assets/{relation-chips-ByFsclaN.2b9dc61299f6.js → relation-chips-DNRRCvrw.b1bc75fb9349.js} +1 -1
- codex/static_root/assets/relation-chips-DNRRCvrw.b1bc75fb9349.js.br +0 -0
- codex/static_root/assets/relation-chips-DNRRCvrw.b1bc75fb9349.js.gz +0 -0
- codex/static_root/assets/{relation-chips-ByFsclaN.js → relation-chips-DNRRCvrw.js} +1 -1
- codex/static_root/assets/relation-chips-DNRRCvrw.js.br +0 -0
- codex/static_root/assets/relation-chips-DNRRCvrw.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-DWa5PBWW.js → settings-drawer-BuB29L5p.fe2eeea0058f.js} +2 -2
- codex/static_root/assets/settings-drawer-BuB29L5p.fe2eeea0058f.js.br +0 -0
- codex/static_root/assets/settings-drawer-BuB29L5p.fe2eeea0058f.js.gz +0 -0
- codex/static_root/assets/{settings-drawer-DWa5PBWW.dee5ebeb24fe.js → settings-drawer-BuB29L5p.js} +2 -2
- codex/static_root/assets/settings-drawer-BuB29L5p.js.br +0 -0
- codex/static_root/assets/settings-drawer-BuB29L5p.js.gz +0 -0
- codex/static_root/assets/{stats-tab-B_i6PH1G.js → stats-tab-D0zymxU6.d5267113b51e.js} +1 -1
- codex/static_root/assets/stats-tab-D0zymxU6.d5267113b51e.js.br +0 -0
- codex/static_root/assets/stats-tab-D0zymxU6.d5267113b51e.js.gz +0 -0
- codex/static_root/assets/{stats-tab-B_i6PH1G.f11e0562b20d.js → stats-tab-D0zymxU6.js} +1 -1
- codex/static_root/assets/stats-tab-D0zymxU6.js.br +0 -0
- codex/static_root/assets/stats-tab-D0zymxU6.js.gz +0 -0
- codex/static_root/assets/{task-tab-DOEbnSf2.fe4907da1530.js → task-tab-CI9RLdMS.120f395dc9c6.js} +1 -1
- codex/static_root/assets/task-tab-CI9RLdMS.120f395dc9c6.js.br +0 -0
- codex/static_root/assets/task-tab-CI9RLdMS.120f395dc9c6.js.gz +0 -0
- codex/static_root/assets/{task-tab-DOEbnSf2.js → task-tab-CI9RLdMS.js} +1 -1
- codex/static_root/assets/task-tab-CI9RLdMS.js.br +0 -0
- codex/static_root/assets/task-tab-CI9RLdMS.js.gz +0 -0
- codex/static_root/assets/{unauthorized-Cblht_KD.e0c38cb1a24c.js → unauthorized-BNwg_Xvu.a894b96156e0.js} +1 -1
- codex/static_root/assets/unauthorized-BNwg_Xvu.a894b96156e0.js.br +0 -0
- codex/static_root/assets/unauthorized-BNwg_Xvu.a894b96156e0.js.gz +0 -0
- codex/static_root/assets/{unauthorized-Cblht_KD.js → unauthorized-BNwg_Xvu.js} +1 -1
- codex/static_root/assets/unauthorized-BNwg_Xvu.js.br +0 -0
- codex/static_root/assets/unauthorized-BNwg_Xvu.js.gz +0 -0
- codex/static_root/assets/{user-tab-CdvLJrTe.e52c18781b89.js → user-tab-w9LgIMMi.4a89c7b37486.js} +1 -1
- codex/static_root/assets/user-tab-w9LgIMMi.4a89c7b37486.js.br +0 -0
- codex/static_root/assets/user-tab-w9LgIMMi.4a89c7b37486.js.gz +0 -0
- codex/static_root/assets/{user-tab-CdvLJrTe.js → user-tab-w9LgIMMi.js} +1 -1
- codex/static_root/assets/user-tab-w9LgIMMi.js.br +0 -0
- codex/static_root/assets/user-tab-w9LgIMMi.js.gz +0 -0
- codex/static_root/manifest.514e63b9f805.json +735 -0
- codex/static_root/manifest.514e63b9f805.json.br +0 -0
- codex/static_root/manifest.514e63b9f805.json.gz +0 -0
- codex/static_root/manifest.json +305 -305
- codex/static_root/manifest.json.br +0 -0
- codex/static_root/manifest.json.gz +0 -0
- codex/static_root/staticfiles.json +1 -1
- codex/status_controller.py +9 -12
- codex/urls/root.py +4 -3
- codex/views/admin/api_key.py +1 -4
- codex/views/admin/library.py +4 -4
- codex/views/admin/stats.py +10 -10
- codex/views/admin/tasks.py +9 -9
- codex/views/auth.py +3 -8
- codex/views/bookmark.py +3 -3
- codex/views/browser/annotate/card.py +2 -2
- codex/views/browser/annotate/order.py +6 -7
- codex/views/browser/bookmark.py +3 -1
- codex/views/browser/breadcrumbs.py +6 -5
- codex/views/browser/browser.py +2 -2
- codex/views/browser/choices.py +6 -7
- codex/views/browser/cover.py +6 -3
- codex/views/browser/download.py +2 -1
- codex/views/browser/filters/bookmark.py +1 -1
- codex/views/browser/filters/field.py +1 -1
- codex/views/browser/filters/filter.py +6 -8
- codex/views/browser/filters/group.py +8 -8
- codex/views/browser/filters/search/field/expression.py +1 -2
- codex/views/browser/filters/search/field/optimize.py +1 -1
- codex/views/browser/filters/search/field/parse.py +2 -2
- codex/views/browser/filters/search/parse.py +4 -19
- codex/views/browser/group_mtime.py +1 -1
- codex/views/browser/metadata/copy_intersections.py +1 -1
- codex/views/browser/metadata/metadata.py +1 -1
- codex/views/browser/mtime.py +1 -1
- codex/views/browser/order_by.py +3 -5
- codex/views/browser/params.py +1 -1
- codex/views/browser/settings.py +1 -1
- codex/views/browser/validate.py +8 -5
- codex/views/const.py +0 -3
- codex/views/frontend.py +1 -1
- codex/views/mixins.py +3 -2
- codex/views/opds/authentication_v1.py +1 -1
- codex/views/opds/const.py +4 -4
- codex/views/opds/util.py +3 -3
- codex/views/opds/v1/entry/entry.py +4 -2
- codex/views/opds/v1/entry/links.py +4 -5
- codex/views/opds/v1/facets.py +8 -4
- codex/views/opds/v1/feed.py +5 -5
- codex/views/opds/v1/links.py +11 -6
- codex/views/opds/v2/const.py +5 -2
- codex/views/opds/v2/feed.py +3 -3
- codex/views/opds/v2/progression.py +8 -9
- codex/views/opds/v2/publications.py +10 -20
- codex/views/public.py +1 -1
- codex/views/reader/books.py +3 -2
- codex/views/reader/page.py +3 -3
- codex/views/reader/params.py +2 -2
- codex/views/reader/reader.py +6 -6
- codex/views/reader/settings.py +1 -1
- codex/views/session.py +8 -2
- codex/views/settings.py +2 -2
- codex/views/timezone.py +2 -2
- codex/views/util.py +10 -9
- codex/views/version.py +1 -1
- {codex-1.7.3a1.dist-info → codex-1.7.4.dist-info}/METADATA +3 -1
- {codex-1.7.3a1.dist-info → codex-1.7.4.dist-info}/RECORD +587 -579
- {codex-1.7.3a1.dist-info → codex-1.7.4.dist-info}/WHEEL +1 -1
- codex/serializers/fields.py +0 -183
- codex/static_root/assets/VCheckbox-BV02IXFk.7b1ac0cc0c68.js.br +0 -0
- codex/static_root/assets/VCheckbox-BV02IXFk.7b1ac0cc0c68.js.gz +0 -0
- codex/static_root/assets/VCheckbox-BV02IXFk.js.br +0 -0
- codex/static_root/assets/VCheckbox-BV02IXFk.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-DRCMElDO.e3bc3b165786.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-DRCMElDO.e3bc3b165786.js.gz +0 -0
- codex/static_root/assets/VCheckboxBtn-DRCMElDO.js.br +0 -0
- codex/static_root/assets/VCheckboxBtn-DRCMElDO.js.gz +0 -0
- codex/static_root/assets/VCombobox-BUzWpAvZ.ec97d55d18d6.js.br +0 -0
- codex/static_root/assets/VCombobox-BUzWpAvZ.ec97d55d18d6.js.gz +0 -0
- codex/static_root/assets/VCombobox-BUzWpAvZ.js.br +0 -0
- codex/static_root/assets/VCombobox-BUzWpAvZ.js.gz +0 -0
- codex/static_root/assets/VDialog-CvyPs47z.06bd89160727.js.br +0 -0
- codex/static_root/assets/VDialog-CvyPs47z.06bd89160727.js.gz +0 -0
- codex/static_root/assets/VDialog-CvyPs47z.js.br +0 -0
- codex/static_root/assets/VDialog-CvyPs47z.js.gz +0 -0
- codex/static_root/assets/VDivider-DxA4gr8D.a62a378b1691.js.br +0 -0
- codex/static_root/assets/VDivider-DxA4gr8D.a62a378b1691.js.gz +0 -0
- codex/static_root/assets/VDivider-DxA4gr8D.js.br +0 -0
- codex/static_root/assets/VDivider-DxA4gr8D.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-_Hd_Icpj.4670cf36fda0.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-_Hd_Icpj.4670cf36fda0.js.gz +0 -0
- codex/static_root/assets/VExpansionPanels-_Hd_Icpj.js.br +0 -0
- codex/static_root/assets/VExpansionPanels-_Hd_Icpj.js.gz +0 -0
- codex/static_root/assets/VForm-B4doHkrL.1f48583f2de6.js.br +0 -0
- codex/static_root/assets/VForm-B4doHkrL.1f48583f2de6.js.gz +0 -0
- codex/static_root/assets/VForm-B4doHkrL.js.br +0 -0
- codex/static_root/assets/VForm-B4doHkrL.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-DT7JWkoW.28cd429e5a15.js.br +0 -0
- codex/static_root/assets/VRadioGroup-DT7JWkoW.28cd429e5a15.js.gz +0 -0
- codex/static_root/assets/VRadioGroup-DT7JWkoW.js.br +0 -0
- codex/static_root/assets/VRadioGroup-DT7JWkoW.js.gz +0 -0
- codex/static_root/assets/VSelect-DtYhH7Mk.67eae5723992.js.br +0 -0
- codex/static_root/assets/VSelect-DtYhH7Mk.67eae5723992.js.gz +0 -0
- codex/static_root/assets/VSelect-DtYhH7Mk.js.br +0 -0
- codex/static_root/assets/VSelect-DtYhH7Mk.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-BJm6ORIw.efe501dcf742.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BJm6ORIw.efe501dcf742.js.gz +0 -0
- codex/static_root/assets/VSelectionControl-BJm6ORIw.js.br +0 -0
- codex/static_root/assets/VSelectionControl-BJm6ORIw.js.gz +0 -0
- codex/static_root/assets/VTable-Bpr_wGHh.65e8b5288ad7.js.br +0 -0
- codex/static_root/assets/VTable-Bpr_wGHh.65e8b5288ad7.js.gz +0 -0
- codex/static_root/assets/VTable-Bpr_wGHh.js.br +0 -0
- codex/static_root/assets/VTable-Bpr_wGHh.js.gz +0 -0
- codex/static_root/assets/VWindowItem-C1nqmRqv.aa75e27fc15e.js.br +0 -0
- codex/static_root/assets/VWindowItem-C1nqmRqv.aa75e27fc15e.js.gz +0 -0
- codex/static_root/assets/VWindowItem-C1nqmRqv.js.br +0 -0
- codex/static_root/assets/VWindowItem-C1nqmRqv.js.gz +0 -0
- codex/static_root/assets/admin-BYCwfr2h.581e490b1ec8.js.br +0 -0
- codex/static_root/assets/admin-BYCwfr2h.581e490b1ec8.js.gz +0 -0
- codex/static_root/assets/admin-BYCwfr2h.js.br +0 -0
- codex/static_root/assets/admin-BYCwfr2h.js.gz +0 -0
- codex/static_root/assets/admin-Do4UwPej.6beffbe88dd0.js.br +0 -0
- codex/static_root/assets/admin-Do4UwPej.6beffbe88dd0.js.gz +0 -0
- codex/static_root/assets/admin-Do4UwPej.js.br +0 -0
- codex/static_root/assets/admin-Do4UwPej.js.gz +0 -0
- codex/static_root/assets/admin-menu-DyaS3ZkH.34c055460f79.js.br +0 -0
- codex/static_root/assets/admin-menu-DyaS3ZkH.34c055460f79.js.gz +0 -0
- codex/static_root/assets/admin-menu-DyaS3ZkH.js.br +0 -0
- codex/static_root/assets/admin-menu-DyaS3ZkH.js.gz +0 -0
- codex/static_root/assets/admin-settings-button-progress-BKp0yruZ.550d96596ce5.js.br +0 -0
- codex/static_root/assets/admin-settings-button-progress-BKp0yruZ.550d96596ce5.js.gz +0 -0
- codex/static_root/assets/admin-settings-button-progress-BKp0yruZ.js.br +0 -0
- codex/static_root/assets/admin-settings-button-progress-BKp0yruZ.js.gz +0 -0
- codex/static_root/assets/browser-BcXpHHP5.ef6076284520.js +0 -1
- codex/static_root/assets/browser-BcXpHHP5.ef6076284520.js.br +0 -0
- codex/static_root/assets/browser-BcXpHHP5.ef6076284520.js.gz +0 -0
- codex/static_root/assets/browser-BcXpHHP5.js +0 -1
- codex/static_root/assets/browser-BcXpHHP5.js.br +0 -0
- codex/static_root/assets/browser-BcXpHHP5.js.gz +0 -0
- codex/static_root/assets/browser-CReWGhn_.521193ab0710.css.br +0 -0
- codex/static_root/assets/browser-CReWGhn_.521193ab0710.css.gz +0 -0
- codex/static_root/assets/browser-CReWGhn_.css.br +0 -0
- codex/static_root/assets/browser-CReWGhn_.css.gz +0 -0
- codex/static_root/assets/change-password-dialog-DB0tGBYA.8712454eb2b5.js.br +0 -0
- codex/static_root/assets/change-password-dialog-DB0tGBYA.8712454eb2b5.js.gz +0 -0
- codex/static_root/assets/change-password-dialog-DB0tGBYA.js.br +0 -0
- codex/static_root/assets/change-password-dialog-DB0tGBYA.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-CUfR1UVh.d59ed57fbf3c.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CUfR1UVh.d59ed57fbf3c.js.gz +0 -0
- codex/static_root/assets/confirm-dialog-CUfR1UVh.js.br +0 -0
- codex/static_root/assets/confirm-dialog-CUfR1UVh.js.gz +0 -0
- codex/static_root/assets/datetime-column-DWwCltHX.be3a30e165e2.js.br +0 -2
- codex/static_root/assets/datetime-column-DWwCltHX.be3a30e165e2.js.gz +0 -0
- codex/static_root/assets/datetime-column-DWwCltHX.js.br +0 -2
- codex/static_root/assets/datetime-column-DWwCltHX.js.gz +0 -0
- codex/static_root/assets/filter-DUzmOcWQ.62e2578018fc.js.br +0 -0
- codex/static_root/assets/filter-DUzmOcWQ.62e2578018fc.js.gz +0 -0
- codex/static_root/assets/filter-DUzmOcWQ.js.br +0 -0
- codex/static_root/assets/filter-DUzmOcWQ.js.gz +0 -0
- codex/static_root/assets/flag-tab-DHGfv0Q3.2b7ef394b850.css +0 -1
- codex/static_root/assets/flag-tab-DHGfv0Q3.2b7ef394b850.css.br +0 -0
- codex/static_root/assets/flag-tab-DHGfv0Q3.2b7ef394b850.css.gz +0 -0
- codex/static_root/assets/flag-tab-DHGfv0Q3.css +0 -1
- codex/static_root/assets/flag-tab-DHGfv0Q3.css.br +0 -0
- codex/static_root/assets/flag-tab-DHGfv0Q3.css.gz +0 -0
- codex/static_root/assets/flag-tab-DI0mJlXh.35d270069e4f.js +0 -1
- codex/static_root/assets/flag-tab-DI0mJlXh.35d270069e4f.js.br +0 -0
- codex/static_root/assets/flag-tab-DI0mJlXh.35d270069e4f.js.gz +0 -0
- codex/static_root/assets/flag-tab-DI0mJlXh.js +0 -1
- codex/static_root/assets/flag-tab-DI0mJlXh.js.br +0 -0
- codex/static_root/assets/flag-tab-DI0mJlXh.js.gz +0 -0
- codex/static_root/assets/forwardRefs-hLICxMEm.fd43ec456950.js.br +0 -0
- codex/static_root/assets/forwardRefs-hLICxMEm.fd43ec456950.js.gz +0 -0
- codex/static_root/assets/forwardRefs-hLICxMEm.js.br +0 -0
- codex/static_root/assets/forwardRefs-hLICxMEm.js.gz +0 -0
- codex/static_root/assets/group-tab-Ch6sd19Y.15f92ebc959d.js.br +0 -0
- codex/static_root/assets/group-tab-Ch6sd19Y.15f92ebc959d.js.gz +0 -0
- codex/static_root/assets/group-tab-Ch6sd19Y.js.br +0 -0
- codex/static_root/assets/group-tab-Ch6sd19Y.js.gz +0 -0
- codex/static_root/assets/http-error-BQoj78jv.fc5280352b17.js.br +0 -0
- codex/static_root/assets/http-error-BQoj78jv.fc5280352b17.js.gz +0 -0
- codex/static_root/assets/http-error-BQoj78jv.js.br +0 -0
- codex/static_root/assets/http-error-BQoj78jv.js.gz +0 -0
- codex/static_root/assets/index-DtVx0ej4.9ca3e3d32eb8.js.br +0 -0
- codex/static_root/assets/index-DtVx0ej4.9ca3e3d32eb8.js.gz +0 -0
- codex/static_root/assets/index-DtVx0ej4.js.br +0 -0
- codex/static_root/assets/index-DtVx0ej4.js.gz +0 -0
- codex/static_root/assets/library-tab-DEvrF6PF.c7a68c22664c.js.br +0 -0
- codex/static_root/assets/library-tab-DEvrF6PF.c7a68c22664c.js.gz +0 -0
- codex/static_root/assets/library-tab-DEvrF6PF.js.br +0 -0
- codex/static_root/assets/library-tab-DEvrF6PF.js.gz +0 -0
- codex/static_root/assets/main-DTplblFl.b8e4b708287f.js.br +0 -0
- codex/static_root/assets/main-DTplblFl.b8e4b708287f.js.gz +0 -0
- codex/static_root/assets/main-DTplblFl.js.br +0 -0
- codex/static_root/assets/main-DTplblFl.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-JIU1UvrN.627b621aa583.js +0 -1
- codex/static_root/assets/pager-full-pdf-JIU1UvrN.627b621aa583.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-JIU1UvrN.627b621aa583.js.gz +0 -0
- codex/static_root/assets/pager-full-pdf-JIU1UvrN.js +0 -1
- codex/static_root/assets/pager-full-pdf-JIU1UvrN.js.br +0 -0
- codex/static_root/assets/pager-full-pdf-JIU1UvrN.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-DHVJWGeE.c70de5ca6915.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-DHVJWGeE.c70de5ca6915.js.gz +0 -0
- codex/static_root/assets/pagination-toolbar-DHVJWGeE.js.br +0 -0
- codex/static_root/assets/pagination-toolbar-DHVJWGeE.js.gz +0 -0
- codex/static_root/assets/pdf-doc-DjtoQWxA.2c9fd3017300.js.br +0 -0
- codex/static_root/assets/pdf-doc-DjtoQWxA.js.br +0 -0
- codex/static_root/assets/reader-DIjUh67D.061a8b501e35.js.br +0 -0
- codex/static_root/assets/reader-DIjUh67D.061a8b501e35.js.gz +0 -0
- codex/static_root/assets/reader-DIjUh67D.js.br +0 -0
- codex/static_root/assets/reader-DIjUh67D.js.gz +0 -0
- codex/static_root/assets/relation-chips-ByFsclaN.2b9dc61299f6.js.br +0 -0
- codex/static_root/assets/relation-chips-ByFsclaN.2b9dc61299f6.js.gz +0 -0
- codex/static_root/assets/relation-chips-ByFsclaN.js.br +0 -0
- codex/static_root/assets/relation-chips-ByFsclaN.js.gz +0 -0
- codex/static_root/assets/settings-drawer-DWa5PBWW.dee5ebeb24fe.js.br +0 -0
- codex/static_root/assets/settings-drawer-DWa5PBWW.dee5ebeb24fe.js.gz +0 -0
- codex/static_root/assets/settings-drawer-DWa5PBWW.js.br +0 -0
- codex/static_root/assets/settings-drawer-DWa5PBWW.js.gz +0 -0
- codex/static_root/assets/stats-tab-B_i6PH1G.f11e0562b20d.js.br +0 -0
- codex/static_root/assets/stats-tab-B_i6PH1G.f11e0562b20d.js.gz +0 -0
- codex/static_root/assets/stats-tab-B_i6PH1G.js.br +0 -0
- codex/static_root/assets/stats-tab-B_i6PH1G.js.gz +0 -0
- codex/static_root/assets/task-tab-DOEbnSf2.fe4907da1530.js.br +0 -0
- codex/static_root/assets/task-tab-DOEbnSf2.fe4907da1530.js.gz +0 -0
- codex/static_root/assets/task-tab-DOEbnSf2.js.br +0 -0
- codex/static_root/assets/task-tab-DOEbnSf2.js.gz +0 -0
- codex/static_root/assets/unauthorized-Cblht_KD.e0c38cb1a24c.js.br +0 -0
- codex/static_root/assets/unauthorized-Cblht_KD.e0c38cb1a24c.js.gz +0 -0
- codex/static_root/assets/unauthorized-Cblht_KD.js.br +0 -0
- codex/static_root/assets/unauthorized-Cblht_KD.js.gz +0 -0
- codex/static_root/assets/user-tab-CdvLJrTe.e52c18781b89.js.br +0 -0
- codex/static_root/assets/user-tab-CdvLJrTe.e52c18781b89.js.gz +0 -0
- codex/static_root/assets/user-tab-CdvLJrTe.js.br +0 -0
- codex/static_root/assets/user-tab-CdvLJrTe.js.gz +0 -0
- codex/static_root/manifest.e3e070ebb908.json +0 -735
- codex/static_root/manifest.e3e070ebb908.json.br +0 -0
- codex/static_root/manifest.e3e070ebb908.json.gz +0 -0
- /codex/static_root/assets/{VCheckbox-CMKdyl0R.016ed8d222c4.css → VCheckbox-CvH8ekHL.016ed8d222c4.css} +0 -0
- /codex/static_root/assets/{VCheckbox-CMKdyl0R.016ed8d222c4.css.br → VCheckbox-CvH8ekHL.016ed8d222c4.css.br} +0 -0
- /codex/static_root/assets/{VCheckbox-CMKdyl0R.016ed8d222c4.css.gz → VCheckbox-CvH8ekHL.016ed8d222c4.css.gz} +0 -0
- /codex/static_root/assets/{VCheckbox-CMKdyl0R.css → VCheckbox-CvH8ekHL.css} +0 -0
- /codex/static_root/assets/{VCheckbox-CMKdyl0R.css.br → VCheckbox-CvH8ekHL.css.br} +0 -0
- /codex/static_root/assets/{VCheckbox-CMKdyl0R.css.gz → VCheckbox-CvH8ekHL.css.gz} +0 -0
- /codex/static_root/assets/{VCombobox-bwEYrXCg.9f25a34994e2.css → VCombobox-BQHELb_o.9f25a34994e2.css} +0 -0
- /codex/static_root/assets/{VCombobox-bwEYrXCg.9f25a34994e2.css.br → VCombobox-BQHELb_o.9f25a34994e2.css.br} +0 -0
- /codex/static_root/assets/{VCombobox-bwEYrXCg.9f25a34994e2.css.gz → VCombobox-BQHELb_o.9f25a34994e2.css.gz} +0 -0
- /codex/static_root/assets/{VCombobox-bwEYrXCg.css → VCombobox-BQHELb_o.css} +0 -0
- /codex/static_root/assets/{VCombobox-bwEYrXCg.css.br → VCombobox-BQHELb_o.css.br} +0 -0
- /codex/static_root/assets/{VCombobox-bwEYrXCg.css.gz → VCombobox-BQHELb_o.css.gz} +0 -0
- /codex/static_root/assets/{VDialog-Dyd05WHA.b07aca713774.css → VDialog-DWos4S54.b07aca713774.css} +0 -0
- /codex/static_root/assets/{VDialog-Dyd05WHA.b07aca713774.css.br → VDialog-DWos4S54.b07aca713774.css.br} +0 -0
- /codex/static_root/assets/{VDialog-Dyd05WHA.b07aca713774.css.gz → VDialog-DWos4S54.b07aca713774.css.gz} +0 -0
- /codex/static_root/assets/{VDialog-Dyd05WHA.css → VDialog-DWos4S54.css} +0 -0
- /codex/static_root/assets/{VDialog-Dyd05WHA.css.br → VDialog-DWos4S54.css.br} +0 -0
- /codex/static_root/assets/{VDialog-Dyd05WHA.css.gz → VDialog-DWos4S54.css.gz} +0 -0
- /codex/static_root/assets/{VDivider-DE8MJPGz.3d2e17799e5c.css → VDivider-DU47sRrT.3d2e17799e5c.css} +0 -0
- /codex/static_root/assets/{VDivider-DE8MJPGz.3d2e17799e5c.css.br → VDivider-DU47sRrT.3d2e17799e5c.css.br} +0 -0
- /codex/static_root/assets/{VDivider-DE8MJPGz.3d2e17799e5c.css.gz → VDivider-DU47sRrT.3d2e17799e5c.css.gz} +0 -0
- /codex/static_root/assets/{VDivider-DE8MJPGz.css → VDivider-DU47sRrT.css} +0 -0
- /codex/static_root/assets/{VDivider-DE8MJPGz.css.br → VDivider-DU47sRrT.css.br} +0 -0
- /codex/static_root/assets/{VDivider-DE8MJPGz.css.gz → VDivider-DU47sRrT.css.gz} +0 -0
- /codex/static_root/assets/{VExpansionPanels-6G1AUajL.5b17872981df.css → VExpansionPanels-RsCANmDP.5b17872981df.css} +0 -0
- /codex/static_root/assets/{VExpansionPanels-6G1AUajL.5b17872981df.css.br → VExpansionPanels-RsCANmDP.5b17872981df.css.br} +0 -0
- /codex/static_root/assets/{VExpansionPanels-6G1AUajL.5b17872981df.css.gz → VExpansionPanels-RsCANmDP.5b17872981df.css.gz} +0 -0
- /codex/static_root/assets/{VExpansionPanels-6G1AUajL.css → VExpansionPanels-RsCANmDP.css} +0 -0
- /codex/static_root/assets/{VExpansionPanels-6G1AUajL.css.br → VExpansionPanels-RsCANmDP.css.br} +0 -0
- /codex/static_root/assets/{VExpansionPanels-6G1AUajL.css.gz → VExpansionPanels-RsCANmDP.css.gz} +0 -0
- /codex/static_root/assets/{VForm-v1Gmu6E1.138c0b89b6fc.css → VForm-DxBt30-N.138c0b89b6fc.css} +0 -0
- /codex/static_root/assets/{VForm-v1Gmu6E1.138c0b89b6fc.css.br → VForm-DxBt30-N.138c0b89b6fc.css.br} +0 -0
- /codex/static_root/assets/{VForm-v1Gmu6E1.138c0b89b6fc.css.gz → VForm-DxBt30-N.138c0b89b6fc.css.gz} +0 -0
- /codex/static_root/assets/{VForm-v1Gmu6E1.css → VForm-DxBt30-N.css} +0 -0
- /codex/static_root/assets/{VForm-v1Gmu6E1.css.br → VForm-DxBt30-N.css.br} +0 -0
- /codex/static_root/assets/{VForm-v1Gmu6E1.css.gz → VForm-DxBt30-N.css.gz} +0 -0
- /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.8e3741381961.css → VRadioGroup-Cp9mZ7cb.8e3741381961.css} +0 -0
- /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.8e3741381961.css.br → VRadioGroup-Cp9mZ7cb.8e3741381961.css.br} +0 -0
- /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.8e3741381961.css.gz → VRadioGroup-Cp9mZ7cb.8e3741381961.css.gz} +0 -0
- /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.css → VRadioGroup-Cp9mZ7cb.css} +0 -0
- /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.css.br → VRadioGroup-Cp9mZ7cb.css.br} +0 -0
- /codex/static_root/assets/{VRadioGroup-i2qP9Wu9.css.gz → VRadioGroup-Cp9mZ7cb.css.gz} +0 -0
- /codex/static_root/assets/{VSelect-8MFoaOUz.6309f7bf17bb.css → VSelect-CP_CVb8s.6309f7bf17bb.css} +0 -0
- /codex/static_root/assets/{VSelect-8MFoaOUz.6309f7bf17bb.css.br → VSelect-CP_CVb8s.6309f7bf17bb.css.br} +0 -0
- /codex/static_root/assets/{VSelect-8MFoaOUz.6309f7bf17bb.css.gz → VSelect-CP_CVb8s.6309f7bf17bb.css.gz} +0 -0
- /codex/static_root/assets/{VSelect-8MFoaOUz.css → VSelect-CP_CVb8s.css} +0 -0
- /codex/static_root/assets/{VSelect-8MFoaOUz.css.br → VSelect-CP_CVb8s.css.br} +0 -0
- /codex/static_root/assets/{VSelect-8MFoaOUz.css.gz → VSelect-CP_CVb8s.css.gz} +0 -0
- /codex/static_root/assets/{VSelectionControl-DLxcLoTI.cc18de4e83f6.css → VSelectionControl-DPpfgCW2.cc18de4e83f6.css} +0 -0
- /codex/static_root/assets/{VSelectionControl-DLxcLoTI.cc18de4e83f6.css.br → VSelectionControl-DPpfgCW2.cc18de4e83f6.css.br} +0 -0
- /codex/static_root/assets/{VSelectionControl-DLxcLoTI.cc18de4e83f6.css.gz → VSelectionControl-DPpfgCW2.cc18de4e83f6.css.gz} +0 -0
- /codex/static_root/assets/{VSelectionControl-DLxcLoTI.css → VSelectionControl-DPpfgCW2.css} +0 -0
- /codex/static_root/assets/{VSelectionControl-DLxcLoTI.css.br → VSelectionControl-DPpfgCW2.css.br} +0 -0
- /codex/static_root/assets/{VSelectionControl-DLxcLoTI.css.gz → VSelectionControl-DPpfgCW2.css.gz} +0 -0
- /codex/static_root/assets/{VTable-Y5Sc3hJd.c36f0a6a30cf.css → VTable-BnxSZ_W5.c36f0a6a30cf.css} +0 -0
- /codex/static_root/assets/{VTable-Y5Sc3hJd.c36f0a6a30cf.css.br → VTable-BnxSZ_W5.c36f0a6a30cf.css.br} +0 -0
- /codex/static_root/assets/{VTable-Y5Sc3hJd.c36f0a6a30cf.css.gz → VTable-BnxSZ_W5.c36f0a6a30cf.css.gz} +0 -0
- /codex/static_root/assets/{VTable-Y5Sc3hJd.css → VTable-BnxSZ_W5.css} +0 -0
- /codex/static_root/assets/{VTable-Y5Sc3hJd.css.br → VTable-BnxSZ_W5.css.br} +0 -0
- /codex/static_root/assets/{VTable-Y5Sc3hJd.css.gz → VTable-BnxSZ_W5.css.gz} +0 -0
- /codex/static_root/assets/{VWindowItem-ByIod57Y.css → VWindowItem-CWBhiE_Y.css} +0 -0
- /codex/static_root/assets/{VWindowItem-ByIod57Y.css.br → VWindowItem-CWBhiE_Y.css.br} +0 -0
- /codex/static_root/assets/{VWindowItem-ByIod57Y.css.gz → VWindowItem-CWBhiE_Y.css.gz} +0 -0
- /codex/static_root/assets/{VWindowItem-ByIod57Y.f7fb19752bf3.css → VWindowItem-CWBhiE_Y.f7fb19752bf3.css} +0 -0
- /codex/static_root/assets/{VWindowItem-ByIod57Y.f7fb19752bf3.css.br → VWindowItem-CWBhiE_Y.f7fb19752bf3.css.br} +0 -0
- /codex/static_root/assets/{VWindowItem-ByIod57Y.f7fb19752bf3.css.gz → VWindowItem-CWBhiE_Y.f7fb19752bf3.css.gz} +0 -0
- /codex/static_root/assets/{admin-VRLEt4I5.06cb213f624d.css → admin-C3iCIUnm.06cb213f624d.css} +0 -0
- /codex/static_root/assets/{admin-VRLEt4I5.06cb213f624d.css.br → admin-C3iCIUnm.06cb213f624d.css.br} +0 -0
- /codex/static_root/assets/{admin-VRLEt4I5.06cb213f624d.css.gz → admin-C3iCIUnm.06cb213f624d.css.gz} +0 -0
- /codex/static_root/assets/{admin-VRLEt4I5.css → admin-C3iCIUnm.css} +0 -0
- /codex/static_root/assets/{admin-VRLEt4I5.css.br → admin-C3iCIUnm.css.br} +0 -0
- /codex/static_root/assets/{admin-VRLEt4I5.css.gz → admin-C3iCIUnm.css.gz} +0 -0
- /codex/static_root/assets/{admin-menu-B9bzD6hV.c13b7df2ff57.css → admin-menu-B3iXsOyy.c13b7df2ff57.css} +0 -0
- /codex/static_root/assets/{admin-menu-B9bzD6hV.c13b7df2ff57.css.br → admin-menu-B3iXsOyy.c13b7df2ff57.css.br} +0 -0
- /codex/static_root/assets/{admin-menu-B9bzD6hV.c13b7df2ff57.css.gz → admin-menu-B3iXsOyy.c13b7df2ff57.css.gz} +0 -0
- /codex/static_root/assets/{admin-menu-B9bzD6hV.css → admin-menu-B3iXsOyy.css} +0 -0
- /codex/static_root/assets/{admin-menu-B9bzD6hV.css.br → admin-menu-B3iXsOyy.css.br} +0 -0
- /codex/static_root/assets/{admin-menu-B9bzD6hV.css.gz → admin-menu-B3iXsOyy.css.gz} +0 -0
- /codex/static_root/assets/{admin-settings-button-progress-DUUQfVsZ.2548c49a853e.css → admin-settings-button-progress-BGB22oTD.2548c49a853e.css} +0 -0
- /codex/static_root/assets/{admin-settings-button-progress-DUUQfVsZ.css → admin-settings-button-progress-BGB22oTD.css} +0 -0
- /codex/static_root/assets/{change-password-dialog-C_EOKOn9.a30e68c6e303.css → change-password-dialog-D0ymWcl_.a30e68c6e303.css} +0 -0
- /codex/static_root/assets/{change-password-dialog-C_EOKOn9.a30e68c6e303.css.br → change-password-dialog-D0ymWcl_.a30e68c6e303.css.br} +0 -0
- /codex/static_root/assets/{change-password-dialog-C_EOKOn9.a30e68c6e303.css.gz → change-password-dialog-D0ymWcl_.a30e68c6e303.css.gz} +0 -0
- /codex/static_root/assets/{change-password-dialog-C_EOKOn9.css → change-password-dialog-D0ymWcl_.css} +0 -0
- /codex/static_root/assets/{change-password-dialog-C_EOKOn9.css.br → change-password-dialog-D0ymWcl_.css.br} +0 -0
- /codex/static_root/assets/{change-password-dialog-C_EOKOn9.css.gz → change-password-dialog-D0ymWcl_.css.gz} +0 -0
- /codex/static_root/assets/{confirm-dialog-54rblwf7.9b5915b112c0.css → confirm-dialog-B1ABbGMU.9b5915b112c0.css} +0 -0
- /codex/static_root/assets/{confirm-dialog-54rblwf7.9b5915b112c0.css.br → confirm-dialog-B1ABbGMU.9b5915b112c0.css.br} +0 -0
- /codex/static_root/assets/{confirm-dialog-54rblwf7.css → confirm-dialog-B1ABbGMU.css} +0 -0
- /codex/static_root/assets/{confirm-dialog-54rblwf7.css.br → confirm-dialog-B1ABbGMU.css.br} +0 -0
- /codex/static_root/assets/{datetime-column-DeCthByU.1f3bf499e063.css → datetime-column-BavtvLnf.1f3bf499e063.css} +0 -0
- /codex/static_root/assets/{datetime-column-DeCthByU.css → datetime-column-BavtvLnf.css} +0 -0
- /codex/static_root/assets/{forwardRefs-zKOZsbbr.9b56b4459240.css → forwardRefs-CFNX6kJ2.9b56b4459240.css} +0 -0
- /codex/static_root/assets/{forwardRefs-zKOZsbbr.9b56b4459240.css.br → forwardRefs-CFNX6kJ2.9b56b4459240.css.br} +0 -0
- /codex/static_root/assets/{forwardRefs-zKOZsbbr.9b56b4459240.css.gz → forwardRefs-CFNX6kJ2.9b56b4459240.css.gz} +0 -0
- /codex/static_root/assets/{forwardRefs-zKOZsbbr.css → forwardRefs-CFNX6kJ2.css} +0 -0
- /codex/static_root/assets/{forwardRefs-zKOZsbbr.css.br → forwardRefs-CFNX6kJ2.css.br} +0 -0
- /codex/static_root/assets/{forwardRefs-zKOZsbbr.css.gz → forwardRefs-CFNX6kJ2.css.gz} +0 -0
- /codex/static_root/assets/{group-tab-DkIN1Heu.948e907b1e6b.css → group-tab-_vKWzoyd.948e907b1e6b.css} +0 -0
- /codex/static_root/assets/{group-tab-DkIN1Heu.948e907b1e6b.css.br → group-tab-_vKWzoyd.948e907b1e6b.css.br} +0 -0
- /codex/static_root/assets/{group-tab-DkIN1Heu.948e907b1e6b.css.gz → group-tab-_vKWzoyd.948e907b1e6b.css.gz} +0 -0
- /codex/static_root/assets/{group-tab-DkIN1Heu.css → group-tab-_vKWzoyd.css} +0 -0
- /codex/static_root/assets/{group-tab-DkIN1Heu.css.br → group-tab-_vKWzoyd.css.br} +0 -0
- /codex/static_root/assets/{group-tab-DkIN1Heu.css.gz → group-tab-_vKWzoyd.css.gz} +0 -0
- /codex/static_root/assets/{http-error-DEJmFobt.8c13689ae574.css → http-error-CODU7jcH.8c13689ae574.css} +0 -0
- /codex/static_root/assets/{http-error-DEJmFobt.8c13689ae574.css.br → http-error-CODU7jcH.8c13689ae574.css.br} +0 -0
- /codex/static_root/assets/{http-error-DEJmFobt.8c13689ae574.css.gz → http-error-CODU7jcH.8c13689ae574.css.gz} +0 -0
- /codex/static_root/assets/{http-error-DEJmFobt.css → http-error-CODU7jcH.css} +0 -0
- /codex/static_root/assets/{http-error-DEJmFobt.css.br → http-error-CODU7jcH.css.br} +0 -0
- /codex/static_root/assets/{http-error-DEJmFobt.css.gz → http-error-CODU7jcH.css.gz} +0 -0
- /codex/static_root/assets/{index-CL_6g4tJ.523d7b3d350f.css → index-BHXJTQ4V.523d7b3d350f.css} +0 -0
- /codex/static_root/assets/{index-CL_6g4tJ.523d7b3d350f.css.br → index-BHXJTQ4V.523d7b3d350f.css.br} +0 -0
- /codex/static_root/assets/{index-CL_6g4tJ.523d7b3d350f.css.gz → index-BHXJTQ4V.523d7b3d350f.css.gz} +0 -0
- /codex/static_root/assets/{index-CL_6g4tJ.css → index-BHXJTQ4V.css} +0 -0
- /codex/static_root/assets/{index-CL_6g4tJ.css.br → index-BHXJTQ4V.css.br} +0 -0
- /codex/static_root/assets/{index-CL_6g4tJ.css.gz → index-BHXJTQ4V.css.gz} +0 -0
- /codex/static_root/assets/{library-tab-Ce6qaeCV.75baedb7e976.css → library-tab-CgsXOX_r.75baedb7e976.css} +0 -0
- /codex/static_root/assets/{library-tab-Ce6qaeCV.75baedb7e976.css.br → library-tab-CgsXOX_r.75baedb7e976.css.br} +0 -0
- /codex/static_root/assets/{library-tab-Ce6qaeCV.75baedb7e976.css.gz → library-tab-CgsXOX_r.75baedb7e976.css.gz} +0 -0
- /codex/static_root/assets/{library-tab-Ce6qaeCV.css → library-tab-CgsXOX_r.css} +0 -0
- /codex/static_root/assets/{library-tab-Ce6qaeCV.css.br → library-tab-CgsXOX_r.css.br} +0 -0
- /codex/static_root/assets/{library-tab-Ce6qaeCV.css.gz → library-tab-CgsXOX_r.css.gz} +0 -0
- /codex/static_root/assets/{main-BZ73p_WW.css → main-K8cER0IH.css} +0 -0
- /codex/static_root/assets/{main-BZ73p_WW.css.br → main-K8cER0IH.css.br} +0 -0
- /codex/static_root/assets/{main-BZ73p_WW.css.gz → main-K8cER0IH.css.gz} +0 -0
- /codex/static_root/assets/{main-BZ73p_WW.d529e8b3f52a.css → main-K8cER0IH.d529e8b3f52a.css} +0 -0
- /codex/static_root/assets/{main-BZ73p_WW.d529e8b3f52a.css.br → main-K8cER0IH.d529e8b3f52a.css.br} +0 -0
- /codex/static_root/assets/{main-BZ73p_WW.d529e8b3f52a.css.gz → main-K8cER0IH.d529e8b3f52a.css.gz} +0 -0
- /codex/static_root/assets/{pagination-toolbar-DSe0TkMm.css → pagination-toolbar-D5VQREy5.css} +0 -0
- /codex/static_root/assets/{pagination-toolbar-DSe0TkMm.css.br → pagination-toolbar-D5VQREy5.css.br} +0 -0
- /codex/static_root/assets/{pagination-toolbar-DSe0TkMm.css.gz → pagination-toolbar-D5VQREy5.css.gz} +0 -0
- /codex/static_root/assets/{pagination-toolbar-DSe0TkMm.dcb0eba65827.css → pagination-toolbar-D5VQREy5.dcb0eba65827.css} +0 -0
- /codex/static_root/assets/{pagination-toolbar-DSe0TkMm.dcb0eba65827.css.br → pagination-toolbar-D5VQREy5.dcb0eba65827.css.br} +0 -0
- /codex/static_root/assets/{pagination-toolbar-DSe0TkMm.dcb0eba65827.css.gz → pagination-toolbar-D5VQREy5.dcb0eba65827.css.gz} +0 -0
- /codex/static_root/assets/{pdf-doc-CG5-AZ2M.b94aac7e3313.css → pdf-doc-B4cGW_Hl.b94aac7e3313.css} +0 -0
- /codex/static_root/assets/{pdf-doc-CG5-AZ2M.b94aac7e3313.css.br → pdf-doc-B4cGW_Hl.b94aac7e3313.css.br} +0 -0
- /codex/static_root/assets/{pdf-doc-CG5-AZ2M.b94aac7e3313.css.gz → pdf-doc-B4cGW_Hl.b94aac7e3313.css.gz} +0 -0
- /codex/static_root/assets/{pdf-doc-CG5-AZ2M.css → pdf-doc-B4cGW_Hl.css} +0 -0
- /codex/static_root/assets/{pdf-doc-CG5-AZ2M.css.br → pdf-doc-B4cGW_Hl.css.br} +0 -0
- /codex/static_root/assets/{pdf-doc-CG5-AZ2M.css.gz → pdf-doc-B4cGW_Hl.css.gz} +0 -0
- /codex/static_root/assets/{reader-B3hgta6g.2ed32f08e906.css → reader-D_3ruSqa.2ed32f08e906.css} +0 -0
- /codex/static_root/assets/{reader-B3hgta6g.2ed32f08e906.css.br → reader-D_3ruSqa.2ed32f08e906.css.br} +0 -0
- /codex/static_root/assets/{reader-B3hgta6g.2ed32f08e906.css.gz → reader-D_3ruSqa.2ed32f08e906.css.gz} +0 -0
- /codex/static_root/assets/{reader-B3hgta6g.css → reader-D_3ruSqa.css} +0 -0
- /codex/static_root/assets/{reader-B3hgta6g.css.br → reader-D_3ruSqa.css.br} +0 -0
- /codex/static_root/assets/{reader-B3hgta6g.css.gz → reader-D_3ruSqa.css.gz} +0 -0
- /codex/static_root/assets/{relation-chips-ByfWwuQc.01269a188e01.css → relation-chips-DpbzrZxT.01269a188e01.css} +0 -0
- /codex/static_root/assets/{relation-chips-ByfWwuQc.01269a188e01.css.br → relation-chips-DpbzrZxT.01269a188e01.css.br} +0 -0
- /codex/static_root/assets/{relation-chips-ByfWwuQc.01269a188e01.css.gz → relation-chips-DpbzrZxT.01269a188e01.css.gz} +0 -0
- /codex/static_root/assets/{relation-chips-ByfWwuQc.css → relation-chips-DpbzrZxT.css} +0 -0
- /codex/static_root/assets/{relation-chips-ByfWwuQc.css.br → relation-chips-DpbzrZxT.css.br} +0 -0
- /codex/static_root/assets/{relation-chips-ByfWwuQc.css.gz → relation-chips-DpbzrZxT.css.gz} +0 -0
- /codex/static_root/assets/{settings-drawer-CqJ4gXLq.75a6ea969e71.css → settings-drawer-DMSsWF8c.75a6ea969e71.css} +0 -0
- /codex/static_root/assets/{settings-drawer-CqJ4gXLq.75a6ea969e71.css.br → settings-drawer-DMSsWF8c.75a6ea969e71.css.br} +0 -0
- /codex/static_root/assets/{settings-drawer-CqJ4gXLq.75a6ea969e71.css.gz → settings-drawer-DMSsWF8c.75a6ea969e71.css.gz} +0 -0
- /codex/static_root/assets/{settings-drawer-CqJ4gXLq.css → settings-drawer-DMSsWF8c.css} +0 -0
- /codex/static_root/assets/{settings-drawer-CqJ4gXLq.css.br → settings-drawer-DMSsWF8c.css.br} +0 -0
- /codex/static_root/assets/{settings-drawer-CqJ4gXLq.css.gz → settings-drawer-DMSsWF8c.css.gz} +0 -0
- /codex/static_root/assets/{stats-tab-BlXGStge.9fdb0106124d.css → stats-tab-WvF2acoZ.9fdb0106124d.css} +0 -0
- /codex/static_root/assets/{stats-tab-BlXGStge.9fdb0106124d.css.br → stats-tab-WvF2acoZ.9fdb0106124d.css.br} +0 -0
- /codex/static_root/assets/{stats-tab-BlXGStge.9fdb0106124d.css.gz → stats-tab-WvF2acoZ.9fdb0106124d.css.gz} +0 -0
- /codex/static_root/assets/{stats-tab-BlXGStge.css → stats-tab-WvF2acoZ.css} +0 -0
- /codex/static_root/assets/{stats-tab-BlXGStge.css.br → stats-tab-WvF2acoZ.css.br} +0 -0
- /codex/static_root/assets/{stats-tab-BlXGStge.css.gz → stats-tab-WvF2acoZ.css.gz} +0 -0
- /codex/static_root/assets/{task-tab-EGlhcKTH.478e74041f80.css → task-tab-DfdUY9Rc.478e74041f80.css} +0 -0
- /codex/static_root/assets/{task-tab-EGlhcKTH.478e74041f80.css.br → task-tab-DfdUY9Rc.478e74041f80.css.br} +0 -0
- /codex/static_root/assets/{task-tab-EGlhcKTH.478e74041f80.css.gz → task-tab-DfdUY9Rc.478e74041f80.css.gz} +0 -0
- /codex/static_root/assets/{task-tab-EGlhcKTH.css → task-tab-DfdUY9Rc.css} +0 -0
- /codex/static_root/assets/{task-tab-EGlhcKTH.css.br → task-tab-DfdUY9Rc.css.br} +0 -0
- /codex/static_root/assets/{task-tab-EGlhcKTH.css.gz → task-tab-DfdUY9Rc.css.gz} +0 -0
- /codex/static_root/assets/{unauthorized-VnIXUO1w.c5536d9dae75.css → unauthorized-CsSak07X.c5536d9dae75.css} +0 -0
- /codex/static_root/assets/{unauthorized-VnIXUO1w.c5536d9dae75.css.br → unauthorized-CsSak07X.c5536d9dae75.css.br} +0 -0
- /codex/static_root/assets/{unauthorized-VnIXUO1w.c5536d9dae75.css.gz → unauthorized-CsSak07X.c5536d9dae75.css.gz} +0 -0
- /codex/static_root/assets/{unauthorized-VnIXUO1w.css → unauthorized-CsSak07X.css} +0 -0
- /codex/static_root/assets/{unauthorized-VnIXUO1w.css.br → unauthorized-CsSak07X.css.br} +0 -0
- /codex/static_root/assets/{unauthorized-VnIXUO1w.css.gz → unauthorized-CsSak07X.css.gz} +0 -0
- {codex-1.7.3a1.dist-info → codex-1.7.4.dist-info}/LICENSE +0 -0
- {codex-1.7.3a1.dist-info → codex-1.7.4.dist-info}/entry_points.txt +0 -0
|
@@ -1,68 +1,40 @@
|
|
|
1
1
|
"""Browser Settings Filter Serializers."""
|
|
2
2
|
|
|
3
|
-
from rest_framework.serializers import
|
|
3
|
+
from rest_framework.serializers import ListField, Serializer
|
|
4
4
|
|
|
5
5
|
from codex.serializers.fields import (
|
|
6
|
-
BookmarkFilterField,
|
|
7
6
|
VuetifyBooleanField,
|
|
8
|
-
VuetifyCharField,
|
|
9
7
|
VuetifyDecadeField,
|
|
10
8
|
VuetifyFloatField,
|
|
11
9
|
VuetifyIntegerField,
|
|
12
10
|
)
|
|
11
|
+
from codex.serializers.fields.browser import BookmarkFilterField
|
|
13
12
|
|
|
14
13
|
|
|
15
|
-
class
|
|
16
|
-
"""All dynamic filters."""
|
|
17
|
-
|
|
18
|
-
age_rating = BooleanField(read_only=True)
|
|
19
|
-
community_rating = BooleanField(read_only=True)
|
|
20
|
-
characters = BooleanField(read_only=True)
|
|
21
|
-
country = BooleanField(read_only=True)
|
|
22
|
-
critical_rating = BooleanField(read_only=True)
|
|
23
|
-
contributors = BooleanField(read_only=True)
|
|
24
|
-
decade = BooleanField(read_only=True)
|
|
25
|
-
genres = BooleanField(read_only=True)
|
|
26
|
-
file_type = BooleanField(read_only=True)
|
|
27
|
-
identifier_type = BooleanField(read_only=True)
|
|
28
|
-
monochrome = BooleanField(read_only=True)
|
|
29
|
-
language = BooleanField(read_only=True)
|
|
30
|
-
locations = BooleanField(read_only=True)
|
|
31
|
-
original_format = BooleanField(read_only=True)
|
|
32
|
-
reading_direction = BooleanField(read_only=True)
|
|
33
|
-
series_groups = BooleanField(read_only=True)
|
|
34
|
-
stories = BooleanField(read_only=True)
|
|
35
|
-
story_arcs = BooleanField(read_only=True)
|
|
36
|
-
tagger = BooleanField(read_only=True)
|
|
37
|
-
tags = BooleanField(read_only=True)
|
|
38
|
-
teams = BooleanField(read_only=True)
|
|
39
|
-
year = BooleanField(read_only=True)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class BrowserSettingsFilterSerializer(Serializer):
|
|
14
|
+
class BrowserSettingsFilterInputSerializer(Serializer):
|
|
43
15
|
"""Filter values for settings."""
|
|
44
16
|
|
|
45
17
|
bookmark = BookmarkFilterField(required=False)
|
|
46
18
|
# Dynamic filters
|
|
47
|
-
age_rating = ListField(child=
|
|
19
|
+
age_rating = ListField(child=VuetifyIntegerField(), required=False)
|
|
48
20
|
characters = ListField(child=VuetifyIntegerField(), required=False)
|
|
49
21
|
community_rating = ListField(child=VuetifyFloatField(), required=False)
|
|
50
22
|
country = ListField(child=VuetifyIntegerField(), required=False)
|
|
51
23
|
contributors = ListField(child=VuetifyIntegerField(), required=False)
|
|
52
24
|
critical_rating = ListField(child=VuetifyFloatField(), required=False)
|
|
53
25
|
decade = ListField(child=VuetifyDecadeField(), required=False)
|
|
54
|
-
file_type = ListField(child=
|
|
26
|
+
file_type = ListField(child=VuetifyIntegerField(), required=False)
|
|
55
27
|
genres = ListField(child=VuetifyIntegerField(), required=False)
|
|
56
|
-
identifier_type = ListField(child=
|
|
28
|
+
identifier_type = ListField(child=VuetifyIntegerField(), required=False)
|
|
57
29
|
language = ListField(child=VuetifyIntegerField(), required=False)
|
|
58
30
|
locations = ListField(child=VuetifyIntegerField(), required=False)
|
|
59
31
|
monochrome = ListField(child=VuetifyBooleanField(), required=False)
|
|
60
|
-
original_format = ListField(child=
|
|
61
|
-
reading_direction = ListField(child=
|
|
32
|
+
original_format = ListField(child=VuetifyIntegerField(), required=False)
|
|
33
|
+
reading_direction = ListField(child=VuetifyIntegerField(), required=False)
|
|
62
34
|
series_groups = ListField(child=VuetifyIntegerField(), required=False)
|
|
63
35
|
stories = ListField(child=VuetifyIntegerField(), required=False)
|
|
64
36
|
story_arcs = ListField(child=VuetifyIntegerField(), required=False)
|
|
65
|
-
tagger = ListField(child=
|
|
37
|
+
tagger = ListField(child=VuetifyIntegerField(), required=False)
|
|
66
38
|
tags = ListField(child=VuetifyIntegerField(), required=False)
|
|
67
39
|
teams = ListField(child=VuetifyIntegerField(), required=False)
|
|
68
40
|
year = ListField(child=VuetifyIntegerField(), required=False)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Codex Serializers for the metadata box."""
|
|
2
2
|
|
|
3
|
-
from rest_framework.
|
|
3
|
+
from rest_framework.fields import CharField
|
|
4
|
+
from rest_framework.serializers import IntegerField, ListField, Serializer
|
|
4
5
|
|
|
5
6
|
from codex.serializers.browser.mixins import BrowserAggregateSerializerMixin
|
|
6
7
|
from codex.serializers.models.comic import ComicSerializer
|
|
@@ -5,7 +5,6 @@ from itertools import chain
|
|
|
5
5
|
|
|
6
6
|
from rest_framework.serializers import (
|
|
7
7
|
BooleanField,
|
|
8
|
-
CharField,
|
|
9
8
|
DecimalField,
|
|
10
9
|
IntegerField,
|
|
11
10
|
ListField,
|
|
@@ -14,6 +13,7 @@ from rest_framework.serializers import (
|
|
|
14
13
|
)
|
|
15
14
|
|
|
16
15
|
from codex.logger.logging import get_logger
|
|
16
|
+
from codex.serializers.fields.browser import TopGroupField
|
|
17
17
|
from codex.util import max_none
|
|
18
18
|
from codex.views.const import EPOCH_START
|
|
19
19
|
|
|
@@ -23,7 +23,7 @@ LOG = get_logger(__name__)
|
|
|
23
23
|
class BrowserAggregateSerializerMixin(Serializer):
|
|
24
24
|
"""Mixin for browser, opds & metadata serializers."""
|
|
25
25
|
|
|
26
|
-
group =
|
|
26
|
+
group = TopGroupField(read_only=True)
|
|
27
27
|
ids = ListField(child=IntegerField(), read_only=True)
|
|
28
28
|
|
|
29
29
|
# Aggregate Annotations
|
|
@@ -64,5 +64,9 @@ class BrowserAggregateSerializerMixin(Serializer):
|
|
|
64
64
|
)
|
|
65
65
|
mtime = self._get_max_updated_at(EPOCH_START, updated_ats)
|
|
66
66
|
if obj.bmua_is_max:
|
|
67
|
-
mtime: datetime = max_none(
|
|
67
|
+
mtime: datetime | None = max_none(
|
|
68
|
+
mtime, obj.bookmark_updated_at, EPOCH_START
|
|
69
|
+
)
|
|
70
|
+
if mtime is None:
|
|
71
|
+
return 0
|
|
68
72
|
return int(mtime.timestamp() * 1000)
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
"""Group Mtimes."""
|
|
2
2
|
|
|
3
|
-
from rest_framework.serializers import
|
|
3
|
+
from rest_framework.serializers import Serializer
|
|
4
4
|
|
|
5
|
-
from codex.serializers.browser.settings import
|
|
5
|
+
from codex.serializers.browser.settings import BrowserFilterChoicesInputSerilalizer
|
|
6
6
|
from codex.serializers.fields import TimestampField
|
|
7
7
|
from codex.serializers.route import SimpleRouteSerializer
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
class GroupsMtimeSerializer(
|
|
10
|
+
class GroupsMtimeSerializer(BrowserFilterChoicesInputSerilalizer):
|
|
11
11
|
"""Groups Mtimes."""
|
|
12
12
|
|
|
13
|
-
filters = BrowserSettingsFilterSerializer(required=False)
|
|
14
|
-
q = CharField(allow_blank=True, required=False)
|
|
15
13
|
groups = SimpleRouteSerializer(many=True, required=True)
|
|
16
14
|
|
|
17
15
|
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
"""Browser Page Serializer."""
|
|
2
2
|
|
|
3
|
-
from rest_framework.
|
|
3
|
+
from rest_framework.fields import (
|
|
4
4
|
BooleanField,
|
|
5
5
|
CharField,
|
|
6
6
|
DecimalField,
|
|
7
7
|
IntegerField,
|
|
8
|
-
Serializer,
|
|
9
8
|
)
|
|
9
|
+
from rest_framework.serializers import Serializer
|
|
10
10
|
|
|
11
11
|
from codex.serializers.browser.mixins import (
|
|
12
12
|
BrowserAggregateSerializerMixin,
|
|
13
13
|
)
|
|
14
|
-
from codex.serializers.fields import
|
|
14
|
+
from codex.serializers.fields import TimestampField
|
|
15
|
+
from codex.serializers.fields.browser import BreadcrumbsField, TopGroupField
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class BrowserCardSerializer(BrowserAggregateSerializerMixin):
|
|
@@ -57,7 +58,7 @@ class BrowserPageSerializer(Serializer):
|
|
|
57
58
|
title = BrowserTitleSerializer(read_only=True)
|
|
58
59
|
zero_pad = IntegerField(read_only=True)
|
|
59
60
|
libraries_exist = BooleanField(read_only=True)
|
|
60
|
-
model_group =
|
|
61
|
+
model_group = TopGroupField(read_only=True)
|
|
61
62
|
num_pages = IntegerField(read_only=True)
|
|
62
63
|
groups = BrowserCardSerializer(allow_empty=True, read_only=True, many=True)
|
|
63
64
|
books = BrowserCardSerializer(allow_empty=True, read_only=True, many=True)
|
|
@@ -9,8 +9,9 @@ from rest_framework.serializers import (
|
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
from codex.choices import BROWSER_ORDER_BY_CHOICES
|
|
12
|
-
from codex.serializers.browser.filters import
|
|
13
|
-
from codex.serializers.fields import
|
|
12
|
+
from codex.serializers.browser.filters import BrowserSettingsFilterInputSerializer
|
|
13
|
+
from codex.serializers.fields import TimestampField
|
|
14
|
+
from codex.serializers.fields.browser import BreadcrumbsField, TopGroupField
|
|
14
15
|
from codex.serializers.route import SimpleRouteSerializer
|
|
15
16
|
|
|
16
17
|
|
|
@@ -26,7 +27,8 @@ class BrowserSettingsShowGroupFlagsSerializer(Serializer):
|
|
|
26
27
|
class BrowserFilterChoicesInputSerilalizer(Serializer):
|
|
27
28
|
"""Browser Settings for the filter choices response."""
|
|
28
29
|
|
|
29
|
-
filters =
|
|
30
|
+
filters = BrowserSettingsFilterInputSerializer(required=False)
|
|
31
|
+
# NOT Sanitized because so complex.
|
|
30
32
|
q = CharField(allow_blank=True, required=False)
|
|
31
33
|
|
|
32
34
|
|
|
@@ -51,7 +53,6 @@ class BrowserCoverInputSerializer(BrowserCoverInputSerializerBase):
|
|
|
51
53
|
class BrowserSettingsSerializerBase(BrowserCoverInputSerializerBase):
|
|
52
54
|
"""Base Serializer for Browser & OPDS Settings."""
|
|
53
55
|
|
|
54
|
-
# search_results_limit = IntegerField(required=False)
|
|
55
56
|
top_group = TopGroupField(required=False)
|
|
56
57
|
|
|
57
58
|
|
|
@@ -64,7 +65,8 @@ class OPDSSettingsSerializer(BrowserSettingsSerializerBase):
|
|
|
64
65
|
|
|
65
66
|
|
|
66
67
|
class BrowserSettingsSerializer(BrowserSettingsSerializerBase):
|
|
67
|
-
"""
|
|
68
|
+
"""
|
|
69
|
+
Browser Settings that the user can change.
|
|
68
70
|
|
|
69
71
|
This is the only browse serializer that's submitted.
|
|
70
72
|
"""
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Custom Serializer Fields."""
|
|
2
|
+
|
|
3
|
+
from codex.serializers.fields.auth import TimestampField, TimezoneField
|
|
4
|
+
from codex.serializers.fields.group import BrowseGroupField
|
|
5
|
+
from codex.serializers.fields.reader import FitToField, ReadingDirectionField
|
|
6
|
+
from codex.serializers.fields.sanitized import SanitizedCharField
|
|
7
|
+
from codex.serializers.fields.session import SessionKeyField
|
|
8
|
+
from codex.serializers.fields.stats import (
|
|
9
|
+
CountDictField,
|
|
10
|
+
SerializerChoicesField,
|
|
11
|
+
StringListMultipleChoiceField,
|
|
12
|
+
)
|
|
13
|
+
from codex.serializers.fields.vuetify import (
|
|
14
|
+
VuetifyBooleanField,
|
|
15
|
+
VuetifyCharField,
|
|
16
|
+
VuetifyDecadeField,
|
|
17
|
+
VuetifyFloatField,
|
|
18
|
+
VuetifyIntegerField,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
__all__ = (
|
|
22
|
+
"TimestampField",
|
|
23
|
+
"TimezoneField",
|
|
24
|
+
"BrowseGroupField",
|
|
25
|
+
"SanitizedCharField",
|
|
26
|
+
"StringListMultipleChoiceField",
|
|
27
|
+
"SerializerChoicesField",
|
|
28
|
+
"CountDictField",
|
|
29
|
+
"VuetifyFloatField",
|
|
30
|
+
"VuetifyIntegerField",
|
|
31
|
+
"VuetifyCharField",
|
|
32
|
+
"VuetifyBooleanField",
|
|
33
|
+
"VuetifyDecadeField",
|
|
34
|
+
"FitToField",
|
|
35
|
+
"ReadingDirectionField",
|
|
36
|
+
"SessionKeyField",
|
|
37
|
+
)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Custom fields."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
|
+
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
|
5
|
+
|
|
6
|
+
from rest_framework.exceptions import ValidationError
|
|
7
|
+
from rest_framework.serializers import (
|
|
8
|
+
CharField,
|
|
9
|
+
IntegerField,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from codex.logger.logging import get_logger
|
|
13
|
+
|
|
14
|
+
LOG = get_logger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TimestampField(IntegerField):
|
|
18
|
+
"""IntegerTimestampField."""
|
|
19
|
+
|
|
20
|
+
def to_representation(self, value) -> int:
|
|
21
|
+
"""Convert to Jascript millisecond int timestamp from datetime, or castable."""
|
|
22
|
+
if isinstance(value, datetime):
|
|
23
|
+
value = value.timestamp()
|
|
24
|
+
return int(float(value) * 1000)
|
|
25
|
+
|
|
26
|
+
def to_internal_value(self, data) -> datetime: # type: ignore[reportIncompatibleMethodOverride]
|
|
27
|
+
"""Convert from castable, likely string to datetime."""
|
|
28
|
+
return datetime.fromtimestamp(float(data) / 1000, tz=timezone.utc)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def validate_timezone(data):
|
|
32
|
+
"""Validate Timezone."""
|
|
33
|
+
try:
|
|
34
|
+
ZoneInfo(data)
|
|
35
|
+
except ZoneInfoNotFoundError as exc:
|
|
36
|
+
raise ValidationError from exc
|
|
37
|
+
return data
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class TimezoneField(CharField):
|
|
41
|
+
"""Timezone field."""
|
|
42
|
+
|
|
43
|
+
def __init__(self, *args, **kwargs):
|
|
44
|
+
"""Call Charfield with defaults."""
|
|
45
|
+
super().__init__(*args, min_length=2, validators=[validate_timezone], **kwargs)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Custom fields."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC
|
|
4
|
+
|
|
5
|
+
import pycountry
|
|
6
|
+
from rest_framework.serializers import (
|
|
7
|
+
ChoiceField,
|
|
8
|
+
ListField,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from codex.choices import (
|
|
12
|
+
BROWSER_BOOKMARK_FILTER_CHOICES,
|
|
13
|
+
BROWSER_TOP_GROUP_CHOICES,
|
|
14
|
+
DUMMY_NULL_NAME,
|
|
15
|
+
)
|
|
16
|
+
from codex.logger.logging import get_logger
|
|
17
|
+
from codex.serializers.fields.sanitized import SanitizedCharField
|
|
18
|
+
from codex.serializers.route import RouteSerializer
|
|
19
|
+
|
|
20
|
+
LOG = get_logger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class TopGroupField(ChoiceField):
|
|
24
|
+
"""Valid Top Groups Only."""
|
|
25
|
+
|
|
26
|
+
class_choices = tuple(BROWSER_TOP_GROUP_CHOICES.keys())
|
|
27
|
+
|
|
28
|
+
def __init__(self, *args, **kwargs):
|
|
29
|
+
"""Initialize with choices."""
|
|
30
|
+
super().__init__(*args, choices=self.class_choices, **kwargs)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class BookmarkFilterField(ChoiceField):
|
|
34
|
+
"""Bookmark Choice Field."""
|
|
35
|
+
|
|
36
|
+
def __init__(self, *args, **kwargs):
|
|
37
|
+
"""Use bookmark filter choices."""
|
|
38
|
+
super().__init__(
|
|
39
|
+
*args, choices=tuple(BROWSER_BOOKMARK_FILTER_CHOICES.keys()), **kwargs
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class PyCountryField(SanitizedCharField, ABC):
|
|
44
|
+
"""Serialize to a long pycountry name."""
|
|
45
|
+
|
|
46
|
+
LOOKUP_MODULE = pycountry.countries
|
|
47
|
+
_ALPHA_2_LEN = 2
|
|
48
|
+
|
|
49
|
+
def to_representation(self, value):
|
|
50
|
+
"""Lookup the name with pycountry, just copy the value on fail."""
|
|
51
|
+
if not value:
|
|
52
|
+
return ""
|
|
53
|
+
if value == DUMMY_NULL_NAME:
|
|
54
|
+
return value
|
|
55
|
+
try:
|
|
56
|
+
# fix for https://github.com/flyingcircusio/pycountry/issues/41
|
|
57
|
+
lookup_obj = (
|
|
58
|
+
self.LOOKUP_MODULE.get(alpha_2=value)
|
|
59
|
+
if len(value) == self._ALPHA_2_LEN
|
|
60
|
+
else self.LOOKUP_MODULE.lookup(value)
|
|
61
|
+
)
|
|
62
|
+
# If lookup fails, return the key as the name
|
|
63
|
+
except Exception:
|
|
64
|
+
LOG.warning(f"Could not serialize name with pycountry {value}")
|
|
65
|
+
return value
|
|
66
|
+
else:
|
|
67
|
+
return lookup_obj.name if lookup_obj else value
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class CountryField(PyCountryField):
|
|
71
|
+
"""Serializer to long country name."""
|
|
72
|
+
|
|
73
|
+
LOOKUP_MODULE = pycountry.countries
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class LanguageField(PyCountryField):
|
|
77
|
+
"""Serializer to long language name."""
|
|
78
|
+
|
|
79
|
+
LOOKUP_MODULE = pycountry.languages
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class BreadcrumbsField(ListField):
|
|
83
|
+
"""And Array of Routes."""
|
|
84
|
+
|
|
85
|
+
child = RouteSerializer()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Browser Group Field."""
|
|
2
|
+
|
|
3
|
+
from rest_framework.fields import ChoiceField
|
|
4
|
+
|
|
5
|
+
from codex.choices import BROWSER_GROUP_CHOICES
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BrowseGroupField(ChoiceField):
|
|
9
|
+
"""BrowseGroup Field."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, *args, **kwargs):
|
|
12
|
+
"""Add choices."""
|
|
13
|
+
super().__init__(*args, choices=tuple(BROWSER_GROUP_CHOICES.keys()), **kwargs)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Reader Fields."""
|
|
2
|
+
|
|
3
|
+
from rest_framework.serializers import ChoiceField
|
|
4
|
+
|
|
5
|
+
from codex.models import Bookmark
|
|
6
|
+
from codex.models.comic import ReadingDirection
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FitToField(ChoiceField):
|
|
10
|
+
"""Bookmark FitTo Fieild."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, *args, **kwargs):
|
|
13
|
+
"""Add Choices."""
|
|
14
|
+
super().__init__(*args, choices=Bookmark.FitTo.values, **kwargs)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ReadingDirectionField(ChoiceField):
|
|
18
|
+
"""Reading Direction Field."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, *args, **kwargs):
|
|
21
|
+
"""Add Choices."""
|
|
22
|
+
super().__init__(*args, choices=ReadingDirection.values, **kwargs)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Sanitied Fields."""
|
|
2
|
+
|
|
3
|
+
from nh3 import clean
|
|
4
|
+
from rest_framework.fields import CharField
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SanitizedCharField(CharField):
|
|
8
|
+
"""Sanitize CharField using NH3."""
|
|
9
|
+
|
|
10
|
+
def to_internal_value(self, data):
|
|
11
|
+
"""Sanitize CharField using NH3."""
|
|
12
|
+
sanitized_data = clean(data)
|
|
13
|
+
return super().to_internal_value(sanitized_data)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Session Custom Fields."""
|
|
2
|
+
|
|
3
|
+
from rest_framework.fields import ChoiceField
|
|
4
|
+
|
|
5
|
+
from codex.choices import BROWSER_DEFAULTS, READER_DEFAULTS
|
|
6
|
+
|
|
7
|
+
_SESSION_KEYS = (*READER_DEFAULTS.keys(), *BROWSER_DEFAULTS.keys(), "filters")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SessionKeyField(ChoiceField):
|
|
11
|
+
"""Session Key Field."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, *args, **kwargs):
|
|
14
|
+
"""Add choices."""
|
|
15
|
+
super().__init__(*args, choices=_SESSION_KEYS, **kwargs)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Custom Vuetify fields."""
|
|
2
|
+
|
|
3
|
+
from rest_framework.fields import DictField, IntegerField
|
|
4
|
+
from rest_framework.serializers import MultipleChoiceField
|
|
5
|
+
|
|
6
|
+
from codex.logger.logging import get_logger
|
|
7
|
+
|
|
8
|
+
LOG = get_logger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class StringListMultipleChoiceField(MultipleChoiceField):
|
|
12
|
+
"""A Multiple Choice Field expressed as as a comma delimited string."""
|
|
13
|
+
|
|
14
|
+
def to_internal_value(self, data):
|
|
15
|
+
"""Convert comma delimited strings to sets."""
|
|
16
|
+
if isinstance(data, str):
|
|
17
|
+
data = frozenset(data.split(","))
|
|
18
|
+
return super().to_internal_value(data) # type: ignore[reportIncompatibleMethodOverride]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SerializerChoicesField(StringListMultipleChoiceField):
|
|
22
|
+
"""A String List Multiple Choice Field limited to a specified serializer's fields."""
|
|
23
|
+
|
|
24
|
+
def __init__(self, *args, serializer=None, **kwargs):
|
|
25
|
+
"""Limit choices to fields from serializers."""
|
|
26
|
+
if not serializer:
|
|
27
|
+
reason = "serializer required for this field."
|
|
28
|
+
raise ValueError(reason)
|
|
29
|
+
choices = serializer().get_fields().keys()
|
|
30
|
+
super().__init__(*args, choices=choices, **kwargs)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class CountDictField(DictField):
|
|
34
|
+
"""Dict for counting things."""
|
|
35
|
+
|
|
36
|
+
child = IntegerField(read_only=True)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Custom Vuetify fields."""
|
|
2
|
+
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
4
|
+
from rest_framework.exceptions import ValidationError
|
|
5
|
+
from rest_framework.serializers import (
|
|
6
|
+
BooleanField,
|
|
7
|
+
CharField,
|
|
8
|
+
FloatField,
|
|
9
|
+
IntegerField,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from codex.choices import VUETIFY_NULL_CODE
|
|
13
|
+
from codex.logger.logging import get_logger
|
|
14
|
+
|
|
15
|
+
LOG = get_logger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class VuetifyNullCodeFieldMixin:
|
|
19
|
+
"""Convert Vuetify null codes to None."""
|
|
20
|
+
|
|
21
|
+
NULL_CODE = VUETIFY_NULL_CODE
|
|
22
|
+
|
|
23
|
+
def to_internal_value(self, data):
|
|
24
|
+
"""Convert numeric null code to None."""
|
|
25
|
+
return None if data == self.NULL_CODE else data
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class VuetifyFloatField(VuetifyNullCodeFieldMixin, FloatField): # type: ignore[reportIncompatibleMethodOverride]
|
|
29
|
+
"""Float Field with null code conversion."""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class VuetifyIntegerField(VuetifyNullCodeFieldMixin, IntegerField): # type: ignore[reportIncompatibleMethodOverride]
|
|
33
|
+
"""Integer Field with null code conversion."""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class VuetifyCharField(VuetifyNullCodeFieldMixin, CharField): # type: ignore[reportIncompatibleMethodOverride]
|
|
37
|
+
"""Char Field with null code conversion."""
|
|
38
|
+
|
|
39
|
+
NULL_CODE = str(VUETIFY_NULL_CODE)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class VuetifyBooleanField(VuetifyNullCodeFieldMixin, BooleanField): # type: ignore[reportIncompatibleMethodOverride]
|
|
43
|
+
"""Boolean Field with null code conversion."""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def validate_decade(decade):
|
|
47
|
+
"""Validate decades."""
|
|
48
|
+
# * We don't need a whole db call just to be perfectly accurate
|
|
49
|
+
# * -1s are decoded back into None before validation
|
|
50
|
+
if decade is not None and decade % 10 != 0:
|
|
51
|
+
raise ValidationError(_("Invalid decade: ") + f"{decade}")
|
|
52
|
+
return True
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class VuetifyDecadeField(VuetifyIntegerField):
|
|
56
|
+
"""Integer field with null code conversion and decade validation."""
|
|
57
|
+
|
|
58
|
+
VALIDATORS = (validate_decade,)
|
|
59
|
+
|
|
60
|
+
def __init__(self, *args, **kwargs):
|
|
61
|
+
"""Use decade validator."""
|
|
62
|
+
super().__init__(*args, validators=self.VALIDATORS, **kwargs)
|
codex/serializers/models/base.py
CHANGED
|
@@ -6,7 +6,7 @@ from rest_framework.serializers import ModelSerializer, SerializerMetaclass
|
|
|
6
6
|
class BaseModelSerializer(ModelSerializer):
|
|
7
7
|
"""BaseModel Serializer for inheritance."""
|
|
8
8
|
|
|
9
|
-
class Meta(SerializerMetaclass): # type: ignore
|
|
9
|
+
class Meta(SerializerMetaclass): # type: ignore[reportIncompatibleVariableOverride]
|
|
10
10
|
"""Use explicit metaclass instead of python 3 method."""
|
|
11
11
|
|
|
12
12
|
abstract = True
|
|
@@ -38,8 +38,8 @@ class ComicSerializer(BaseModelSerializer):
|
|
|
38
38
|
pk = IntegerField(source="id")
|
|
39
39
|
|
|
40
40
|
# Annotations
|
|
41
|
-
# issue_count = IntegerField(allow_null=True)
|
|
42
|
-
# volume_count = IntegerField(allow_null=True)
|
|
41
|
+
# issue_count = IntegerField(allow_null=True) could be 1
|
|
42
|
+
# volume_count = IntegerField(allow_null=True) could be 1
|
|
43
43
|
|
|
44
44
|
# Group FKs
|
|
45
45
|
publisher = PublisherSerializer(allow_null=True)
|
|
@@ -43,7 +43,6 @@ class SeriesSerializer(GroupModelSerializer):
|
|
|
43
43
|
"""Configure model."""
|
|
44
44
|
|
|
45
45
|
model = Series
|
|
46
|
-
# fields = (*NamedModelMeta.fields, "volume_count")
|
|
47
46
|
|
|
48
47
|
|
|
49
48
|
class VolumeSerializer(GroupModelSerializer):
|
|
@@ -53,4 +52,3 @@ class VolumeSerializer(GroupModelSerializer):
|
|
|
53
52
|
"""Configure model."""
|
|
54
53
|
|
|
55
54
|
model = Volume
|
|
56
|
-
# fields = (*NamedModelMeta.fields, "issue_count")
|
|
@@ -5,7 +5,7 @@ from codex.models import (
|
|
|
5
5
|
Country,
|
|
6
6
|
Language,
|
|
7
7
|
)
|
|
8
|
-
from codex.serializers.fields import CountryField, LanguageField
|
|
8
|
+
from codex.serializers.fields.browser import CountryField, LanguageField
|
|
9
9
|
from codex.serializers.models.named import NamedModelSerializer
|
|
10
10
|
|
|
11
11
|
LOG = get_logger(__name__)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
OPDS Authentication 1.0 Serializer.
|
|
2
3
|
|
|
3
4
|
https://drafts.opds.io/schema/authentication.schema.json
|
|
4
5
|
"""
|
|
5
6
|
|
|
6
|
-
from rest_framework.
|
|
7
|
+
from rest_framework.fields import CharField
|
|
8
|
+
from rest_framework.serializers import IntegerField, Serializer
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
class OPDSAuth1LinksSerializer(Serializer):
|
codex/serializers/opds/urls.py
CHANGED
codex/serializers/opds/v1.py
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
from zoneinfo import ZoneInfo
|
|
4
4
|
|
|
5
|
-
from rest_framework.
|
|
5
|
+
from rest_framework.fields import (
|
|
6
6
|
BooleanField,
|
|
7
7
|
CharField,
|
|
8
8
|
DateField,
|
|
9
9
|
DateTimeField,
|
|
10
10
|
DictField,
|
|
11
11
|
IntegerField,
|
|
12
|
-
Serializer,
|
|
13
12
|
)
|
|
13
|
+
from rest_framework.serializers import Serializer
|
|
14
14
|
|
|
15
|
+
from codex.serializers.fields.browser import TopGroupField
|
|
15
16
|
from codex.serializers.models.pycountry import LanguageSerializer
|
|
16
17
|
|
|
17
18
|
UTC_TZ = ZoneInfo("UTC")
|
|
@@ -25,7 +26,7 @@ class OPDS1TemplateLinkSerializer(Serializer):
|
|
|
25
26
|
mime_type = CharField(read_only=True)
|
|
26
27
|
title = CharField(read_only=True, required=False)
|
|
27
28
|
length = IntegerField(read_only=True, required=False)
|
|
28
|
-
facet_group =
|
|
29
|
+
facet_group = TopGroupField(read_only=True, required=False)
|
|
29
30
|
facet_active = BooleanField(read_only=True, required=False)
|
|
30
31
|
thr_count = IntegerField(read_only=True, required=False)
|
|
31
32
|
pse_count = IntegerField(read_only=True, required=False)
|