codex 1.6.19__py3-none-any.whl → 1.7.0__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.

Files changed (842) hide show
  1. codex/choices.py +419 -0
  2. codex/choices_to_json.py +122 -0
  3. codex/db.py +134 -0
  4. codex/exceptions.py +2 -3
  5. codex/librarian/bookmark/__init__.py +1 -0
  6. codex/librarian/bookmark/bookmarkd.py +38 -0
  7. codex/librarian/bookmark/tasks.py +19 -0
  8. codex/librarian/bookmark/update.py +154 -0
  9. codex/librarian/covers/coverd.py +3 -4
  10. codex/librarian/covers/create.py +8 -7
  11. codex/librarian/covers/path.py +1 -2
  12. codex/librarian/covers/purge.py +3 -3
  13. codex/librarian/importer/const.py +7 -1
  14. codex/librarian/importer/create_fks.py +5 -2
  15. codex/librarian/importer/importerd.py +17 -12
  16. codex/librarian/importer/moved.py +44 -13
  17. codex/librarian/importer/tasks.py +2 -0
  18. codex/librarian/janitor/cleanup.py +21 -8
  19. codex/librarian/janitor/integrity.py +371 -0
  20. codex/librarian/janitor/janitor.py +50 -15
  21. codex/librarian/janitor/latest_version.py +2 -1
  22. codex/librarian/janitor/status.py +5 -0
  23. codex/librarian/janitor/tasks.py +37 -0
  24. codex/librarian/janitor/update.py +1 -1
  25. codex/librarian/librariand.py +37 -24
  26. codex/librarian/search/optimize.py +43 -0
  27. codex/librarian/search/remove.py +18 -46
  28. codex/librarian/search/searchd.py +14 -17
  29. codex/librarian/search/status.py +2 -1
  30. codex/librarian/search/tasks.py +4 -9
  31. codex/librarian/search/update.py +223 -301
  32. codex/librarian/watchdog/emitter.py +21 -19
  33. codex/librarian/watchdog/event_batcherd.py +0 -1
  34. codex/librarian/watchdog/observers.py +2 -1
  35. codex/migrations/0029_comicfts.py +58 -0
  36. codex/migrations/0030_nocase_collation_day_month_indexes_status_types.py +202 -0
  37. codex/models/admin.py +15 -11
  38. codex/models/base.py +9 -0
  39. codex/models/bookmark.py +3 -3
  40. codex/models/comic.py +68 -16
  41. codex/models/functions.py +60 -2
  42. codex/models/groups.py +6 -1
  43. codex/models/library.py +1 -3
  44. codex/models/paths.py +9 -3
  45. codex/models/query.py +6 -0
  46. codex/run.py +11 -9
  47. codex/serializers/admin/tasks.py +2 -2
  48. codex/serializers/browser/mixins.py +18 -14
  49. codex/serializers/browser/page.py +2 -0
  50. codex/serializers/browser/settings.py +4 -4
  51. codex/serializers/fields.py +9 -5
  52. codex/settings/settings.py +16 -17
  53. codex/signals/django_signals.py +4 -10
  54. codex/startup.py +7 -39
  55. codex/static_root/assets/VCheckbox-D_CWEmqR.84f2b49311e8.js +1 -0
  56. codex/static_root/assets/VCheckbox-D_CWEmqR.84f2b49311e8.js.br +0 -0
  57. codex/static_root/assets/VCheckbox-D_CWEmqR.84f2b49311e8.js.gz +0 -0
  58. codex/static_root/assets/VCheckbox-D_CWEmqR.js +1 -0
  59. codex/static_root/assets/VCheckbox-D_CWEmqR.js.br +0 -0
  60. codex/static_root/assets/VCheckbox-D_CWEmqR.js.gz +0 -0
  61. codex/static_root/assets/VCheckboxBtn-B1BhcFvi.0eaf3c516474.js +1 -0
  62. codex/static_root/assets/VCheckboxBtn-B1BhcFvi.0eaf3c516474.js.br +0 -0
  63. codex/static_root/assets/VCheckboxBtn-B1BhcFvi.0eaf3c516474.js.gz +0 -0
  64. codex/static_root/assets/VCheckboxBtn-B1BhcFvi.js +1 -0
  65. codex/static_root/assets/VCheckboxBtn-B1BhcFvi.js.br +0 -0
  66. codex/static_root/assets/VCheckboxBtn-B1BhcFvi.js.gz +0 -0
  67. codex/static_root/assets/VCombobox-CZAW6_3Q.0e2401e819a5.js +1 -0
  68. codex/static_root/assets/VCombobox-CZAW6_3Q.0e2401e819a5.js.br +0 -0
  69. codex/static_root/assets/VCombobox-CZAW6_3Q.0e2401e819a5.js.gz +0 -0
  70. codex/static_root/assets/VCombobox-CZAW6_3Q.js +1 -0
  71. codex/static_root/assets/VCombobox-CZAW6_3Q.js.br +0 -0
  72. codex/static_root/assets/VCombobox-CZAW6_3Q.js.gz +0 -0
  73. codex/static_root/assets/VDialog-CSHgHIlG.a0bcd336cb7b.js +1 -0
  74. codex/static_root/assets/VDialog-CSHgHIlG.a0bcd336cb7b.js.br +0 -0
  75. codex/static_root/assets/VDialog-CSHgHIlG.a0bcd336cb7b.js.gz +0 -0
  76. codex/static_root/assets/VDialog-CSHgHIlG.js +1 -0
  77. codex/static_root/assets/VDialog-CSHgHIlG.js.br +0 -0
  78. codex/static_root/assets/VDialog-CSHgHIlG.js.gz +0 -0
  79. codex/static_root/assets/VDialog-CSvrKKb2.css +1 -0
  80. codex/static_root/assets/VDialog-CSvrKKb2.css.br +0 -0
  81. codex/static_root/assets/VDialog-CSvrKKb2.css.gz +0 -0
  82. codex/static_root/assets/VDialog-CSvrKKb2.fd4d50904b17.css +1 -0
  83. codex/static_root/assets/VDialog-CSvrKKb2.fd4d50904b17.css.br +0 -0
  84. codex/static_root/assets/VDialog-CSvrKKb2.fd4d50904b17.css.gz +0 -0
  85. codex/static_root/assets/VExpansionPanels-CG6MpdMC.e96ae8afad97.js +1 -0
  86. codex/static_root/assets/VExpansionPanels-CG6MpdMC.e96ae8afad97.js.br +0 -0
  87. codex/static_root/assets/VExpansionPanels-CG6MpdMC.e96ae8afad97.js.gz +0 -0
  88. codex/static_root/assets/VExpansionPanels-CG6MpdMC.js +1 -0
  89. codex/static_root/assets/VExpansionPanels-CG6MpdMC.js.br +0 -0
  90. codex/static_root/assets/VExpansionPanels-CG6MpdMC.js.gz +0 -0
  91. codex/static_root/assets/VRadioGroup-CAgQxkiU.f26ecb0c3e34.js +1 -0
  92. codex/static_root/assets/VRadioGroup-CAgQxkiU.f26ecb0c3e34.js.br +0 -0
  93. codex/static_root/assets/VRadioGroup-CAgQxkiU.f26ecb0c3e34.js.gz +0 -0
  94. codex/static_root/assets/VRadioGroup-CAgQxkiU.js +1 -0
  95. codex/static_root/assets/VRadioGroup-CAgQxkiU.js.br +0 -0
  96. codex/static_root/assets/VRadioGroup-CAgQxkiU.js.gz +0 -0
  97. codex/static_root/assets/VSelect-C1gez8rl.9b11d2f00faf.js +1 -0
  98. codex/static_root/assets/VSelect-C1gez8rl.9b11d2f00faf.js.br +0 -0
  99. codex/static_root/assets/VSelect-C1gez8rl.9b11d2f00faf.js.gz +0 -0
  100. codex/static_root/assets/VSelect-C1gez8rl.js +1 -0
  101. codex/static_root/assets/VSelect-C1gez8rl.js.br +0 -0
  102. codex/static_root/assets/VSelect-C1gez8rl.js.gz +0 -0
  103. codex/static_root/assets/VSelect-DLu8bpcs.98bdcf35411c.css +1 -0
  104. codex/static_root/assets/VSelect-DLu8bpcs.98bdcf35411c.css.br +0 -0
  105. codex/static_root/assets/VSelect-DLu8bpcs.98bdcf35411c.css.gz +0 -0
  106. codex/static_root/assets/VSelect-DLu8bpcs.css +1 -0
  107. codex/static_root/assets/VSelect-DLu8bpcs.css.br +0 -0
  108. codex/static_root/assets/VSelect-DLu8bpcs.css.gz +0 -0
  109. codex/static_root/assets/VSelectionControl-DBqDlKjK.160beaa1b56c.js +1 -0
  110. codex/static_root/assets/VSelectionControl-DBqDlKjK.160beaa1b56c.js.br +0 -0
  111. codex/static_root/assets/VSelectionControl-DBqDlKjK.160beaa1b56c.js.gz +0 -0
  112. codex/static_root/assets/VSelectionControl-DBqDlKjK.js +1 -0
  113. codex/static_root/assets/VSelectionControl-DBqDlKjK.js.br +0 -0
  114. codex/static_root/assets/VSelectionControl-DBqDlKjK.js.gz +0 -0
  115. codex/static_root/assets/VSlideGroup-BtXPhMOT.830f136ffd41.css +1 -0
  116. codex/static_root/assets/VSlideGroup-BtXPhMOT.830f136ffd41.css.br +0 -0
  117. codex/static_root/assets/VSlideGroup-BtXPhMOT.830f136ffd41.css.gz +0 -0
  118. codex/static_root/assets/VSlideGroup-BtXPhMOT.css +1 -0
  119. codex/static_root/assets/VSlideGroup-BtXPhMOT.css.br +0 -0
  120. codex/static_root/assets/VSlideGroup-BtXPhMOT.css.gz +0 -0
  121. codex/static_root/assets/VSlideGroup-SqR_NAL1.40ba1d838a6e.js +1 -0
  122. codex/static_root/assets/VSlideGroup-SqR_NAL1.40ba1d838a6e.js.br +0 -0
  123. codex/static_root/assets/VSlideGroup-SqR_NAL1.40ba1d838a6e.js.gz +0 -0
  124. codex/static_root/assets/VSlideGroup-SqR_NAL1.js +1 -0
  125. codex/static_root/assets/VSlideGroup-SqR_NAL1.js.br +0 -0
  126. codex/static_root/assets/VSlideGroup-SqR_NAL1.js.gz +0 -0
  127. codex/static_root/assets/VTable-CYC-wMpk.8f15d66044da.js +1 -0
  128. codex/static_root/assets/VTable-CYC-wMpk.8f15d66044da.js.br +0 -0
  129. codex/static_root/assets/VTable-CYC-wMpk.8f15d66044da.js.gz +0 -0
  130. codex/static_root/assets/VTable-CYC-wMpk.js +1 -0
  131. codex/static_root/assets/VTable-CYC-wMpk.js.br +0 -0
  132. codex/static_root/assets/VTable-CYC-wMpk.js.gz +0 -0
  133. codex/static_root/assets/VTextField-BnCEPZIq.b0c32b2c0b14.css +1 -0
  134. codex/static_root/assets/VTextField-BnCEPZIq.b0c32b2c0b14.css.br +0 -0
  135. codex/static_root/assets/VTextField-BnCEPZIq.b0c32b2c0b14.css.gz +0 -0
  136. codex/static_root/assets/VTextField-BnCEPZIq.css +1 -0
  137. codex/static_root/assets/VTextField-BnCEPZIq.css.br +0 -0
  138. codex/static_root/assets/VTextField-BnCEPZIq.css.gz +0 -0
  139. codex/static_root/assets/VTextField-DMRKRbbT.911ac84d8c9d.js +1 -0
  140. codex/static_root/assets/VTextField-DMRKRbbT.911ac84d8c9d.js.br +0 -0
  141. codex/static_root/assets/VTextField-DMRKRbbT.911ac84d8c9d.js.gz +0 -0
  142. codex/static_root/assets/VTextField-DMRKRbbT.js +1 -0
  143. codex/static_root/assets/VTextField-DMRKRbbT.js.br +0 -0
  144. codex/static_root/assets/VTextField-DMRKRbbT.js.gz +0 -0
  145. codex/static_root/assets/VWindowItem-D0P2xNJl.6a10e3f3a153.js +1 -0
  146. codex/static_root/assets/VWindowItem-D0P2xNJl.6a10e3f3a153.js.br +0 -0
  147. codex/static_root/assets/VWindowItem-D0P2xNJl.6a10e3f3a153.js.gz +0 -0
  148. codex/static_root/assets/VWindowItem-D0P2xNJl.js +1 -0
  149. codex/static_root/assets/VWindowItem-D0P2xNJl.js.br +0 -0
  150. codex/static_root/assets/VWindowItem-D0P2xNJl.js.gz +0 -0
  151. codex/static_root/assets/admin-CD90VMen.4c2b6f2a5111.js +1 -0
  152. codex/static_root/assets/admin-CD90VMen.4c2b6f2a5111.js.br +0 -0
  153. codex/static_root/assets/admin-CD90VMen.4c2b6f2a5111.js.gz +0 -0
  154. codex/static_root/assets/admin-CD90VMen.js +1 -0
  155. codex/static_root/assets/admin-CD90VMen.js.br +0 -0
  156. codex/static_root/assets/admin-CD90VMen.js.gz +0 -0
  157. codex/static_root/assets/{admin-CWEjaFr5.7d4523387384.css → admin-DJ7pIXDQ.css} +1 -1
  158. codex/static_root/assets/admin-DJ7pIXDQ.css.br +0 -0
  159. codex/static_root/assets/admin-DJ7pIXDQ.css.gz +0 -0
  160. codex/static_root/assets/{admin-CWEjaFr5.css → admin-DJ7pIXDQ.e2a77af73ef2.css} +1 -1
  161. codex/static_root/assets/admin-DJ7pIXDQ.e2a77af73ef2.css.br +0 -0
  162. codex/static_root/assets/admin-DJ7pIXDQ.e2a77af73ef2.css.gz +0 -0
  163. codex/static_root/assets/admin-menu-B9bzD6hV.c13b7df2ff57.css +1 -0
  164. codex/static_root/assets/admin-menu-B9bzD6hV.c13b7df2ff57.css.br +0 -0
  165. codex/static_root/assets/admin-menu-B9bzD6hV.c13b7df2ff57.css.gz +0 -0
  166. codex/static_root/assets/admin-menu-B9bzD6hV.css +1 -0
  167. codex/static_root/assets/admin-menu-B9bzD6hV.css.br +0 -0
  168. codex/static_root/assets/admin-menu-B9bzD6hV.css.gz +0 -0
  169. codex/static_root/assets/admin-menu-BpEPGKr_.c9f9178c5a82.js +1 -0
  170. codex/static_root/assets/admin-menu-BpEPGKr_.c9f9178c5a82.js.br +0 -0
  171. codex/static_root/assets/admin-menu-BpEPGKr_.c9f9178c5a82.js.gz +0 -0
  172. codex/static_root/assets/admin-menu-BpEPGKr_.js +1 -0
  173. codex/static_root/assets/admin-menu-BpEPGKr_.js.br +0 -0
  174. codex/static_root/assets/admin-menu-BpEPGKr_.js.gz +0 -0
  175. codex/static_root/assets/admin-settings-button-progress-DDF4rY07.4f1158b650ab.js +1 -0
  176. codex/static_root/assets/admin-settings-button-progress-DDF4rY07.4f1158b650ab.js.br +0 -0
  177. codex/static_root/assets/admin-settings-button-progress-DDF4rY07.4f1158b650ab.js.gz +0 -0
  178. codex/static_root/assets/admin-settings-button-progress-DDF4rY07.js +1 -0
  179. codex/static_root/assets/admin-settings-button-progress-DDF4rY07.js.br +0 -0
  180. codex/static_root/assets/admin-settings-button-progress-DDF4rY07.js.gz +0 -0
  181. codex/static_root/assets/admin-settings-button-progress-DUUQfVsZ.2548c49a853e.css +1 -0
  182. codex/static_root/assets/admin-settings-button-progress-DUUQfVsZ.css +1 -0
  183. codex/static_root/assets/browser-C0KS3g2E.0bf1c9c6319c.js +1 -0
  184. codex/static_root/assets/browser-C0KS3g2E.0bf1c9c6319c.js.br +0 -0
  185. codex/static_root/assets/browser-C0KS3g2E.0bf1c9c6319c.js.gz +0 -0
  186. codex/static_root/assets/browser-C0KS3g2E.js +1 -0
  187. codex/static_root/assets/browser-C0KS3g2E.js.br +0 -0
  188. codex/static_root/assets/browser-C0KS3g2E.js.gz +0 -0
  189. codex/static_root/assets/browser-JFL2hLjt.21cb2f7335f7.css +1 -0
  190. codex/static_root/assets/browser-JFL2hLjt.21cb2f7335f7.css.br +0 -0
  191. codex/static_root/assets/browser-JFL2hLjt.21cb2f7335f7.css.gz +0 -0
  192. codex/static_root/assets/browser-JFL2hLjt.css +1 -0
  193. codex/static_root/assets/browser-JFL2hLjt.css.br +0 -0
  194. codex/static_root/assets/browser-JFL2hLjt.css.gz +0 -0
  195. codex/static_root/assets/change-password-dialog-DXJalgW4.a9f34729599d.js +1 -0
  196. codex/static_root/assets/change-password-dialog-DXJalgW4.a9f34729599d.js.br +0 -0
  197. codex/static_root/assets/change-password-dialog-DXJalgW4.a9f34729599d.js.gz +0 -0
  198. codex/static_root/assets/change-password-dialog-DXJalgW4.js +1 -0
  199. codex/static_root/assets/change-password-dialog-DXJalgW4.js.br +0 -0
  200. codex/static_root/assets/change-password-dialog-DXJalgW4.js.gz +0 -0
  201. codex/static_root/assets/change-password-dialog-DrIXdKUC.217574b45b02.css +1 -0
  202. codex/static_root/assets/change-password-dialog-DrIXdKUC.217574b45b02.css.br +0 -0
  203. codex/static_root/assets/change-password-dialog-DrIXdKUC.217574b45b02.css.gz +0 -0
  204. codex/static_root/assets/change-password-dialog-DrIXdKUC.css +1 -0
  205. codex/static_root/assets/change-password-dialog-DrIXdKUC.css.br +0 -0
  206. codex/static_root/assets/change-password-dialog-DrIXdKUC.css.gz +0 -0
  207. codex/static_root/assets/confirm-dialog-B7w6z2rf.472011c06253.css +1 -0
  208. codex/static_root/assets/confirm-dialog-B7w6z2rf.css +1 -0
  209. codex/static_root/assets/confirm-dialog-CqDEpU9k.e1811488121d.js +1 -0
  210. codex/static_root/assets/confirm-dialog-CqDEpU9k.e1811488121d.js.br +0 -0
  211. codex/static_root/assets/confirm-dialog-CqDEpU9k.e1811488121d.js.gz +0 -0
  212. codex/static_root/assets/confirm-dialog-CqDEpU9k.js +1 -0
  213. codex/static_root/assets/confirm-dialog-CqDEpU9k.js.br +0 -0
  214. codex/static_root/assets/confirm-dialog-CqDEpU9k.js.gz +0 -0
  215. codex/static_root/assets/datetime-column-UxNaJr8b.c06a11531af3.js +1 -0
  216. codex/static_root/assets/datetime-column-UxNaJr8b.c06a11531af3.js.br +0 -0
  217. codex/static_root/assets/datetime-column-UxNaJr8b.c06a11531af3.js.gz +0 -0
  218. codex/static_root/assets/datetime-column-UxNaJr8b.js +1 -0
  219. codex/static_root/assets/datetime-column-UxNaJr8b.js.br +0 -0
  220. codex/static_root/assets/datetime-column-UxNaJr8b.js.gz +0 -0
  221. codex/static_root/assets/filter-DskcqZHA.e707b5a05b4b.js +1 -0
  222. codex/static_root/assets/filter-DskcqZHA.e707b5a05b4b.js.br +0 -0
  223. codex/static_root/assets/filter-DskcqZHA.e707b5a05b4b.js.gz +0 -0
  224. codex/static_root/assets/filter-DskcqZHA.js +1 -0
  225. codex/static_root/assets/filter-DskcqZHA.js.br +0 -0
  226. codex/static_root/assets/filter-DskcqZHA.js.gz +0 -0
  227. codex/static_root/assets/flag-tab-CqWovuBu.4dfc6b251e85.css +1 -0
  228. codex/static_root/assets/flag-tab-CqWovuBu.4dfc6b251e85.css.br +0 -0
  229. codex/static_root/assets/flag-tab-CqWovuBu.4dfc6b251e85.css.gz +0 -0
  230. codex/static_root/assets/flag-tab-CqWovuBu.css +1 -0
  231. codex/static_root/assets/flag-tab-CqWovuBu.css.br +0 -0
  232. codex/static_root/assets/flag-tab-CqWovuBu.css.gz +0 -0
  233. codex/static_root/assets/flag-tab-xBeWEQ0w.582e77d9e885.js +1 -0
  234. codex/static_root/assets/flag-tab-xBeWEQ0w.582e77d9e885.js.br +0 -0
  235. codex/static_root/assets/flag-tab-xBeWEQ0w.582e77d9e885.js.gz +0 -0
  236. codex/static_root/assets/flag-tab-xBeWEQ0w.js +1 -0
  237. codex/static_root/assets/flag-tab-xBeWEQ0w.js.br +0 -0
  238. codex/static_root/assets/flag-tab-xBeWEQ0w.js.gz +0 -0
  239. codex/static_root/assets/group-tab-Czt2x61x.56e2886b1bac.js +1 -0
  240. codex/static_root/assets/group-tab-Czt2x61x.56e2886b1bac.js.br +0 -0
  241. codex/static_root/assets/group-tab-Czt2x61x.56e2886b1bac.js.gz +0 -0
  242. codex/static_root/assets/group-tab-Czt2x61x.js +1 -0
  243. codex/static_root/assets/group-tab-Czt2x61x.js.br +0 -0
  244. codex/static_root/assets/group-tab-Czt2x61x.js.gz +0 -0
  245. codex/static_root/assets/group-tab-DkIN1Heu.948e907b1e6b.css +1 -0
  246. codex/static_root/assets/group-tab-DkIN1Heu.948e907b1e6b.css.br +0 -0
  247. codex/static_root/assets/group-tab-DkIN1Heu.948e907b1e6b.css.gz +0 -0
  248. codex/static_root/assets/group-tab-DkIN1Heu.css +1 -0
  249. codex/static_root/assets/group-tab-DkIN1Heu.css.br +0 -0
  250. codex/static_root/assets/group-tab-DkIN1Heu.css.gz +0 -0
  251. codex/static_root/assets/http-error-NHcwE5e_.d49089e40589.js +1 -0
  252. codex/static_root/assets/http-error-NHcwE5e_.d49089e40589.js.br +0 -0
  253. codex/static_root/assets/http-error-NHcwE5e_.d49089e40589.js.gz +0 -0
  254. codex/static_root/assets/http-error-NHcwE5e_.js +1 -0
  255. codex/static_root/assets/http-error-NHcwE5e_.js.br +0 -0
  256. codex/static_root/assets/http-error-NHcwE5e_.js.gz +0 -0
  257. codex/static_root/assets/index-CL_6g4tJ.523d7b3d350f.css +1 -0
  258. codex/static_root/assets/index-CL_6g4tJ.523d7b3d350f.css.br +0 -0
  259. codex/static_root/assets/index-CL_6g4tJ.523d7b3d350f.css.gz +0 -0
  260. codex/static_root/assets/index-CL_6g4tJ.css +1 -0
  261. codex/static_root/assets/index-CL_6g4tJ.css.br +0 -0
  262. codex/static_root/assets/index-CL_6g4tJ.css.gz +0 -0
  263. codex/static_root/assets/index-DYNNO5kn.24a2d270253a.js +1 -0
  264. codex/static_root/assets/index-DYNNO5kn.24a2d270253a.js.br +0 -0
  265. codex/static_root/assets/index-DYNNO5kn.24a2d270253a.js.gz +0 -0
  266. codex/static_root/assets/index-DYNNO5kn.js +1 -0
  267. codex/static_root/assets/index-DYNNO5kn.js.br +0 -0
  268. codex/static_root/assets/index-DYNNO5kn.js.gz +0 -0
  269. codex/static_root/assets/library-tab-CgIqcjvj.60327dfa8ecb.js +1 -0
  270. codex/static_root/assets/library-tab-CgIqcjvj.60327dfa8ecb.js.br +0 -0
  271. codex/static_root/assets/library-tab-CgIqcjvj.60327dfa8ecb.js.gz +0 -0
  272. codex/static_root/assets/library-tab-CgIqcjvj.js +1 -0
  273. codex/static_root/assets/library-tab-CgIqcjvj.js.br +0 -0
  274. codex/static_root/assets/library-tab-CgIqcjvj.js.gz +0 -0
  275. codex/static_root/assets/{library-tab-Bh7ErAk7.7c44200ee727.css → library-tab-Wew8YOLv.0c1780a6b68e.css} +1 -1
  276. codex/static_root/assets/library-tab-Wew8YOLv.0c1780a6b68e.css.br +0 -0
  277. codex/static_root/assets/library-tab-Wew8YOLv.0c1780a6b68e.css.gz +0 -0
  278. codex/static_root/assets/{library-tab-Bh7ErAk7.css → library-tab-Wew8YOLv.css} +1 -1
  279. codex/static_root/assets/library-tab-Wew8YOLv.css.br +0 -0
  280. codex/static_root/assets/library-tab-Wew8YOLv.css.gz +0 -0
  281. codex/static_root/assets/main-B3EwXQ3Q.14dfc21e272c.js +35 -0
  282. codex/static_root/assets/main-B3EwXQ3Q.14dfc21e272c.js.br +0 -0
  283. codex/static_root/assets/main-B3EwXQ3Q.14dfc21e272c.js.gz +0 -0
  284. codex/static_root/assets/main-B3EwXQ3Q.js +35 -0
  285. codex/static_root/assets/main-B3EwXQ3Q.js.br +0 -0
  286. codex/static_root/assets/main-B3EwXQ3Q.js.gz +0 -0
  287. codex/static_root/assets/pager-full-pdf-YkzUXx0B.f39d84e2380a.js +1 -0
  288. codex/static_root/assets/pager-full-pdf-YkzUXx0B.f39d84e2380a.js.br +0 -0
  289. codex/static_root/assets/pager-full-pdf-YkzUXx0B.f39d84e2380a.js.gz +0 -0
  290. codex/static_root/assets/pager-full-pdf-YkzUXx0B.js +1 -0
  291. codex/static_root/assets/pager-full-pdf-YkzUXx0B.js.br +0 -0
  292. codex/static_root/assets/pager-full-pdf-YkzUXx0B.js.gz +0 -0
  293. codex/static_root/assets/pagination-toolbar-CrruiVov.3bf9b795350d.js +1 -0
  294. codex/static_root/assets/pagination-toolbar-CrruiVov.3bf9b795350d.js.br +0 -0
  295. codex/static_root/assets/pagination-toolbar-CrruiVov.3bf9b795350d.js.gz +0 -0
  296. codex/static_root/assets/pagination-toolbar-CrruiVov.js +1 -0
  297. codex/static_root/assets/pagination-toolbar-CrruiVov.js.br +0 -0
  298. codex/static_root/assets/pagination-toolbar-CrruiVov.js.gz +0 -0
  299. codex/static_root/assets/{pagination-toolbar-C45-onwe.4722195bb60b.css → pagination-toolbar-DGrxp2OD.css} +1 -1
  300. codex/static_root/assets/pagination-toolbar-DGrxp2OD.css.br +0 -0
  301. codex/static_root/assets/pagination-toolbar-DGrxp2OD.css.gz +0 -0
  302. codex/static_root/assets/{pagination-toolbar-C45-onwe.css → pagination-toolbar-DGrxp2OD.f960a624f04f.css} +1 -1
  303. codex/static_root/assets/pagination-toolbar-DGrxp2OD.f960a624f04f.css.br +0 -0
  304. codex/static_root/assets/pagination-toolbar-DGrxp2OD.f960a624f04f.css.gz +0 -0
  305. codex/static_root/assets/{pdf-doc-BjlRPuf4.0f056fa321b6.js → pdf-doc-ctqZIwOP.7e7b2c815ea4.js} +3 -3
  306. codex/static_root/assets/pdf-doc-ctqZIwOP.7e7b2c815ea4.js.br +0 -0
  307. codex/static_root/assets/pdf-doc-ctqZIwOP.7e7b2c815ea4.js.gz +0 -0
  308. codex/static_root/assets/{pdf-doc-BjlRPuf4.js → pdf-doc-ctqZIwOP.js} +3 -3
  309. codex/static_root/assets/pdf-doc-ctqZIwOP.js.br +0 -0
  310. codex/static_root/assets/pdf-doc-ctqZIwOP.js.gz +0 -0
  311. codex/static_root/assets/reader-DPLhdrJD.268417c618c5.js +2 -0
  312. codex/static_root/assets/reader-DPLhdrJD.268417c618c5.js.br +0 -0
  313. codex/static_root/assets/reader-DPLhdrJD.268417c618c5.js.gz +0 -0
  314. codex/static_root/assets/reader-DPLhdrJD.js +2 -0
  315. codex/static_root/assets/reader-DPLhdrJD.js.br +0 -0
  316. codex/static_root/assets/reader-DPLhdrJD.js.gz +0 -0
  317. codex/static_root/assets/reader-nD70BeEz.06e85e73c391.css +1 -0
  318. codex/static_root/assets/reader-nD70BeEz.06e85e73c391.css.br +0 -0
  319. codex/static_root/assets/reader-nD70BeEz.06e85e73c391.css.gz +0 -0
  320. codex/static_root/assets/reader-nD70BeEz.css +1 -0
  321. codex/static_root/assets/reader-nD70BeEz.css.br +0 -0
  322. codex/static_root/assets/reader-nD70BeEz.css.gz +0 -0
  323. codex/static_root/assets/relation-chips-DOALMcWL.5d3b8100ba03.js +1 -0
  324. codex/static_root/assets/relation-chips-DOALMcWL.5d3b8100ba03.js.br +0 -0
  325. codex/static_root/assets/relation-chips-DOALMcWL.5d3b8100ba03.js.gz +0 -0
  326. codex/static_root/assets/relation-chips-DOALMcWL.js +1 -0
  327. codex/static_root/assets/relation-chips-DOALMcWL.js.br +0 -0
  328. codex/static_root/assets/relation-chips-DOALMcWL.js.gz +0 -0
  329. codex/static_root/assets/settings-drawer-BVj1U_LC.c68369e0c2de.js +2 -0
  330. codex/static_root/assets/settings-drawer-BVj1U_LC.c68369e0c2de.js.br +0 -0
  331. codex/static_root/assets/settings-drawer-BVj1U_LC.c68369e0c2de.js.gz +0 -0
  332. codex/static_root/assets/settings-drawer-BVj1U_LC.js +2 -0
  333. codex/static_root/assets/settings-drawer-BVj1U_LC.js.br +0 -0
  334. codex/static_root/assets/settings-drawer-BVj1U_LC.js.gz +0 -0
  335. codex/static_root/assets/{stats-tab-BXGisn5N.9b7a71e7fe28.css → stats-tab-BAYTqQNg.5f715428c394.css} +1 -1
  336. codex/static_root/assets/stats-tab-BAYTqQNg.5f715428c394.css.br +0 -0
  337. codex/static_root/assets/stats-tab-BAYTqQNg.5f715428c394.css.gz +0 -0
  338. codex/static_root/assets/{stats-tab-BXGisn5N.css → stats-tab-BAYTqQNg.css} +1 -1
  339. codex/static_root/assets/stats-tab-BAYTqQNg.css.br +0 -0
  340. codex/static_root/assets/stats-tab-BAYTqQNg.css.gz +0 -0
  341. codex/static_root/assets/stats-tab-DDLwwwnP.35305258097b.js +1 -0
  342. codex/static_root/assets/stats-tab-DDLwwwnP.35305258097b.js.br +0 -0
  343. codex/static_root/assets/stats-tab-DDLwwwnP.35305258097b.js.gz +0 -0
  344. codex/static_root/assets/stats-tab-DDLwwwnP.js +1 -0
  345. codex/static_root/assets/stats-tab-DDLwwwnP.js.br +0 -0
  346. codex/static_root/assets/stats-tab-DDLwwwnP.js.gz +0 -0
  347. codex/static_root/assets/task-tab--cXi48kg.5dfd6890a1c2.css +1 -0
  348. codex/static_root/assets/{task-tab-1XiWn9xP.06cb8e1b794d.css.br → task-tab--cXi48kg.5dfd6890a1c2.css.br} +1 -1
  349. codex/static_root/assets/task-tab--cXi48kg.5dfd6890a1c2.css.gz +0 -0
  350. codex/static_root/assets/task-tab--cXi48kg.css +1 -0
  351. codex/static_root/assets/{task-tab-1XiWn9xP.css.br → task-tab--cXi48kg.css.br} +1 -1
  352. codex/static_root/assets/task-tab--cXi48kg.css.gz +0 -0
  353. codex/static_root/assets/task-tab-BpP3n2dO.c853eb565200.js +1 -0
  354. codex/static_root/assets/task-tab-BpP3n2dO.c853eb565200.js.br +0 -0
  355. codex/static_root/assets/task-tab-BpP3n2dO.c853eb565200.js.gz +0 -0
  356. codex/static_root/assets/task-tab-BpP3n2dO.js +1 -0
  357. codex/static_root/assets/task-tab-BpP3n2dO.js.br +0 -0
  358. codex/static_root/assets/task-tab-BpP3n2dO.js.gz +0 -0
  359. codex/static_root/assets/transition-3g2arGgl.c6e6f91b7978.js +1 -0
  360. codex/static_root/assets/transition-3g2arGgl.c6e6f91b7978.js.br +0 -0
  361. codex/static_root/assets/transition-3g2arGgl.c6e6f91b7978.js.gz +0 -0
  362. codex/static_root/assets/transition-3g2arGgl.js +1 -0
  363. codex/static_root/assets/transition-3g2arGgl.js.br +0 -0
  364. codex/static_root/assets/transition-3g2arGgl.js.gz +0 -0
  365. codex/static_root/assets/transition-5LRFTPo5.3d726f9bbcb0.css +1 -0
  366. codex/static_root/assets/transition-5LRFTPo5.3d726f9bbcb0.css.br +4 -0
  367. codex/static_root/assets/transition-5LRFTPo5.3d726f9bbcb0.css.gz +0 -0
  368. codex/static_root/assets/transition-5LRFTPo5.css +1 -0
  369. codex/static_root/assets/transition-5LRFTPo5.css.br +4 -0
  370. codex/static_root/assets/transition-5LRFTPo5.css.gz +0 -0
  371. codex/static_root/assets/{unauthorized-muDsv-rC.css → unauthorized-BjhIc97q.728511c92cd0.css} +1 -1
  372. codex/static_root/assets/unauthorized-BjhIc97q.728511c92cd0.css.br +0 -0
  373. codex/static_root/assets/unauthorized-BjhIc97q.728511c92cd0.css.gz +0 -0
  374. codex/static_root/assets/{unauthorized-muDsv-rC.2166ec8b3a32.css → unauthorized-BjhIc97q.css} +1 -1
  375. codex/static_root/assets/unauthorized-BjhIc97q.css.br +0 -0
  376. codex/static_root/assets/unauthorized-BjhIc97q.css.gz +0 -0
  377. codex/static_root/assets/unauthorized-CdumQ1Vf.79d9a61eb572.js +1 -0
  378. codex/static_root/assets/unauthorized-CdumQ1Vf.79d9a61eb572.js.br +0 -0
  379. codex/static_root/assets/unauthorized-CdumQ1Vf.79d9a61eb572.js.gz +0 -0
  380. codex/static_root/assets/unauthorized-CdumQ1Vf.js +1 -0
  381. codex/static_root/assets/unauthorized-CdumQ1Vf.js.br +0 -0
  382. codex/static_root/assets/unauthorized-CdumQ1Vf.js.gz +0 -0
  383. codex/static_root/assets/user-tab-D6oOKZTP.05944b00c700.js +1 -0
  384. codex/static_root/assets/user-tab-D6oOKZTP.05944b00c700.js.br +0 -0
  385. codex/static_root/assets/user-tab-D6oOKZTP.05944b00c700.js.gz +0 -0
  386. codex/static_root/assets/user-tab-D6oOKZTP.js +1 -0
  387. codex/static_root/assets/user-tab-D6oOKZTP.js.br +0 -0
  388. codex/static_root/assets/user-tab-D6oOKZTP.js.gz +0 -0
  389. codex/static_root/manifest.c5f1de88b1ac.json +712 -0
  390. codex/static_root/manifest.c5f1de88b1ac.json.br +0 -0
  391. codex/static_root/manifest.c5f1de88b1ac.json.gz +0 -0
  392. codex/static_root/manifest.json +371 -294
  393. codex/static_root/manifest.json.br +0 -0
  394. codex/static_root/manifest.json.gz +0 -0
  395. codex/static_root/staticfiles.json +1 -1
  396. codex/status_controller.py +15 -10
  397. codex/threads.py +1 -1
  398. codex/urls/api/auth.py +1 -1
  399. codex/urls/api/browser.py +1 -1
  400. codex/views/admin/library.py +18 -13
  401. codex/views/admin/stats.py +23 -16
  402. codex/views/admin/tasks.py +45 -40
  403. codex/views/auth.py +50 -74
  404. codex/views/bookmark.py +16 -153
  405. codex/views/browser/annotate/__init__.py +1 -0
  406. codex/views/browser/annotate/bookmark.py +112 -0
  407. codex/views/browser/annotate/card.py +61 -0
  408. codex/views/browser/annotate/order.py +247 -0
  409. codex/views/browser/breadcrumbs.py +90 -11
  410. codex/views/browser/browser.py +82 -117
  411. codex/views/browser/choices.py +15 -18
  412. codex/views/browser/cover.py +18 -24
  413. codex/views/browser/filters/bookmark.py +18 -19
  414. codex/views/browser/filters/field.py +8 -3
  415. codex/views/browser/filters/filter.py +69 -0
  416. codex/views/browser/filters/group.py +9 -6
  417. codex/views/browser/filters/search/__init__.py +1 -0
  418. codex/views/browser/filters/search/aliases.py +81 -0
  419. codex/views/browser/filters/search/field/__init__.py +1 -0
  420. codex/views/browser/filters/search/field/column.py +53 -0
  421. codex/views/browser/filters/search/field/expression.py +177 -0
  422. codex/views/browser/filters/search/field/filter.py +70 -0
  423. codex/views/browser/filters/search/field/optimize.py +71 -0
  424. codex/views/browser/filters/search/field/parse.py +187 -0
  425. codex/views/browser/filters/search/fts.py +24 -0
  426. codex/views/browser/filters/search/parse.py +250 -0
  427. codex/views/browser/group_mtime.py +83 -0
  428. codex/views/browser/metadata/__init__.py +1 -0
  429. codex/views/browser/metadata/annotate.py +109 -0
  430. codex/views/browser/metadata/copy_intersections.py +90 -0
  431. codex/views/browser/metadata/metadata.py +83 -0
  432. codex/views/browser/metadata/query_intersections.py +112 -0
  433. codex/views/browser/mtime.py +2 -10
  434. codex/views/browser/order_by.py +22 -16
  435. codex/views/browser/page_in_bounds.py +88 -0
  436. codex/views/browser/paginate.py +32 -123
  437. codex/views/browser/params.py +64 -0
  438. codex/views/browser/title.py +1 -6
  439. codex/views/browser/validate.py +68 -33
  440. codex/views/const.py +0 -1
  441. codex/views/download.py +1 -1
  442. codex/views/mixins.py +27 -15
  443. codex/views/opds/const.py +2 -3
  444. codex/views/opds/urls.py +2 -2
  445. codex/views/opds/util.py +2 -3
  446. codex/views/opds/v1/entry/links.py +3 -1
  447. codex/views/opds/v1/facets.py +65 -12
  448. codex/views/opds/v1/feed.py +7 -65
  449. codex/views/opds/v1/links.py +5 -4
  450. codex/views/opds/v2/feed.py +2 -28
  451. codex/views/opds/v2/links.py +27 -2
  452. codex/views/opds/v2/publications.py +5 -6
  453. codex/views/opds/v2/top_links.py +3 -6
  454. codex/views/public.py +2 -2
  455. codex/views/reader/arcs.py +0 -3
  456. codex/views/reader/books.py +57 -41
  457. codex/views/reader/page.py +13 -7
  458. codex/views/reader/{init.py → params.py} +37 -31
  459. codex/views/reader/reader.py +1 -2
  460. codex/views/session.py +43 -54
  461. codex/views/timezone.py +54 -0
  462. codex/views/version.py +1 -1
  463. {codex-1.6.19.dist-info → codex-1.7.0.dist-info}/METADATA +15 -10
  464. {codex-1.6.19.dist-info → codex-1.7.0.dist-info}/RECORD +467 -484
  465. codex/_vendor/__init__.py +0 -0
  466. codex/_vendor/django_haystack-3.2.1.dist-info/AUTHORS +0 -127
  467. codex/_vendor/django_haystack-3.2.1.dist-info/INSTALLER +0 -1
  468. codex/_vendor/django_haystack-3.2.1.dist-info/LICENSE +0 -31
  469. codex/_vendor/django_haystack-3.2.1.dist-info/METADATA +0 -98
  470. codex/_vendor/django_haystack-3.2.1.dist-info/RECORD +0 -97
  471. codex/_vendor/django_haystack-3.2.1.dist-info/REQUESTED +0 -0
  472. codex/_vendor/django_haystack-3.2.1.dist-info/WHEEL +0 -5
  473. codex/_vendor/django_haystack-3.2.1.dist-info/top_level.txt +0 -1
  474. codex/_vendor/haystack/__init__.py +0 -80
  475. codex/_vendor/haystack/admin.py +0 -163
  476. codex/_vendor/haystack/apps.py +0 -31
  477. codex/_vendor/haystack/backends/__init__.py +0 -1109
  478. codex/_vendor/haystack/backends/elasticsearch2_backend.py +0 -390
  479. codex/_vendor/haystack/backends/elasticsearch5_backend.py +0 -483
  480. codex/_vendor/haystack/backends/elasticsearch7_backend.py +0 -586
  481. codex/_vendor/haystack/backends/elasticsearch_backend.py +0 -1141
  482. codex/_vendor/haystack/backends/simple_backend.py +0 -132
  483. codex/_vendor/haystack/backends/solr_backend.py +0 -991
  484. codex/_vendor/haystack/backends/whoosh_backend.py +0 -1104
  485. codex/_vendor/haystack/constants.py +0 -57
  486. codex/_vendor/haystack/exceptions.py +0 -57
  487. codex/_vendor/haystack/fields.py +0 -562
  488. codex/_vendor/haystack/forms.py +0 -135
  489. codex/_vendor/haystack/generic_views.py +0 -141
  490. codex/_vendor/haystack/indexes.py +0 -548
  491. codex/_vendor/haystack/inputs.py +0 -169
  492. codex/_vendor/haystack/management/__init__.py +0 -0
  493. codex/_vendor/haystack/management/commands/__init__.py +0 -0
  494. codex/_vendor/haystack/management/commands/build_solr_schema.py +0 -187
  495. codex/_vendor/haystack/management/commands/clear_index.py +0 -67
  496. codex/_vendor/haystack/management/commands/haystack_info.py +0 -22
  497. codex/_vendor/haystack/management/commands/rebuild_index.py +0 -65
  498. codex/_vendor/haystack/management/commands/update_index.py +0 -438
  499. codex/_vendor/haystack/manager.py +0 -105
  500. codex/_vendor/haystack/models.py +0 -257
  501. codex/_vendor/haystack/panels.py +0 -89
  502. codex/_vendor/haystack/query.py +0 -771
  503. codex/_vendor/haystack/routers.py +0 -14
  504. codex/_vendor/haystack/signals.py +0 -88
  505. codex/_vendor/haystack/templates/panels/haystack.html +0 -33
  506. codex/_vendor/haystack/templates/search_configuration/schema.xml +0 -1056
  507. codex/_vendor/haystack/templates/search_configuration/solrconfig.xml +0 -1446
  508. codex/_vendor/haystack/templatetags/__init__.py +0 -0
  509. codex/_vendor/haystack/templatetags/highlight.py +0 -131
  510. codex/_vendor/haystack/templatetags/more_like_this.py +0 -119
  511. codex/_vendor/haystack/urls.py +0 -5
  512. codex/_vendor/haystack/utils/__init__.py +0 -84
  513. codex/_vendor/haystack/utils/app_loading.py +0 -34
  514. codex/_vendor/haystack/utils/geo.py +0 -71
  515. codex/_vendor/haystack/utils/highlighting.py +0 -165
  516. codex/_vendor/haystack/utils/loading.py +0 -374
  517. codex/_vendor/haystack/utils/log.py +0 -21
  518. codex/_vendor/haystack/version.py +0 -16
  519. codex/_vendor/haystack/views.py +0 -253
  520. codex/integrity.py +0 -492
  521. codex/librarian/search/merge.py +0 -86
  522. codex/librarian/search/version.py +0 -63
  523. codex/search/__init__.py +0 -1
  524. codex/search/backend.py +0 -524
  525. codex/search/backend_search.py +0 -229
  526. codex/search/engine.py +0 -33
  527. codex/search/indexes.py +0 -79
  528. codex/search/query.py +0 -67
  529. codex/search/writing.py +0 -180
  530. codex/serializers/choices.py +0 -196
  531. codex/static_root/assets/VCheckbox-Cko1sQK-.170726b3b8a1.js +0 -1
  532. codex/static_root/assets/VCheckbox-Cko1sQK-.170726b3b8a1.js.br +0 -0
  533. codex/static_root/assets/VCheckbox-Cko1sQK-.170726b3b8a1.js.gz +0 -0
  534. codex/static_root/assets/VCheckbox-Cko1sQK-.js +0 -1
  535. codex/static_root/assets/VCheckbox-Cko1sQK-.js.br +0 -0
  536. codex/static_root/assets/VCheckbox-Cko1sQK-.js.gz +0 -0
  537. codex/static_root/assets/VCheckboxBtn-CO3-aqQL.c9b8062fd66f.js +0 -1
  538. codex/static_root/assets/VCheckboxBtn-CO3-aqQL.c9b8062fd66f.js.br +0 -0
  539. codex/static_root/assets/VCheckboxBtn-CO3-aqQL.c9b8062fd66f.js.gz +0 -0
  540. codex/static_root/assets/VCheckboxBtn-CO3-aqQL.js +0 -1
  541. codex/static_root/assets/VCheckboxBtn-CO3-aqQL.js.br +0 -0
  542. codex/static_root/assets/VCheckboxBtn-CO3-aqQL.js.gz +0 -0
  543. codex/static_root/assets/VCombobox-Bjp6lffE.caf59fba486e.js +0 -1
  544. codex/static_root/assets/VCombobox-Bjp6lffE.caf59fba486e.js.br +0 -0
  545. codex/static_root/assets/VCombobox-Bjp6lffE.caf59fba486e.js.gz +0 -0
  546. codex/static_root/assets/VCombobox-Bjp6lffE.js +0 -1
  547. codex/static_root/assets/VCombobox-Bjp6lffE.js.br +0 -0
  548. codex/static_root/assets/VCombobox-Bjp6lffE.js.gz +0 -0
  549. codex/static_root/assets/VDialog-38np3TSA.5a0cb7a9e56d.css +0 -1
  550. codex/static_root/assets/VDialog-38np3TSA.5a0cb7a9e56d.css.br +0 -0
  551. codex/static_root/assets/VDialog-38np3TSA.5a0cb7a9e56d.css.gz +0 -0
  552. codex/static_root/assets/VDialog-38np3TSA.css +0 -1
  553. codex/static_root/assets/VDialog-38np3TSA.css.br +0 -0
  554. codex/static_root/assets/VDialog-38np3TSA.css.gz +0 -0
  555. codex/static_root/assets/VDialog-BkpVGB70.6eea3ca762a5.js +0 -1
  556. codex/static_root/assets/VDialog-BkpVGB70.6eea3ca762a5.js.br +0 -0
  557. codex/static_root/assets/VDialog-BkpVGB70.6eea3ca762a5.js.gz +0 -0
  558. codex/static_root/assets/VDialog-BkpVGB70.js +0 -1
  559. codex/static_root/assets/VDialog-BkpVGB70.js.br +0 -0
  560. codex/static_root/assets/VDialog-BkpVGB70.js.gz +0 -0
  561. codex/static_root/assets/VExpansionPanels-Ci2-j8XX.9c55db4ef49e.js +0 -1
  562. codex/static_root/assets/VExpansionPanels-Ci2-j8XX.9c55db4ef49e.js.br +0 -0
  563. codex/static_root/assets/VExpansionPanels-Ci2-j8XX.9c55db4ef49e.js.gz +0 -0
  564. codex/static_root/assets/VExpansionPanels-Ci2-j8XX.js +0 -1
  565. codex/static_root/assets/VExpansionPanels-Ci2-j8XX.js.br +0 -0
  566. codex/static_root/assets/VExpansionPanels-Ci2-j8XX.js.gz +0 -0
  567. codex/static_root/assets/VRadioGroup-D3Py5BfQ.a4f25edb86d3.js +0 -1
  568. codex/static_root/assets/VRadioGroup-D3Py5BfQ.a4f25edb86d3.js.br +0 -0
  569. codex/static_root/assets/VRadioGroup-D3Py5BfQ.a4f25edb86d3.js.gz +0 -0
  570. codex/static_root/assets/VRadioGroup-D3Py5BfQ.js +0 -1
  571. codex/static_root/assets/VRadioGroup-D3Py5BfQ.js.br +0 -0
  572. codex/static_root/assets/VRadioGroup-D3Py5BfQ.js.gz +0 -0
  573. codex/static_root/assets/VSelect-Ca2bIOso.6613989e4c45.css +0 -1
  574. codex/static_root/assets/VSelect-Ca2bIOso.6613989e4c45.css.br +0 -0
  575. codex/static_root/assets/VSelect-Ca2bIOso.6613989e4c45.css.gz +0 -0
  576. codex/static_root/assets/VSelect-Ca2bIOso.css +0 -1
  577. codex/static_root/assets/VSelect-Ca2bIOso.css.br +0 -0
  578. codex/static_root/assets/VSelect-Ca2bIOso.css.gz +0 -0
  579. codex/static_root/assets/VSelect-DtvZsYZz.e98745d858eb.js +0 -1
  580. codex/static_root/assets/VSelect-DtvZsYZz.e98745d858eb.js.br +0 -0
  581. codex/static_root/assets/VSelect-DtvZsYZz.e98745d858eb.js.gz +0 -0
  582. codex/static_root/assets/VSelect-DtvZsYZz.js +0 -1
  583. codex/static_root/assets/VSelect-DtvZsYZz.js.br +0 -0
  584. codex/static_root/assets/VSelect-DtvZsYZz.js.gz +0 -0
  585. codex/static_root/assets/VSelectionControl-D6kmykQW.1e1fda62ceba.js +0 -1
  586. codex/static_root/assets/VSelectionControl-D6kmykQW.1e1fda62ceba.js.br +0 -0
  587. codex/static_root/assets/VSelectionControl-D6kmykQW.1e1fda62ceba.js.gz +0 -0
  588. codex/static_root/assets/VSelectionControl-D6kmykQW.js +0 -1
  589. codex/static_root/assets/VSelectionControl-D6kmykQW.js.br +0 -0
  590. codex/static_root/assets/VSelectionControl-D6kmykQW.js.gz +0 -0
  591. codex/static_root/assets/VSlideGroup-Dk_1upHt.2c836070ec75.css +0 -1
  592. codex/static_root/assets/VSlideGroup-Dk_1upHt.2c836070ec75.css.br +0 -0
  593. codex/static_root/assets/VSlideGroup-Dk_1upHt.2c836070ec75.css.gz +0 -0
  594. codex/static_root/assets/VSlideGroup-Dk_1upHt.css +0 -1
  595. codex/static_root/assets/VSlideGroup-Dk_1upHt.css.br +0 -0
  596. codex/static_root/assets/VSlideGroup-Dk_1upHt.css.gz +0 -0
  597. codex/static_root/assets/VSlideGroup-UGZWxpF5.360bdefcd215.js +0 -1
  598. codex/static_root/assets/VSlideGroup-UGZWxpF5.360bdefcd215.js.br +0 -0
  599. codex/static_root/assets/VSlideGroup-UGZWxpF5.360bdefcd215.js.gz +0 -0
  600. codex/static_root/assets/VSlideGroup-UGZWxpF5.js +0 -1
  601. codex/static_root/assets/VSlideGroup-UGZWxpF5.js.br +0 -0
  602. codex/static_root/assets/VSlideGroup-UGZWxpF5.js.gz +0 -0
  603. codex/static_root/assets/VTable-DXH_yQ0o.1149f56ad566.js +0 -1
  604. codex/static_root/assets/VTable-DXH_yQ0o.1149f56ad566.js.br +0 -0
  605. codex/static_root/assets/VTable-DXH_yQ0o.1149f56ad566.js.gz +0 -0
  606. codex/static_root/assets/VTable-DXH_yQ0o.js +0 -1
  607. codex/static_root/assets/VTable-DXH_yQ0o.js.br +0 -0
  608. codex/static_root/assets/VTable-DXH_yQ0o.js.gz +0 -0
  609. codex/static_root/assets/VTextField-Blqy56_L.26d8761e0155.js +0 -1
  610. codex/static_root/assets/VTextField-Blqy56_L.26d8761e0155.js.br +0 -0
  611. codex/static_root/assets/VTextField-Blqy56_L.26d8761e0155.js.gz +0 -0
  612. codex/static_root/assets/VTextField-Blqy56_L.js +0 -1
  613. codex/static_root/assets/VTextField-Blqy56_L.js.br +0 -0
  614. codex/static_root/assets/VTextField-Blqy56_L.js.gz +0 -0
  615. codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css +0 -1
  616. codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css.br +0 -0
  617. codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css.gz +0 -0
  618. codex/static_root/assets/VTextField-Crc3gdNh.css +0 -1
  619. codex/static_root/assets/VTextField-Crc3gdNh.css.br +0 -0
  620. codex/static_root/assets/VTextField-Crc3gdNh.css.gz +0 -0
  621. codex/static_root/assets/VWindowItem-C8_ovV7e.afbc08414765.js +0 -1
  622. codex/static_root/assets/VWindowItem-C8_ovV7e.afbc08414765.js.br +0 -0
  623. codex/static_root/assets/VWindowItem-C8_ovV7e.afbc08414765.js.gz +0 -0
  624. codex/static_root/assets/VWindowItem-C8_ovV7e.js +0 -1
  625. codex/static_root/assets/VWindowItem-C8_ovV7e.js.br +0 -0
  626. codex/static_root/assets/VWindowItem-C8_ovV7e.js.gz +0 -0
  627. codex/static_root/assets/admin-CWEjaFr5.7d4523387384.css.br +0 -0
  628. codex/static_root/assets/admin-CWEjaFr5.7d4523387384.css.gz +0 -0
  629. codex/static_root/assets/admin-CWEjaFr5.css.br +0 -0
  630. codex/static_root/assets/admin-CWEjaFr5.css.gz +0 -0
  631. codex/static_root/assets/admin-DTRn8bBs.d031ea42d8d0.js +0 -1
  632. codex/static_root/assets/admin-DTRn8bBs.d031ea42d8d0.js.br +0 -0
  633. codex/static_root/assets/admin-DTRn8bBs.d031ea42d8d0.js.gz +0 -0
  634. codex/static_root/assets/admin-DTRn8bBs.js +0 -1
  635. codex/static_root/assets/admin-DTRn8bBs.js.br +0 -0
  636. codex/static_root/assets/admin-DTRn8bBs.js.gz +0 -0
  637. codex/static_root/assets/admin-drawer-panel-BaXFOcru.b1a44b05f482.js +0 -30
  638. codex/static_root/assets/admin-drawer-panel-BaXFOcru.b1a44b05f482.js.br +0 -0
  639. codex/static_root/assets/admin-drawer-panel-BaXFOcru.b1a44b05f482.js.gz +0 -0
  640. codex/static_root/assets/admin-drawer-panel-BaXFOcru.js +0 -30
  641. codex/static_root/assets/admin-drawer-panel-BaXFOcru.js.br +0 -0
  642. codex/static_root/assets/admin-drawer-panel-BaXFOcru.js.gz +0 -0
  643. codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.3cb33056e994.css +0 -1
  644. codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.3cb33056e994.css.br +0 -0
  645. codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.3cb33056e994.css.gz +0 -0
  646. codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.css +0 -1
  647. codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.css.br +0 -0
  648. codex/static_root/assets/admin-drawer-panel-Bs2wgKj3.css.gz +0 -0
  649. codex/static_root/assets/browser-BBpUyGmz.c1cb9e2d463b.js +0 -1
  650. codex/static_root/assets/browser-BBpUyGmz.c1cb9e2d463b.js.br +0 -0
  651. codex/static_root/assets/browser-BBpUyGmz.c1cb9e2d463b.js.gz +0 -0
  652. codex/static_root/assets/browser-BBpUyGmz.js +0 -1
  653. codex/static_root/assets/browser-BBpUyGmz.js.br +0 -0
  654. codex/static_root/assets/browser-BBpUyGmz.js.gz +0 -0
  655. codex/static_root/assets/browser-Binc3n9H.313722d27ca3.css +0 -1
  656. codex/static_root/assets/browser-Binc3n9H.313722d27ca3.css.br +0 -0
  657. codex/static_root/assets/browser-Binc3n9H.313722d27ca3.css.gz +0 -0
  658. codex/static_root/assets/browser-Binc3n9H.css +0 -1
  659. codex/static_root/assets/browser-Binc3n9H.css.br +0 -0
  660. codex/static_root/assets/browser-Binc3n9H.css.gz +0 -0
  661. codex/static_root/assets/change-password-dialog-Cebek1-c.aff2975e31f8.css +0 -1
  662. codex/static_root/assets/change-password-dialog-Cebek1-c.aff2975e31f8.css.br +0 -0
  663. codex/static_root/assets/change-password-dialog-Cebek1-c.aff2975e31f8.css.gz +0 -0
  664. codex/static_root/assets/change-password-dialog-Cebek1-c.css +0 -1
  665. codex/static_root/assets/change-password-dialog-Cebek1-c.css.br +0 -0
  666. codex/static_root/assets/change-password-dialog-Cebek1-c.css.gz +0 -0
  667. codex/static_root/assets/change-password-dialog-DlHoLhDF.76ab4a29bb9b.js +0 -1
  668. codex/static_root/assets/change-password-dialog-DlHoLhDF.76ab4a29bb9b.js.br +0 -0
  669. codex/static_root/assets/change-password-dialog-DlHoLhDF.76ab4a29bb9b.js.gz +0 -0
  670. codex/static_root/assets/change-password-dialog-DlHoLhDF.js +0 -1
  671. codex/static_root/assets/change-password-dialog-DlHoLhDF.js.br +0 -0
  672. codex/static_root/assets/change-password-dialog-DlHoLhDF.js.gz +0 -0
  673. codex/static_root/assets/confirm-dialog-BmhedLCx.7c2103d319d4.css +0 -1
  674. codex/static_root/assets/confirm-dialog-BmhedLCx.css +0 -1
  675. codex/static_root/assets/confirm-dialog-D3_s2DQy.9dde66036c72.js +0 -1
  676. codex/static_root/assets/confirm-dialog-D3_s2DQy.9dde66036c72.js.br +0 -0
  677. codex/static_root/assets/confirm-dialog-D3_s2DQy.9dde66036c72.js.gz +0 -0
  678. codex/static_root/assets/confirm-dialog-D3_s2DQy.js +0 -1
  679. codex/static_root/assets/confirm-dialog-D3_s2DQy.js.br +0 -0
  680. codex/static_root/assets/confirm-dialog-D3_s2DQy.js.gz +0 -0
  681. codex/static_root/assets/datetime-column-BxC1Li9e.3dc314b3295d.js +0 -1
  682. codex/static_root/assets/datetime-column-BxC1Li9e.3dc314b3295d.js.br +0 -0
  683. codex/static_root/assets/datetime-column-BxC1Li9e.3dc314b3295d.js.gz +0 -0
  684. codex/static_root/assets/datetime-column-BxC1Li9e.js +0 -1
  685. codex/static_root/assets/datetime-column-BxC1Li9e.js.br +0 -0
  686. codex/static_root/assets/datetime-column-BxC1Li9e.js.gz +0 -0
  687. codex/static_root/assets/filter-Bzk7x841.d0c3b602e62d.js +0 -1
  688. codex/static_root/assets/filter-Bzk7x841.d0c3b602e62d.js.br +0 -0
  689. codex/static_root/assets/filter-Bzk7x841.d0c3b602e62d.js.gz +0 -0
  690. codex/static_root/assets/filter-Bzk7x841.js +0 -1
  691. codex/static_root/assets/filter-Bzk7x841.js.br +0 -0
  692. codex/static_root/assets/filter-Bzk7x841.js.gz +0 -0
  693. codex/static_root/assets/flag-tab-C2bI5zq3.8f8c297600a6.js +0 -1
  694. codex/static_root/assets/flag-tab-C2bI5zq3.8f8c297600a6.js.br +0 -0
  695. codex/static_root/assets/flag-tab-C2bI5zq3.8f8c297600a6.js.gz +0 -0
  696. codex/static_root/assets/flag-tab-C2bI5zq3.js +0 -1
  697. codex/static_root/assets/flag-tab-C2bI5zq3.js.br +0 -0
  698. codex/static_root/assets/flag-tab-C2bI5zq3.js.gz +0 -0
  699. codex/static_root/assets/flag-tab-DBqpLKi7.css +0 -1
  700. codex/static_root/assets/flag-tab-DBqpLKi7.css.br +0 -0
  701. codex/static_root/assets/flag-tab-DBqpLKi7.css.gz +0 -0
  702. codex/static_root/assets/flag-tab-DBqpLKi7.dcfef39f541e.css +0 -1
  703. codex/static_root/assets/flag-tab-DBqpLKi7.dcfef39f541e.css.br +0 -0
  704. codex/static_root/assets/flag-tab-DBqpLKi7.dcfef39f541e.css.gz +0 -0
  705. codex/static_root/assets/group-tab-5esH4lwX.a81fdd258117.js +0 -1
  706. codex/static_root/assets/group-tab-5esH4lwX.a81fdd258117.js.br +0 -0
  707. codex/static_root/assets/group-tab-5esH4lwX.a81fdd258117.js.gz +0 -0
  708. codex/static_root/assets/group-tab-5esH4lwX.js +0 -1
  709. codex/static_root/assets/group-tab-5esH4lwX.js.br +0 -0
  710. codex/static_root/assets/group-tab-5esH4lwX.js.gz +0 -0
  711. codex/static_root/assets/group-tab-CBKuS3Iv.7e4746634782.css +0 -1
  712. codex/static_root/assets/group-tab-CBKuS3Iv.7e4746634782.css.br +0 -0
  713. codex/static_root/assets/group-tab-CBKuS3Iv.7e4746634782.css.gz +0 -0
  714. codex/static_root/assets/group-tab-CBKuS3Iv.css +0 -1
  715. codex/static_root/assets/group-tab-CBKuS3Iv.css.br +0 -0
  716. codex/static_root/assets/group-tab-CBKuS3Iv.css.gz +0 -0
  717. codex/static_root/assets/http-error-BTOBfcGY.52ced6f28420.js +0 -1
  718. codex/static_root/assets/http-error-BTOBfcGY.52ced6f28420.js.br +0 -0
  719. codex/static_root/assets/http-error-BTOBfcGY.52ced6f28420.js.gz +0 -0
  720. codex/static_root/assets/http-error-BTOBfcGY.js +0 -1
  721. codex/static_root/assets/http-error-BTOBfcGY.js.br +0 -0
  722. codex/static_root/assets/http-error-BTOBfcGY.js.gz +0 -0
  723. codex/static_root/assets/library-tab-Bh7ErAk7.7c44200ee727.css.br +0 -2
  724. codex/static_root/assets/library-tab-Bh7ErAk7.7c44200ee727.css.gz +0 -0
  725. codex/static_root/assets/library-tab-Bh7ErAk7.css.br +0 -2
  726. codex/static_root/assets/library-tab-Bh7ErAk7.css.gz +0 -0
  727. codex/static_root/assets/library-tab-DiPEdOF7.ece2d642a9dc.js +0 -1
  728. codex/static_root/assets/library-tab-DiPEdOF7.ece2d642a9dc.js.br +0 -0
  729. codex/static_root/assets/library-tab-DiPEdOF7.ece2d642a9dc.js.gz +0 -0
  730. codex/static_root/assets/library-tab-DiPEdOF7.js +0 -1
  731. codex/static_root/assets/library-tab-DiPEdOF7.js.br +0 -0
  732. codex/static_root/assets/library-tab-DiPEdOF7.js.gz +0 -0
  733. codex/static_root/assets/main-BPIPjzsc.66def8991e38.js +0 -6
  734. codex/static_root/assets/main-BPIPjzsc.66def8991e38.js.br +0 -0
  735. codex/static_root/assets/main-BPIPjzsc.66def8991e38.js.gz +0 -0
  736. codex/static_root/assets/main-BPIPjzsc.js +0 -6
  737. codex/static_root/assets/main-BPIPjzsc.js.br +0 -0
  738. codex/static_root/assets/main-BPIPjzsc.js.gz +0 -0
  739. codex/static_root/assets/pager-full-pdf-CiyC6Al9.278b9978f36f.js +0 -1
  740. codex/static_root/assets/pager-full-pdf-CiyC6Al9.278b9978f36f.js.br +0 -0
  741. codex/static_root/assets/pager-full-pdf-CiyC6Al9.278b9978f36f.js.gz +0 -0
  742. codex/static_root/assets/pager-full-pdf-CiyC6Al9.js +0 -1
  743. codex/static_root/assets/pager-full-pdf-CiyC6Al9.js.br +0 -0
  744. codex/static_root/assets/pager-full-pdf-CiyC6Al9.js.gz +0 -0
  745. codex/static_root/assets/pagination-toolbar-C45-onwe.4722195bb60b.css.br +0 -0
  746. codex/static_root/assets/pagination-toolbar-C45-onwe.4722195bb60b.css.gz +0 -0
  747. codex/static_root/assets/pagination-toolbar-C45-onwe.css.br +0 -0
  748. codex/static_root/assets/pagination-toolbar-C45-onwe.css.gz +0 -0
  749. codex/static_root/assets/pagination-toolbar-CkIzuyx1.00c354a82e6e.js +0 -1
  750. codex/static_root/assets/pagination-toolbar-CkIzuyx1.00c354a82e6e.js.br +0 -0
  751. codex/static_root/assets/pagination-toolbar-CkIzuyx1.00c354a82e6e.js.gz +0 -0
  752. codex/static_root/assets/pagination-toolbar-CkIzuyx1.js +0 -1
  753. codex/static_root/assets/pagination-toolbar-CkIzuyx1.js.br +0 -0
  754. codex/static_root/assets/pagination-toolbar-CkIzuyx1.js.gz +0 -0
  755. codex/static_root/assets/pdf-doc-BjlRPuf4.0f056fa321b6.js.br +0 -0
  756. codex/static_root/assets/pdf-doc-BjlRPuf4.0f056fa321b6.js.gz +0 -0
  757. codex/static_root/assets/pdf-doc-BjlRPuf4.js.br +0 -0
  758. codex/static_root/assets/pdf-doc-BjlRPuf4.js.gz +0 -0
  759. codex/static_root/assets/reader-_stAWL-4.5089e9144795.css +0 -1
  760. codex/static_root/assets/reader-_stAWL-4.5089e9144795.css.br +0 -0
  761. codex/static_root/assets/reader-_stAWL-4.5089e9144795.css.gz +0 -0
  762. codex/static_root/assets/reader-_stAWL-4.css +0 -1
  763. codex/static_root/assets/reader-_stAWL-4.css.br +0 -0
  764. codex/static_root/assets/reader-_stAWL-4.css.gz +0 -0
  765. codex/static_root/assets/reader-ucxnLi2K.d0fbce0f03c1.js +0 -2
  766. codex/static_root/assets/reader-ucxnLi2K.d0fbce0f03c1.js.br +0 -0
  767. codex/static_root/assets/reader-ucxnLi2K.d0fbce0f03c1.js.gz +0 -0
  768. codex/static_root/assets/reader-ucxnLi2K.js +0 -2
  769. codex/static_root/assets/reader-ucxnLi2K.js.br +0 -0
  770. codex/static_root/assets/reader-ucxnLi2K.js.gz +0 -0
  771. codex/static_root/assets/relation-chips-CUSatZET.a58031ff8141.js +0 -1
  772. codex/static_root/assets/relation-chips-CUSatZET.a58031ff8141.js.br +0 -0
  773. codex/static_root/assets/relation-chips-CUSatZET.a58031ff8141.js.gz +0 -0
  774. codex/static_root/assets/relation-chips-CUSatZET.js +0 -1
  775. codex/static_root/assets/relation-chips-CUSatZET.js.br +0 -0
  776. codex/static_root/assets/relation-chips-CUSatZET.js.gz +0 -0
  777. codex/static_root/assets/settings-drawer-BSHTAsJ9.1d07ce084fc9.js +0 -2
  778. codex/static_root/assets/settings-drawer-BSHTAsJ9.1d07ce084fc9.js.br +0 -0
  779. codex/static_root/assets/settings-drawer-BSHTAsJ9.1d07ce084fc9.js.gz +0 -0
  780. codex/static_root/assets/settings-drawer-BSHTAsJ9.js +0 -2
  781. codex/static_root/assets/settings-drawer-BSHTAsJ9.js.br +0 -0
  782. codex/static_root/assets/settings-drawer-BSHTAsJ9.js.gz +0 -0
  783. codex/static_root/assets/stats-tab-BXGisn5N.9b7a71e7fe28.css.br +0 -0
  784. codex/static_root/assets/stats-tab-BXGisn5N.9b7a71e7fe28.css.gz +0 -0
  785. codex/static_root/assets/stats-tab-BXGisn5N.css.br +0 -0
  786. codex/static_root/assets/stats-tab-BXGisn5N.css.gz +0 -0
  787. codex/static_root/assets/stats-tab-DKXVB2Cc.0a3de58bf5ee.js +0 -1
  788. codex/static_root/assets/stats-tab-DKXVB2Cc.0a3de58bf5ee.js.br +0 -0
  789. codex/static_root/assets/stats-tab-DKXVB2Cc.0a3de58bf5ee.js.gz +0 -0
  790. codex/static_root/assets/stats-tab-DKXVB2Cc.js +0 -1
  791. codex/static_root/assets/stats-tab-DKXVB2Cc.js.br +0 -0
  792. codex/static_root/assets/stats-tab-DKXVB2Cc.js.gz +0 -0
  793. codex/static_root/assets/task-tab-1XiWn9xP.06cb8e1b794d.css +0 -1
  794. codex/static_root/assets/task-tab-1XiWn9xP.06cb8e1b794d.css.gz +0 -0
  795. codex/static_root/assets/task-tab-1XiWn9xP.css +0 -1
  796. codex/static_root/assets/task-tab-1XiWn9xP.css.gz +0 -0
  797. codex/static_root/assets/task-tab-NORFAa9p.97e07e366ddd.js +0 -1
  798. codex/static_root/assets/task-tab-NORFAa9p.97e07e366ddd.js.br +0 -0
  799. codex/static_root/assets/task-tab-NORFAa9p.97e07e366ddd.js.gz +0 -0
  800. codex/static_root/assets/task-tab-NORFAa9p.js +0 -1
  801. codex/static_root/assets/task-tab-NORFAa9p.js.br +0 -0
  802. codex/static_root/assets/task-tab-NORFAa9p.js.gz +0 -0
  803. codex/static_root/assets/unauthorized-RHaQZRfr.a234e9403f60.js +0 -1
  804. codex/static_root/assets/unauthorized-RHaQZRfr.a234e9403f60.js.br +0 -0
  805. codex/static_root/assets/unauthorized-RHaQZRfr.a234e9403f60.js.gz +0 -0
  806. codex/static_root/assets/unauthorized-RHaQZRfr.js +0 -1
  807. codex/static_root/assets/unauthorized-RHaQZRfr.js.br +0 -0
  808. codex/static_root/assets/unauthorized-RHaQZRfr.js.gz +0 -0
  809. codex/static_root/assets/unauthorized-muDsv-rC.2166ec8b3a32.css.br +0 -0
  810. codex/static_root/assets/unauthorized-muDsv-rC.2166ec8b3a32.css.gz +0 -0
  811. codex/static_root/assets/unauthorized-muDsv-rC.css.br +0 -0
  812. codex/static_root/assets/unauthorized-muDsv-rC.css.gz +0 -0
  813. codex/static_root/assets/user-tab-CHbyN1EW.e7206db08680.js +0 -1
  814. codex/static_root/assets/user-tab-CHbyN1EW.e7206db08680.js.br +0 -0
  815. codex/static_root/assets/user-tab-CHbyN1EW.e7206db08680.js.gz +0 -0
  816. codex/static_root/assets/user-tab-CHbyN1EW.js +0 -1
  817. codex/static_root/assets/user-tab-CHbyN1EW.js.br +0 -0
  818. codex/static_root/assets/user-tab-CHbyN1EW.js.gz +0 -0
  819. codex/static_root/js/choices-admin.1a20a5648f20.json +0 -1
  820. codex/static_root/js/choices-admin.1a20a5648f20.json.br +0 -0
  821. codex/static_root/js/choices-admin.1a20a5648f20.json.gz +0 -0
  822. codex/static_root/js/choices-admin.json +0 -1
  823. codex/static_root/js/choices-admin.json.br +0 -0
  824. codex/static_root/js/choices-admin.json.gz +0 -0
  825. codex/static_root/js/choices.2f6b0359e1ef.json +0 -1
  826. codex/static_root/js/choices.2f6b0359e1ef.json.br +0 -0
  827. codex/static_root/js/choices.2f6b0359e1ef.json.gz +0 -0
  828. codex/static_root/js/choices.json +0 -1
  829. codex/static_root/js/choices.json.br +0 -0
  830. codex/static_root/js/choices.json.gz +0 -0
  831. codex/static_root/manifest.0fe31a6cb99f.json +0 -635
  832. codex/static_root/manifest.0fe31a6cb99f.json.br +0 -0
  833. codex/static_root/manifest.0fe31a6cb99f.json.gz +0 -0
  834. codex/templates/search/indexes/codex/comic_text.txt +0 -47
  835. codex/views/browser/annotations.py +0 -296
  836. codex/views/browser/base.py +0 -140
  837. codex/views/browser/filters/annotations.py +0 -103
  838. codex/views/browser/filters/search.py +0 -196
  839. codex/views/browser/metadata.py +0 -332
  840. {codex-1.6.19.dist-info → codex-1.7.0.dist-info}/LICENSE +0 -0
  841. {codex-1.6.19.dist-info → codex-1.7.0.dist-info}/WHEEL +0 -0
  842. {codex-1.6.19.dist-info → codex-1.7.0.dist-info}/entry_points.txt +0 -0
codex/integrity.py DELETED
@@ -1,492 +0,0 @@
1
- """Repair Database Integrity Errors."""
2
-
3
- import re
4
- import sqlite3
5
- from types import MappingProxyType
6
-
7
- from django.apps import apps
8
- from django.contrib.auth import get_user_model
9
- from django.contrib.auth.models import Group
10
- from django.contrib.sessions.models import Session
11
- from django.db import DEFAULT_DB_ALIAS, connection, connections
12
- from django.db.migrations.executor import MigrationExecutor
13
- from django.db.migrations.recorder import MigrationRecorder
14
- from django.db.models.functions import Now
15
- from django.db.models.query import Q
16
- from django.db.utils import OperationalError
17
-
18
- from codex.logger.logging import get_logger
19
- from codex.settings.settings import (
20
- CODEX_PATH,
21
- CONFIG_PATH,
22
- CUSTOM_COVERS_DIR,
23
- DB_PATH,
24
- SKIP_INTEGRITY_CHECK,
25
- )
26
-
27
- NO_MIGRATIONS_TABLE_ERROR = "no such table: django_migrations"
28
- REPAIR_FLAG_PATH = CONFIG_PATH / "rebuild_db"
29
- DUMP_LINE_MATCHER = re.compile("TRANSACTION|ROLLBACK|COMMIT")
30
- REBUILT_DB_PATH = DB_PATH.parent / (DB_PATH.name + ".rebuilt")
31
- BACKUP_DB_PATH = DB_PATH.parent / (DB_PATH.name + ".bak")
32
- MIGRATION_0005 = "0005_auto_20200918_0146"
33
- MIGRATION_0007 = "0007_auto_20211210_1710"
34
- MIGRATION_0010 = "0010_haystack"
35
- MIGRATION_0011 = "0010_library_groups_and_metadata_changes"
36
- MIGRATION_0018 = "0018_rename_userbookmark_bookmark"
37
- MIGRATION_0025 = "0025_add_story_arc_number"
38
- MIGRATION_0026 = "0026_comicbox_1"
39
- MIGRATION_0027 = "0027_import_order_and_covers"
40
- M2M_NAMES = MappingProxyType(
41
- {
42
- "Character": "characters",
43
- "Contributor": "contributors",
44
- "Genre": "genres",
45
- "Location": "locations",
46
- "SeriesGroup": "series_groups",
47
- "StoryArcNumber": "story_arc_numbers",
48
- "Tag": "tags",
49
- "Team": "teams",
50
- "Folder": "folders",
51
- }
52
- )
53
- SKIP_M2M_CHECKS = MappingProxyType(
54
- {"Contributor": MIGRATION_0026, "StoryArcNumber": MIGRATION_0025}
55
- )
56
- NULL_SET = frozenset({None})
57
- HAVE_LIBRARY_FKS = ("FailedImport", "Folder", "Comic", "CustomCover")
58
- GROUP_HOSTS = MappingProxyType(
59
- {
60
- "Imprint": ("Publisher",),
61
- "Series": ("Publisher", "Imprint"),
62
- "Volume": ("Publisher", "Imprint", "Series"),
63
- "Comic": ("Publisher", "Imprint", "Series", "Volume"),
64
- }
65
- )
66
- COMIC_FK_FIELDS = MappingProxyType(
67
- {
68
- "AgeRating": "age_rating",
69
- "Country": "country",
70
- "Language": "language",
71
- "OriginalFormat": "original_format",
72
- "ScanInfo": "scan_info",
73
- "Tagger": "tagger",
74
- }
75
- )
76
- WATCHED_PATHS = ("Comic", "Folder")
77
- CONTRIBUTOR_FIELDS = MappingProxyType(
78
- {"ContributorRole": "role", "ContributorPerson": "person"}
79
- )
80
- OPERATIONAL_ERRORS_BEFORE_MIGRATIONS = (
81
- "no such column: codex_comic.name",
82
- "no such column: codex_comic.stat",
83
- "no such column: codex_folder.stat",
84
- "no such table: codex_comic_folders",
85
- # "no such table: codex_comic_contributors",
86
- "'QuerySet' object has no attribute 'stat'",
87
- )
88
- DELETE_BAD_COMIC_FOLDER_RELATIONS_SQL = (
89
- 'DELETE FROM "codex_comic_folder" '
90
- 'WHERE (NOT ("codex_comic_folder"."comic_id" '
91
- 'IN (SELECT "codex_comic"."id" FROM "codex_comic")) '
92
- 'OR NOT ("codex_comic_folder"."folder_id" '
93
- 'IN (SELECT "codex_folder"."id" FROM "codex_folder")))'
94
- )
95
- MIGRATION_DIR = CODEX_PATH / "migrations"
96
- CUSTOM_COVER_MODEL_NAMES = MappingProxyType(
97
- {"publisher": "p", "imprint": "i", "series": "s", "storyarc": "a", "folder": "f"}
98
- )
99
-
100
- LOG = get_logger(__name__)
101
-
102
-
103
- def has_applied_migration(migration_name):
104
- """Check if a specific migration has been applied."""
105
- return MigrationRecorder.Migration.objects.filter(
106
- app="codex", name=migration_name
107
- ).exists()
108
-
109
-
110
- def has_unapplied_migrations():
111
- """Check if any migrations are outstanding."""
112
- try:
113
- connection = connections[DEFAULT_DB_ALIAS]
114
- connection.prepare_database()
115
- executor = MigrationExecutor(connection)
116
- targets = [
117
- key for key in executor.loader.graph.leaf_nodes() if key[0] == "codex"
118
- ]
119
- plan = executor.migration_plan(targets)
120
- except Exception as exc:
121
- LOG.warning(f"has_unapplied_migrations(): {exc}")
122
- return False
123
- else:
124
- return bool(plan)
125
-
126
-
127
- def _delete_old_comic_folder_fks():
128
- if has_applied_migration(MIGRATION_0007):
129
- return
130
-
131
- try:
132
- with connection.cursor() as cursor:
133
- cursor.execute(DELETE_BAD_COMIC_FOLDER_RELATIONS_SQL)
134
- LOG.info("Deleted old comic_folder relations with bad integrity.")
135
- except Exception:
136
- LOG.exception("Deleting old comic folders")
137
-
138
-
139
- def _fix_comic_m2m_integrity_errors(apps, comic_model, m2m_model_name, field_name):
140
- """Fix Comic ManyToMany integrity errors."""
141
- """Delete relations to comics that don't exist and m2ms that don't exist."""
142
- m2m_model = apps.get_model("codex", m2m_model_name)
143
- field = getattr(comic_model, field_name)
144
- through_model = field.through
145
- link_col = field_name[:-1].replace("_", "") + "_id"
146
-
147
- m2m_rels_with_bad_comic_ids = through_model.objects.exclude(
148
- comic_id__in=comic_model.objects.all()
149
- )
150
- count_comic, _ = m2m_rels_with_bad_comic_ids.delete()
151
- m2m_rels_with_bad_m2m_ids = through_model.objects.exclude(
152
- **{f"{link_col}__in": m2m_model.objects.all()}
153
- )
154
- bad_comic_ids = comic_model.objects.filter(
155
- pk__in=m2m_rels_with_bad_m2m_ids.values_list("comic_id", flat=True)
156
- ).values_list("pk", flat=True)
157
- count_m2m, _ = m2m_rels_with_bad_m2m_ids.delete()
158
- count = count_comic + count_m2m
159
- if count:
160
- LOG.info(f"Deleted {count} orphan relations to {field_name}")
161
- return frozenset(bad_comic_ids)
162
-
163
-
164
- def _fix_comic_fk_integrity_errors(apps, comic_model, fk_model_name, field_name):
165
- fk_model = apps.get_model("codex", fk_model_name)
166
- bad_pks = _null_missing_fk(comic_model, fk_model, field_name)
167
- getattr(comic_model, field_name)
168
- count = len(bad_pks)
169
- if count:
170
- LOG.info(f"Deleted {count} {field_name} links to missing rows.")
171
- return frozenset(bad_pks)
172
-
173
-
174
- def _mark_comics_with_bad_rels_for_update(comic_model, bad_comic_ids):
175
- """Mark affected comics for update."""
176
- try:
177
- update_comics = []
178
- bad_comics = comic_model.objects.filter(pk__in=bad_comic_ids).only("stat")
179
-
180
- for comic in bad_comics:
181
- stat_list = comic.stat
182
- if not stat_list:
183
- continue
184
- stat_list[8] = 0.0
185
- comic.stat = stat_list
186
- update_comics.append(comic)
187
-
188
- if not update_comics:
189
- return
190
-
191
- count = comic_model.objects.bulk_update(update_comics, fields=["stat"])
192
- LOG.info(f"Marked {count} comics with bad relations for update by poller.")
193
- except (OperationalError, AttributeError) as exc:
194
- ok = False
195
- for arg in exc.args:
196
- if arg in OPERATIONAL_ERRORS_BEFORE_MIGRATIONS:
197
- LOG.debug(
198
- "Can't mark modified comics for update, "
199
- "but if this happens right before migration 0007, "
200
- "they'll be updated anyway."
201
- )
202
- ok = True
203
- if not ok:
204
- LOG.exception("Mark comics with bad relations for update.")
205
-
206
-
207
- def _find_fk_integrity_errors_with_models(
208
- host_model, fk_model, fk_field_name, log=True
209
- ):
210
- """Find foreign key integrity errors with specified models."""
211
- inner_qs = fk_model.objects.all()
212
- exclude_filter = {f"{fk_field_name}__in": inner_qs}
213
- invalid_host_objs = host_model.objects.exclude(**exclude_filter).only(fk_field_name)
214
- if fk_field_name in ("parent_folder", "role"):
215
- # Special fields can be null
216
- # THIS IS VERY IMPORTANT TO AVOID DELETING ALL TOP LEVEL FOLDERS
217
- not_null_filter = {f"{fk_field_name}__isnull": False}
218
- invalid_host_objs = invalid_host_objs.filter(**not_null_filter)
219
-
220
- count = invalid_host_objs.count()
221
- if count and log:
222
- LOG.info(f"Found {host_model.__name__}s with bad {fk_field_name}: {count}")
223
- return invalid_host_objs
224
-
225
-
226
- def _find_fk_integrity_errors(apps, host_model_name, fk_model_name, fk_field_name):
227
- """Find foreign key integrity errors."""
228
- host_model = apps.get_model("codex", host_model_name)
229
- fk_model = apps.get_model("codex", fk_model_name)
230
- return _find_fk_integrity_errors_with_models(host_model, fk_model, fk_field_name)
231
-
232
-
233
- def _delete_query(query, host_model_name, fk_model_name):
234
- """Execute the delete on the query."""
235
- count, _ = query.delete()
236
- if count:
237
- LOG.info(f"Deleted {count} {host_model_name}s in nonextant {fk_model_name}s.")
238
-
239
-
240
- def _delete_fk_integrity_errors(apps, host_model_name, fk_model_name, fk_field_name):
241
- """Delete objects with bad integrity."""
242
- try:
243
- if not has_applied_migration(MIGRATION_0026) and (
244
- host_model_name == "Contributor"
245
- or fk_model_name == "Contributor"
246
- or fk_field_name == "contributors"
247
- ):
248
- LOG.debug(
249
- "Skipping Contributor integrity check until"
250
- f"migration {MIGRATION_0026} applied."
251
- )
252
- return
253
-
254
- bad_host_objs = _find_fk_integrity_errors(
255
- apps, host_model_name, fk_model_name, fk_field_name
256
- )
257
- _delete_query(bad_host_objs, host_model_name, fk_model_name)
258
- except OperationalError as exc:
259
- ok = False
260
- for arg in exc.args:
261
- if arg in OPERATIONAL_ERRORS_BEFORE_MIGRATIONS:
262
- ok = True
263
- if not ok:
264
- LOG.exception("Operational error before migrations")
265
- except Exception:
266
- LOG.exception("Delete foreign key integrity errors.")
267
-
268
-
269
- def _null_missing_fk(host_model, fk_model, fk_field_name):
270
- """Set missing fks to null."""
271
- query_missing_fks = _find_fk_integrity_errors_with_models(
272
- host_model, fk_model, fk_field_name, log=False
273
- )
274
- not_null_filter = {f"{fk_field_name}__isnull": False}
275
- query_missing_fks = query_missing_fks.filter(**not_null_filter)
276
- count = query_missing_fks.count()
277
- if count:
278
- update_dict = {fk_field_name: None, "updated_at": Now()}
279
- query_missing_fks.update(**update_dict)
280
- LOG.info(f"Fixed {count} {host_model.__name__}s with missing {fk_field_name}")
281
- return query_missing_fks.values_list("pk", flat=True)
282
-
283
-
284
- def _delete_bookmark_integrity_errors(apps):
285
- """Fix Bookmarks with non codex model fields."""
286
- if not has_applied_migration(MIGRATION_0018):
287
- return
288
- # Bookmarks that don't reference a valid comic are useless.
289
- _delete_fk_integrity_errors(apps, "Bookmark", "Comic", "comic")
290
-
291
- # Bookmarks that aren't linked to a valid session or a user are orphans
292
- bm_model = apps.get_model("codex", "Bookmark")
293
- _null_missing_fk(bm_model, Session, "session")
294
- _null_missing_fk(bm_model, get_user_model(), "user")
295
- orphan_bms = bm_model.objects.filter(session=None, user=None)
296
- _delete_query(orphan_bms, "Bookmark", "session or user")
297
-
298
-
299
- def _repair_library_groups(apps):
300
- """Remove non-extant groups from libraries."""
301
- if not has_applied_migration(MIGRATION_0011):
302
- return
303
- library_model = apps.get_model("codex", "library")
304
- through_model = library_model.groups.through
305
- valid_groups = Group.objects.all()
306
- bad_relations = through_model.objects.exclude(group_id__in=valid_groups)
307
- bad_relations.delete()
308
-
309
-
310
- def _delete_extra_custom_cover_libraries(apps):
311
- if not has_applied_migration(MIGRATION_0027):
312
- return
313
- library_model = apps.get_model("codex", "library")
314
- custom_cover_libraries = library_model.objects.filter(covers_only=True)
315
- if custom_cover_libraries.count() <= 1:
316
- return
317
-
318
- # Attempt to remove the bad ones, probably futile
319
- bad_lib_pks = []
320
- for library in custom_cover_libraries:
321
- if library.path != CUSTOM_COVERS_DIR:
322
- bad_lib_pks.append(library.pk)
323
- delete_libs = library_model.object.filter(pk__in=bad_lib_pks)
324
- count = delete_libs.count()
325
- if count:
326
- delete_libs.delete()
327
- LOG.warn(
328
- f"Removed {count} duplicate custom cover libraries pointing to unused custom cover dirs."
329
- )
330
-
331
- custom_cover_libraries = library_model.object.filter(covers_only=True)
332
- count = custom_cover_libraries.count()
333
- if count <= 1:
334
- return
335
- custom_cover_libraries.delete()
336
- LOG.warn(
337
- f"Removed all ({count}) custom cover libraries, Unable to determine valid one. Will recreate upon startup."
338
- )
339
-
340
-
341
- def _repair_groups_with_custom_covers(apps):
342
- if not has_applied_migration(MIGRATION_0027):
343
- return
344
- custom_cover_model = apps.get_model("codex", "customcover")
345
- for model_name, group_letter in CUSTOM_COVER_MODEL_NAMES.items():
346
- valid_covers = custom_cover_model.objects.filter(group=group_letter)
347
- group_model = apps.get_model("codex", model_name)
348
- objs = group_model.objects.exclude(
349
- Q(custom_cover__isnull=True) | Q(custom_cover__in=valid_covers)
350
- )
351
- update_groups = []
352
- for group in objs:
353
- group.custom_cover = None
354
- group.updated_at = Now()
355
- update_groups.append(group)
356
- group_model.objects.bulk_update(update_groups, ["custom_cover"])
357
- count = len(update_groups)
358
- if count:
359
- LOG.warn(f"Removed illegal custom cover links from {count} {model_name}s")
360
-
361
-
362
- def _delete_errors():
363
- """DELETE things we can't fix."""
364
- _delete_extra_custom_cover_libraries(apps)
365
-
366
- for host_model_name in HAVE_LIBRARY_FKS:
367
- if host_model_name == "CustomCover" and not has_applied_migration(
368
- MIGRATION_0027
369
- ):
370
- continue
371
- _delete_fk_integrity_errors(apps, host_model_name, "Library", "library")
372
-
373
- for host_model_name in WATCHED_PATHS:
374
- _delete_fk_integrity_errors(apps, host_model_name, "Folder", "parent_folder")
375
-
376
- for host_model_name, groups in GROUP_HOSTS.items():
377
- for group_model_name in groups:
378
- group_field_name = group_model_name.lower()
379
- _delete_fk_integrity_errors(
380
- apps, host_model_name, group_model_name, group_field_name
381
- )
382
-
383
- if has_applied_migration(MIGRATION_0026):
384
- for fk_model_name in COMIC_FK_FIELDS:
385
- _delete_fk_integrity_errors(apps, fk_model_name, "Comic", "comic")
386
-
387
- for fk_model_name, fk_field_name in CONTRIBUTOR_FIELDS.items():
388
- _delete_fk_integrity_errors(apps, "Contributor", fk_model_name, fk_field_name)
389
-
390
- _delete_bookmark_integrity_errors(apps)
391
-
392
- _delete_old_comic_folder_fks()
393
-
394
-
395
- def _check_field_for_migration(model_name):
396
- """Skip some models before migrations."""
397
- for check_model_name, migration in SKIP_M2M_CHECKS.items():
398
- if model_name == check_model_name and not has_applied_migration(migration):
399
- LOG.debug(
400
- f"Skipping {check_model_name} integrity check until"
401
- f" migration {migration} applied."
402
- )
403
- return True
404
- return False
405
-
406
-
407
- def _repair_integrity():
408
- """REPAIR the objects that are left."""
409
- comic_model = apps.get_model("codex", "Comic")
410
- bad_comic_ids = set()
411
- for m2m_model_name, field_name in M2M_NAMES.items():
412
- if _check_field_for_migration(m2m_model_name):
413
- continue
414
- try:
415
- bad_comic_ids |= _fix_comic_m2m_integrity_errors(
416
- apps, comic_model, m2m_model_name, field_name
417
- )
418
- except OperationalError as exc:
419
- ok = False
420
- for arg in exc.args:
421
- if arg in OPERATIONAL_ERRORS_BEFORE_MIGRATIONS:
422
- ok = True
423
- if ok:
424
- LOG.info(
425
- "Couldn't look for comics with folder integrity problems before "
426
- "migration 0007. We'll get them on the next restart."
427
- )
428
- else:
429
- LOG.exception("Occurred after migration 0007")
430
-
431
- if has_applied_migration(MIGRATION_0026):
432
- for fk_model_name, field_name in COMIC_FK_FIELDS.items():
433
- try:
434
- bad_comic_ids |= _fix_comic_fk_integrity_errors(
435
- apps, comic_model, fk_model_name, field_name
436
- )
437
- except Exception:
438
- LOG.exception(f"Fix fk integrity error {fk_model_name}")
439
-
440
- _mark_comics_with_bad_rels_for_update(comic_model, bad_comic_ids)
441
-
442
- _repair_library_groups(apps)
443
- _repair_groups_with_custom_covers(apps)
444
-
445
-
446
- def repair_db():
447
- """Fix the db but trap errors if it goes wrong."""
448
- try:
449
- if SKIP_INTEGRITY_CHECK:
450
- LOG.info("Skipping integrity check")
451
- return
452
-
453
- if not has_applied_migration(MIGRATION_0005):
454
- LOG.info(
455
- "Not running integrity checks until migration"
456
- f"{MIGRATION_0005} has been applied."
457
- )
458
- return
459
-
460
- LOG.debug("Reparing database integrity...")
461
- _delete_errors()
462
- _repair_integrity()
463
- LOG.info("Database integrity confirmed.")
464
- except OperationalError as exc:
465
- if NO_MIGRATIONS_TABLE_ERROR in exc.args:
466
- LOG.debug("Database not constructed yet, skipping integrity check.")
467
- else:
468
- raise
469
- except Exception:
470
- LOG.exception("Repair DB")
471
-
472
-
473
- def rebuild_db():
474
- """Dump and rebuild the database."""
475
- # Drastic
476
- if not REPAIR_FLAG_PATH.exists():
477
- return
478
-
479
- LOG.warning("REBUILDING DATABASE!!")
480
- with sqlite3.connect(REBUILT_DB_PATH) as new_db_conn:
481
- new_db_cur = new_db_conn.cursor()
482
- with sqlite3.connect(DB_PATH) as old_db_conn:
483
- for line in old_db_conn.iterdump():
484
- if DUMP_LINE_MATCHER.search(line):
485
- continue
486
- new_db_cur.execute(line)
487
-
488
- DB_PATH.rename(BACKUP_DB_PATH)
489
- LOG.info("Backed up old db to %s", BACKUP_DB_PATH)
490
- REBUILT_DB_PATH.replace(DB_PATH)
491
- REPAIR_FLAG_PATH.unlink(missing_ok=True)
492
- LOG.info("Rebuilt database.")
@@ -1,86 +0,0 @@
1
- """Search Index Merging for Read Optimization."""
2
-
3
- from pathlib import Path
4
- from time import time
5
- from typing import TYPE_CHECKING
6
-
7
- from humanize import naturaldelta, naturalsize
8
-
9
- from codex.librarian.search.status import SearchIndexStatusTypes
10
- from codex.librarian.search.version import VersionMixin
11
- from codex.settings.settings import SEARCH_INDEX_PATH
12
- from codex.status import Status
13
-
14
- if TYPE_CHECKING:
15
- from codex.search.backend import CodexSearchBackend
16
-
17
-
18
- class MergeMixin(VersionMixin):
19
- """Search Index Merge Methods."""
20
-
21
- def _is_index_optimized(self, num_segments):
22
- """Is the index already in one segment."""
23
- if num_segments <= 1:
24
- self.log.info("Search index already optimized.")
25
- return True
26
- return False
27
-
28
- @staticmethod
29
- def _get_segments_and_len():
30
- segments = SEARCH_INDEX_PATH.glob("*.seg")
31
- num_segments = len(tuple(segments))
32
- return segments, num_segments
33
-
34
- @staticmethod
35
- def _get_segments_size(segments):
36
- size = 0
37
- for segment in segments:
38
- size += Path(segment).stat().st_size
39
- return size
40
-
41
- def _merge_search_index(self, optimize, status, name):
42
- """Optimize search index."""
43
- self.status_controller.start(status)
44
- start = time()
45
-
46
- segments, old_num_segments = self._get_segments_and_len()
47
- if self._is_index_optimized(old_num_segments):
48
- return
49
- self.status_controller.start(status)
50
- old_size = self._get_segments_size(segments)
51
- # Optimize
52
- self.log.info(
53
- f"Search index found in {old_num_segments} segments," f" merging {name}..."
54
- )
55
- backend: CodexSearchBackend = self.engine.get_backend() # type: ignore
56
- if optimize:
57
- backend.optimize()
58
- else:
59
- backend.merge_small()
60
-
61
- # Finish
62
- segments, new_num_segments = self._get_segments_and_len()
63
- new_size = self._get_segments_size(segments)
64
- saved = naturalsize(old_size - new_size)
65
- num_segments_diff = old_num_segments - new_num_segments
66
- elapsed_time = time() - start
67
- elapsed = naturaldelta(elapsed_time)
68
- if num_segments_diff:
69
- self.log.info(
70
- f"Merged {num_segments_diff} search index segments in {elapsed}."
71
- f"Saved {saved}."
72
- )
73
- else:
74
- self.log.info("No small search index segments found.")
75
-
76
- def merge_search_index(self, optimize=False):
77
- """Optimize search index, trapping exceptions."""
78
- verb = "All" if optimize else "Small"
79
- name = f"Merge {verb} Segments"
80
- status = Status(SearchIndexStatusTypes.SEARCH_INDEX_MERGE, subtitle=name)
81
- try:
82
- self._merge_search_index(optimize, status, name)
83
- except Exception:
84
- self.log.exception("Search index merge.")
85
- finally:
86
- self.status_controller.finish(status)
@@ -1,63 +0,0 @@
1
- """Search Engine to database matching."""
2
-
3
- from uuid import uuid4
4
-
5
- from codex.librarian.search.tasks import SearchIndexUpdateTask
6
- from codex.models import Timestamp
7
- from codex.search.engine import CodexSearchEngine
8
- from codex.settings.settings import SEARCH_INDEX_PATH, SEARCH_INDEX_UUID_PATH
9
- from codex.threads import QueuedThread
10
-
11
-
12
- class VersionMixin(QueuedThread):
13
- """Search Engine to database matching methods."""
14
-
15
- def __init__(self, abort_event, *args, **kwargs):
16
- """Initialize search engine."""
17
- self.abort_event = abort_event
18
- super().__init__(*args, **kwargs)
19
- queue_kwargs = {
20
- "log_queue": self.log_queue,
21
- "librarian_queue": self.librarian_queue,
22
- }
23
- self.engine = CodexSearchEngine(queue_kwargs=queue_kwargs)
24
-
25
- def set_search_index_version(self):
26
- """Set the codex db to search index matching id."""
27
- version = str(uuid4())
28
- try:
29
- lv = Timestamp.objects.get(
30
- key=Timestamp.TimestampChoices.SEARCH_INDEX_UUID.value
31
- )
32
- lv.version = version
33
- lv.save()
34
- SEARCH_INDEX_PATH.mkdir(parents=True, exist_ok=True)
35
- with SEARCH_INDEX_UUID_PATH.open("w") as uuid_file:
36
- uuid_file.write(version)
37
- except Exception:
38
- self.log.exception("Setting search index to db synchronization token")
39
-
40
- def is_search_index_uuid_match(self):
41
- """Is this search index for this database."""
42
- result = False
43
- try:
44
- with SEARCH_INDEX_UUID_PATH.open("r") as uuid_file:
45
- version = uuid_file.read()
46
- result = Timestamp.objects.filter(
47
- key=Timestamp.TimestampChoices.SEARCH_INDEX_UUID.value, version=version
48
- ).exists()
49
- except (FileNotFoundError, Timestamp.DoesNotExist):
50
- pass
51
- except Exception:
52
- self.log.exception("Does search index match database uuid")
53
- if not result:
54
- self.log.warning("Database does not match search index.")
55
- return result
56
-
57
- def rebuild_search_index_if_db_changed(self):
58
- """Rebuild the search index if the db changed."""
59
- if not self.is_search_index_uuid_match():
60
- task = SearchIndexUpdateTask(True)
61
- self.librarian_queue.put(task)
62
- else:
63
- self.log.info("Database matches search index.")
codex/search/__init__.py DELETED
@@ -1 +0,0 @@
1
- """Haystack Search Customizations."""