codex 1.5.13__py3-none-any.whl → 1.5.13a0__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 (397) hide show
  1. codex/applications/websocket.py +7 -1
  2. codex/librarian/importer/query_fks.py +0 -1
  3. codex/serializers/browser/settings.py +1 -0
  4. codex/serializers/choices.py +2 -1
  5. codex/settings/settings.py +5 -0
  6. codex/signals/django_signals.py +6 -0
  7. codex/static_root/assets/{VCheckbox-Wdu19ZuZ.50f2bf3b5ce5.js → VCheckbox-BMRDCYNv.7f791d7f065f.js} +1 -1
  8. codex/static_root/assets/VCheckbox-BMRDCYNv.7f791d7f065f.js.br +0 -0
  9. codex/static_root/assets/VCheckbox-BMRDCYNv.7f791d7f065f.js.gz +0 -0
  10. codex/static_root/assets/{VCheckbox-Wdu19ZuZ.js → VCheckbox-BMRDCYNv.js} +1 -1
  11. codex/static_root/assets/VCheckbox-BMRDCYNv.js.br +0 -0
  12. codex/static_root/assets/VCheckbox-BMRDCYNv.js.gz +0 -0
  13. codex/static_root/assets/{VCheckboxBtn-C7NngFC8.bd12ea5cdbb2.js → VCheckboxBtn-Dqp1u3GT.e80f145994b6.js} +1 -1
  14. codex/static_root/assets/VCheckboxBtn-Dqp1u3GT.e80f145994b6.js.br +0 -0
  15. codex/static_root/assets/VCheckboxBtn-Dqp1u3GT.e80f145994b6.js.gz +0 -0
  16. codex/static_root/assets/{VCheckboxBtn-C7NngFC8.js → VCheckboxBtn-Dqp1u3GT.js} +1 -1
  17. codex/static_root/assets/VCheckboxBtn-Dqp1u3GT.js.br +0 -0
  18. codex/static_root/assets/VCheckboxBtn-Dqp1u3GT.js.gz +0 -0
  19. codex/static_root/assets/{VCombobox-DxNlm_ji.11d317a5dbb0.js → VCombobox-DT52mZm3.309c77be4a55.js} +1 -1
  20. codex/static_root/assets/VCombobox-DT52mZm3.309c77be4a55.js.br +0 -0
  21. codex/static_root/assets/VCombobox-DT52mZm3.309c77be4a55.js.gz +0 -0
  22. codex/static_root/assets/{VCombobox-DxNlm_ji.js → VCombobox-DT52mZm3.js} +1 -1
  23. codex/static_root/assets/VCombobox-DT52mZm3.js.br +0 -0
  24. codex/static_root/assets/VCombobox-DT52mZm3.js.gz +0 -0
  25. codex/static_root/assets/{VDataTableVirtual-C4UTS-jp.4b2926f1461f.js → VDataTableVirtual-DhhCmPtf.0735a1ab4c2f.js} +1 -1
  26. codex/static_root/assets/VDataTableVirtual-DhhCmPtf.0735a1ab4c2f.js.br +0 -0
  27. codex/static_root/assets/VDataTableVirtual-DhhCmPtf.0735a1ab4c2f.js.gz +0 -0
  28. codex/static_root/assets/{VDataTableVirtual-C4UTS-jp.js → VDataTableVirtual-DhhCmPtf.js} +1 -1
  29. codex/static_root/assets/VDataTableVirtual-DhhCmPtf.js.br +0 -0
  30. codex/static_root/assets/VDataTableVirtual-DhhCmPtf.js.gz +0 -0
  31. codex/static_root/assets/{VExpansionPanel-1dRZTsNe.6213946f43dd.js → VExpansionPanel-C593uXqT.d3bdc6a21208.js} +1 -1
  32. codex/static_root/assets/VExpansionPanel-C593uXqT.d3bdc6a21208.js.br +0 -0
  33. codex/static_root/assets/VExpansionPanel-C593uXqT.d3bdc6a21208.js.gz +0 -0
  34. codex/static_root/assets/{VExpansionPanel-1dRZTsNe.js → VExpansionPanel-C593uXqT.js} +1 -1
  35. codex/static_root/assets/VExpansionPanel-C593uXqT.js.br +0 -0
  36. codex/static_root/assets/VExpansionPanel-C593uXqT.js.gz +0 -0
  37. codex/static_root/assets/{VMain-BVEH6Gtw.51ef468a0780.js → VMain-DmQvRj_k.1e0480bed9a6.js} +1 -1
  38. codex/static_root/assets/VMain-DmQvRj_k.1e0480bed9a6.js.br +0 -0
  39. codex/static_root/assets/VMain-DmQvRj_k.1e0480bed9a6.js.gz +0 -0
  40. codex/static_root/assets/{VMain-BVEH6Gtw.js → VMain-DmQvRj_k.js} +1 -1
  41. codex/static_root/assets/VMain-DmQvRj_k.js.br +0 -0
  42. codex/static_root/assets/VMain-DmQvRj_k.js.gz +0 -0
  43. codex/static_root/assets/{VRadioGroup-D1WV2cpK.83ba2e5689fd.js → VRadioGroup-Bi16yPEE.69086b77f9b1.js} +1 -1
  44. codex/static_root/assets/VRadioGroup-Bi16yPEE.69086b77f9b1.js.br +0 -0
  45. codex/static_root/assets/VRadioGroup-Bi16yPEE.69086b77f9b1.js.gz +0 -0
  46. codex/static_root/assets/{VRadioGroup-D1WV2cpK.js → VRadioGroup-Bi16yPEE.js} +1 -1
  47. codex/static_root/assets/VRadioGroup-Bi16yPEE.js.br +0 -0
  48. codex/static_root/assets/VRadioGroup-Bi16yPEE.js.gz +0 -0
  49. codex/static_root/assets/{VSelect-BVyqMxyX.4a54cd987085.js → VSelect-BdaijxdJ.b969ab260593.js} +1 -1
  50. codex/static_root/assets/VSelect-BdaijxdJ.b969ab260593.js.br +0 -0
  51. codex/static_root/assets/VSelect-BdaijxdJ.b969ab260593.js.gz +0 -0
  52. codex/static_root/assets/{VSelect-BVyqMxyX.js → VSelect-BdaijxdJ.js} +1 -1
  53. codex/static_root/assets/VSelect-BdaijxdJ.js.br +0 -0
  54. codex/static_root/assets/VSelect-BdaijxdJ.js.gz +0 -0
  55. codex/static_root/assets/{VSelectionControl-CC9aC7ZT.2db18d99af8b.js → VSelectionControl-CuM4okF6.0f246e35e86f.js} +1 -1
  56. codex/static_root/assets/VSelectionControl-CuM4okF6.0f246e35e86f.js.br +0 -0
  57. codex/static_root/assets/VSelectionControl-CuM4okF6.0f246e35e86f.js.gz +0 -0
  58. codex/static_root/assets/{VSelectionControl-CC9aC7ZT.js → VSelectionControl-CuM4okF6.js} +1 -1
  59. codex/static_root/assets/VSelectionControl-CuM4okF6.js.br +0 -0
  60. codex/static_root/assets/VSelectionControl-CuM4okF6.js.gz +0 -0
  61. codex/static_root/assets/{VSlideGroup-D4n-jSgi.686cc428f5fe.js → VSlideGroup-ztBraz6g.02a0bc55b207.js} +1 -1
  62. codex/static_root/assets/VSlideGroup-ztBraz6g.02a0bc55b207.js.br +0 -0
  63. codex/static_root/assets/VSlideGroup-ztBraz6g.02a0bc55b207.js.gz +0 -0
  64. codex/static_root/assets/{VSlideGroup-D4n-jSgi.js → VSlideGroup-ztBraz6g.js} +1 -1
  65. codex/static_root/assets/VSlideGroup-ztBraz6g.js.br +0 -0
  66. codex/static_root/assets/VSlideGroup-ztBraz6g.js.gz +0 -0
  67. codex/static_root/assets/{VTable-DioYRJkC.c8638b2267ed.js → VTable-CGuSv-Tv.eddaf5526d93.js} +1 -1
  68. codex/static_root/assets/VTable-CGuSv-Tv.eddaf5526d93.js.br +0 -0
  69. codex/static_root/assets/VTable-CGuSv-Tv.eddaf5526d93.js.gz +0 -0
  70. codex/static_root/assets/{VTable-DioYRJkC.js → VTable-CGuSv-Tv.js} +1 -1
  71. codex/static_root/assets/VTable-CGuSv-Tv.js.br +0 -0
  72. codex/static_root/assets/VTable-CGuSv-Tv.js.gz +0 -0
  73. codex/static_root/assets/{VToolbar-DLtG5Ngs.e32539656f6d.js → VToolbar-CAUhD2BO.279f0b52347a.js} +2 -2
  74. codex/static_root/assets/VToolbar-CAUhD2BO.279f0b52347a.js.br +0 -0
  75. codex/static_root/assets/VToolbar-CAUhD2BO.279f0b52347a.js.gz +0 -0
  76. codex/static_root/assets/{VToolbar-DLtG5Ngs.js → VToolbar-CAUhD2BO.js} +2 -2
  77. codex/static_root/assets/VToolbar-CAUhD2BO.js.br +0 -0
  78. codex/static_root/assets/VToolbar-CAUhD2BO.js.gz +0 -0
  79. codex/static_root/assets/{VWindowItem-D-OB7e0u.ef9bcb84a01e.js → VWindowItem-YvmNwCNb.20a7e3b303de.js} +1 -1
  80. codex/static_root/assets/VWindowItem-YvmNwCNb.20a7e3b303de.js.br +0 -0
  81. codex/static_root/assets/VWindowItem-YvmNwCNb.20a7e3b303de.js.gz +0 -0
  82. codex/static_root/assets/{VWindowItem-D-OB7e0u.js → VWindowItem-YvmNwCNb.js} +1 -1
  83. codex/static_root/assets/VWindowItem-YvmNwCNb.js.br +0 -0
  84. codex/static_root/assets/VWindowItem-YvmNwCNb.js.gz +0 -0
  85. codex/static_root/assets/{admin-BwXMQOyX.8c44117c2b63.js → admin-Ch9WezG1.bdace86b7c25.js} +1 -1
  86. codex/static_root/assets/admin-Ch9WezG1.bdace86b7c25.js.br +0 -0
  87. codex/static_root/assets/admin-Ch9WezG1.bdace86b7c25.js.gz +0 -0
  88. codex/static_root/assets/{admin-BwXMQOyX.js → admin-Ch9WezG1.js} +1 -1
  89. codex/static_root/assets/admin-Ch9WezG1.js.br +0 -0
  90. codex/static_root/assets/admin-Ch9WezG1.js.gz +0 -0
  91. codex/static_root/assets/{admin-drawer-panel-CGj6J0rX.cc680f2603da.js → admin-drawer-panel-B4VvGE4s.2265b9de60ab.js} +1 -1
  92. codex/static_root/assets/admin-drawer-panel-B4VvGE4s.2265b9de60ab.js.br +0 -0
  93. codex/static_root/assets/admin-drawer-panel-B4VvGE4s.2265b9de60ab.js.gz +0 -0
  94. codex/static_root/assets/{admin-drawer-panel-CGj6J0rX.js → admin-drawer-panel-B4VvGE4s.js} +1 -1
  95. codex/static_root/assets/admin-drawer-panel-B4VvGE4s.js.br +0 -0
  96. codex/static_root/assets/admin-drawer-panel-B4VvGE4s.js.gz +0 -0
  97. codex/static_root/assets/browser-BTel3sYS.8e1515bc039a.js +1 -0
  98. codex/static_root/assets/browser-BTel3sYS.8e1515bc039a.js.br +0 -0
  99. codex/static_root/assets/browser-BTel3sYS.8e1515bc039a.js.gz +0 -0
  100. codex/static_root/assets/browser-BTel3sYS.js +1 -0
  101. codex/static_root/assets/browser-BTel3sYS.js.br +0 -0
  102. codex/static_root/assets/browser-BTel3sYS.js.gz +0 -0
  103. codex/static_root/assets/{browser-CTxEKlCx.211d729d9165.css → browser-CVvV08AM.7667051b18fa.css} +1 -1
  104. codex/static_root/assets/browser-CVvV08AM.7667051b18fa.css.br +0 -0
  105. codex/static_root/assets/browser-CVvV08AM.7667051b18fa.css.gz +0 -0
  106. codex/static_root/assets/{browser-CTxEKlCx.css → browser-CVvV08AM.css} +1 -1
  107. codex/static_root/assets/browser-CVvV08AM.css.br +0 -0
  108. codex/static_root/assets/browser-CVvV08AM.css.gz +0 -0
  109. codex/static_root/assets/{change-password-dialog-DDvVSrWH.915709700c5f.js → change-password-dialog-Dq6GjT1T.01b56b4b3e87.js} +1 -1
  110. codex/static_root/assets/change-password-dialog-Dq6GjT1T.01b56b4b3e87.js.br +0 -0
  111. codex/static_root/assets/change-password-dialog-Dq6GjT1T.01b56b4b3e87.js.gz +0 -0
  112. codex/static_root/assets/{change-password-dialog-DDvVSrWH.js → change-password-dialog-Dq6GjT1T.js} +1 -1
  113. codex/static_root/assets/change-password-dialog-Dq6GjT1T.js.br +0 -0
  114. codex/static_root/assets/change-password-dialog-Dq6GjT1T.js.gz +0 -0
  115. codex/static_root/assets/{confirm-dialog-Bf3Sde_o.b437109b579e.js → confirm-dialog-D-Fx-51m.54b7d1059106.js} +1 -1
  116. codex/static_root/assets/confirm-dialog-D-Fx-51m.54b7d1059106.js.br +0 -0
  117. codex/static_root/assets/confirm-dialog-D-Fx-51m.54b7d1059106.js.gz +0 -0
  118. codex/static_root/assets/{confirm-dialog-Bf3Sde_o.js → confirm-dialog-D-Fx-51m.js} +1 -1
  119. codex/static_root/assets/confirm-dialog-D-Fx-51m.js.br +0 -0
  120. codex/static_root/assets/confirm-dialog-D-Fx-51m.js.gz +0 -0
  121. codex/static_root/assets/{confirm-footer-CLwOC3F0.js → confirm-footer-Yn7T9Tns.75a17cd86ca9.js} +1 -1
  122. codex/static_root/assets/confirm-footer-Yn7T9Tns.75a17cd86ca9.js.br +0 -0
  123. codex/static_root/assets/confirm-footer-Yn7T9Tns.75a17cd86ca9.js.gz +0 -0
  124. codex/static_root/assets/{confirm-footer-CLwOC3F0.d25d9085b300.js → confirm-footer-Yn7T9Tns.js} +1 -1
  125. codex/static_root/assets/confirm-footer-Yn7T9Tns.js.br +0 -0
  126. codex/static_root/assets/confirm-footer-Yn7T9Tns.js.gz +0 -0
  127. codex/static_root/assets/{datetime-column-DGfoC2Ap.ef9499c6bca8.js → datetime-column-DCeBthsr.22ed49a999cc.js} +1 -1
  128. codex/static_root/assets/datetime-column-DCeBthsr.22ed49a999cc.js.br +0 -0
  129. codex/static_root/assets/datetime-column-DCeBthsr.22ed49a999cc.js.gz +0 -0
  130. codex/static_root/assets/{datetime-column-DGfoC2Ap.js → datetime-column-DCeBthsr.js} +1 -1
  131. codex/static_root/assets/datetime-column-DCeBthsr.js.br +0 -0
  132. codex/static_root/assets/datetime-column-DCeBthsr.js.gz +0 -0
  133. codex/static_root/assets/{filter-DcOs3rVI.495426fbd29e.js → filter-Dw0fjwZi.4d5f085435ab.js} +1 -1
  134. codex/static_root/assets/filter-Dw0fjwZi.4d5f085435ab.js.br +0 -0
  135. codex/static_root/assets/filter-Dw0fjwZi.4d5f085435ab.js.gz +0 -0
  136. codex/static_root/assets/{filter-DcOs3rVI.js → filter-Dw0fjwZi.js} +1 -1
  137. codex/static_root/assets/filter-Dw0fjwZi.js.br +0 -0
  138. codex/static_root/assets/filter-Dw0fjwZi.js.gz +0 -0
  139. codex/static_root/assets/{flag-tab-D77e2Ors.068789b9d816.js → flag-tab-D5RcLFbQ.1073708ea164.js} +1 -1
  140. codex/static_root/assets/flag-tab-D5RcLFbQ.1073708ea164.js.br +0 -0
  141. codex/static_root/assets/flag-tab-D5RcLFbQ.1073708ea164.js.gz +0 -0
  142. codex/static_root/assets/{flag-tab-D77e2Ors.js → flag-tab-D5RcLFbQ.js} +1 -1
  143. codex/static_root/assets/flag-tab-D5RcLFbQ.js.br +0 -0
  144. codex/static_root/assets/flag-tab-D5RcLFbQ.js.gz +0 -0
  145. codex/static_root/assets/{group-tab-SxqTtCGs.c23d57a22257.js → group-tab-BilDDNz5.cba5ca15d7cf.js} +1 -1
  146. codex/static_root/assets/group-tab-BilDDNz5.cba5ca15d7cf.js.br +0 -0
  147. codex/static_root/assets/group-tab-BilDDNz5.cba5ca15d7cf.js.gz +0 -0
  148. codex/static_root/assets/{group-tab-SxqTtCGs.js → group-tab-BilDDNz5.js} +1 -1
  149. codex/static_root/assets/group-tab-BilDDNz5.js.br +0 -0
  150. codex/static_root/assets/group-tab-BilDDNz5.js.gz +0 -0
  151. codex/static_root/assets/{http-error-CKL2ByeE.c0333de973b1.js → http-error-DHmC7qgT.bde1d32b55df.js} +1 -1
  152. codex/static_root/assets/http-error-DHmC7qgT.bde1d32b55df.js.br +0 -0
  153. codex/static_root/assets/http-error-DHmC7qgT.bde1d32b55df.js.gz +0 -0
  154. codex/static_root/assets/{http-error-CKL2ByeE.js → http-error-DHmC7qgT.js} +1 -1
  155. codex/static_root/assets/http-error-DHmC7qgT.js.br +0 -0
  156. codex/static_root/assets/http-error-DHmC7qgT.js.gz +0 -0
  157. codex/static_root/assets/{library-tab-jesPyoqi.453abce07ca3.js → library-tab-dbcbv0--.efa2d1d95b77.js} +1 -1
  158. codex/static_root/assets/library-tab-dbcbv0--.efa2d1d95b77.js.br +0 -0
  159. codex/static_root/assets/library-tab-dbcbv0--.efa2d1d95b77.js.gz +0 -0
  160. codex/static_root/assets/{library-tab-jesPyoqi.js → library-tab-dbcbv0--.js} +1 -1
  161. codex/static_root/assets/library-tab-dbcbv0--.js.br +0 -0
  162. codex/static_root/assets/library-tab-dbcbv0--.js.gz +0 -0
  163. codex/static_root/assets/{main-BXWucpmC.js → main-CCY5Ix0K.b067e1d16cf5.js} +4 -4
  164. codex/static_root/assets/main-CCY5Ix0K.b067e1d16cf5.js.br +0 -0
  165. codex/static_root/assets/main-CCY5Ix0K.b067e1d16cf5.js.gz +0 -0
  166. codex/static_root/assets/{main-BXWucpmC.f8485541954a.js → main-CCY5Ix0K.js} +4 -4
  167. codex/static_root/assets/main-CCY5Ix0K.js.br +0 -0
  168. codex/static_root/assets/main-CCY5Ix0K.js.gz +0 -0
  169. codex/static_root/assets/main-CacfwsKA.4f849ef1c5db.css.br +0 -0
  170. codex/static_root/assets/main-CacfwsKA.css.br +0 -0
  171. codex/static_root/assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf.br +0 -0
  172. codex/static_root/assets/materialdesignicons-webfont-B7mPwVP_.ttf.br +0 -0
  173. codex/static_root/assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot.br +0 -0
  174. codex/static_root/assets/materialdesignicons-webfont-CSr8KVlo.eot.br +0 -0
  175. codex/static_root/assets/{metadata-dialog-QTkQOBoB.2e6935edafee.css → metadata-dialog-DIhQctD5.67830cc94cf8.css} +1 -1
  176. codex/static_root/assets/metadata-dialog-DIhQctD5.67830cc94cf8.css.br +0 -0
  177. codex/static_root/assets/metadata-dialog-DIhQctD5.67830cc94cf8.css.gz +0 -0
  178. codex/static_root/assets/{metadata-dialog-QTkQOBoB.css → metadata-dialog-DIhQctD5.css} +1 -1
  179. codex/static_root/assets/metadata-dialog-DIhQctD5.css.br +0 -0
  180. codex/static_root/assets/metadata-dialog-DIhQctD5.css.gz +0 -0
  181. codex/static_root/assets/metadata-dialog-PkTw4uLp.ce5ee2377f27.js +1 -0
  182. codex/static_root/assets/metadata-dialog-PkTw4uLp.ce5ee2377f27.js.br +0 -0
  183. codex/static_root/assets/metadata-dialog-PkTw4uLp.ce5ee2377f27.js.gz +0 -0
  184. codex/static_root/assets/metadata-dialog-PkTw4uLp.js +1 -0
  185. codex/static_root/assets/metadata-dialog-PkTw4uLp.js.br +0 -0
  186. codex/static_root/assets/metadata-dialog-PkTw4uLp.js.gz +0 -0
  187. codex/static_root/assets/{pdf-doc-DwPaMGER.d981a9066397.js → pdf-doc-CEOcuQZb.260e6671eb89.js} +1 -1
  188. codex/static_root/assets/pdf-doc-CEOcuQZb.260e6671eb89.js.br +0 -0
  189. codex/static_root/assets/pdf-doc-CEOcuQZb.260e6671eb89.js.gz +0 -0
  190. codex/static_root/assets/{pdf-doc-DwPaMGER.js → pdf-doc-CEOcuQZb.js} +1 -1
  191. codex/static_root/assets/pdf-doc-CEOcuQZb.js.br +0 -0
  192. codex/static_root/assets/pdf-doc-CEOcuQZb.js.gz +0 -0
  193. codex/static_root/assets/{reader-7CNuDD9b.3593146c30b7.js → reader-DRsYPz-3.b8ee57f2aefc.js} +2 -2
  194. codex/static_root/assets/reader-DRsYPz-3.b8ee57f2aefc.js.br +0 -0
  195. codex/static_root/assets/reader-DRsYPz-3.b8ee57f2aefc.js.gz +0 -0
  196. codex/static_root/assets/{reader-7CNuDD9b.js → reader-DRsYPz-3.js} +2 -2
  197. codex/static_root/assets/reader-DRsYPz-3.js.br +0 -0
  198. codex/static_root/assets/reader-DRsYPz-3.js.gz +0 -0
  199. codex/static_root/assets/{stats-tab-CyQ4G2G_.10e279711e77.js → stats-tab-QTG23RuT.654f85e0b21d.js} +1 -1
  200. codex/static_root/assets/stats-tab-QTG23RuT.654f85e0b21d.js.br +0 -0
  201. codex/static_root/assets/stats-tab-QTG23RuT.654f85e0b21d.js.gz +0 -0
  202. codex/static_root/assets/{stats-tab-CyQ4G2G_.js → stats-tab-QTG23RuT.js} +1 -1
  203. codex/static_root/assets/stats-tab-QTG23RuT.js.br +0 -0
  204. codex/static_root/assets/stats-tab-QTG23RuT.js.gz +0 -0
  205. codex/static_root/assets/{task-tab-ncnnRysH.13fa947767f5.js → task-tab-Kff6fz1t.28380a665ed7.js} +1 -1
  206. codex/static_root/assets/task-tab-Kff6fz1t.28380a665ed7.js.br +0 -0
  207. codex/static_root/assets/task-tab-Kff6fz1t.28380a665ed7.js.gz +0 -0
  208. codex/static_root/assets/{task-tab-ncnnRysH.js → task-tab-Kff6fz1t.js} +1 -1
  209. codex/static_root/assets/task-tab-Kff6fz1t.js.br +0 -0
  210. codex/static_root/assets/task-tab-Kff6fz1t.js.gz +0 -0
  211. codex/static_root/assets/{user-tab-BWjYndVM.503bf20bdbc0.js → user-tab-OAmZ6CQl.eed3361aefb7.js} +1 -1
  212. codex/static_root/assets/user-tab-OAmZ6CQl.eed3361aefb7.js.br +0 -0
  213. codex/static_root/assets/user-tab-OAmZ6CQl.eed3361aefb7.js.gz +0 -0
  214. codex/static_root/assets/{user-tab-BWjYndVM.js → user-tab-OAmZ6CQl.js} +1 -1
  215. codex/static_root/assets/user-tab-OAmZ6CQl.js.br +0 -0
  216. codex/static_root/assets/user-tab-OAmZ6CQl.js.gz +0 -0
  217. codex/static_root/js/choices.a4dcff295a04.json +1 -0
  218. codex/static_root/js/choices.a4dcff295a04.json.br +0 -0
  219. codex/static_root/js/choices.a4dcff295a04.json.gz +0 -0
  220. codex/static_root/js/choices.json +1 -1
  221. codex/static_root/js/choices.json.br +0 -0
  222. codex/static_root/js/choices.json.gz +0 -0
  223. codex/static_root/{manifest.a5c8e7a036f3.json → manifest.13219ea92507.json} +214 -213
  224. codex/static_root/manifest.13219ea92507.json.br +0 -0
  225. codex/static_root/manifest.13219ea92507.json.gz +0 -0
  226. codex/static_root/manifest.json +214 -213
  227. codex/static_root/manifest.json.br +0 -0
  228. codex/static_root/manifest.json.gz +0 -0
  229. codex/static_root/rest_framework/fonts/fontawesome-webfont.dcb26c7239d8.ttf.br +0 -0
  230. codex/static_root/rest_framework/fonts/fontawesome-webfont.ttf.br +0 -0
  231. codex/static_root/rest_framework/fonts/glyphicons-halflings-regular.e18bbf611f2a.ttf.br +0 -0
  232. codex/static_root/rest_framework/fonts/glyphicons-halflings-regular.ttf.br +0 -0
  233. codex/static_root/staticfiles.json +1 -1
  234. codex/views/browser/base.py +10 -8
  235. codex/views/browser/browser.py +23 -17
  236. codex/views/browser/browser_annotations.py +19 -7
  237. codex/views/browser/choices.py +3 -5
  238. codex/views/browser/filters/search.py +114 -22
  239. codex/views/browser/metadata.py +4 -6
  240. codex/views/error.py +1 -0
  241. codex/views/session.py +1 -0
  242. {codex-1.5.13.dist-info → codex-1.5.13a0.dist-info}/METADATA +2 -1
  243. {codex-1.5.13.dist-info → codex-1.5.13a0.dist-info}/RECORD +250 -250
  244. codex/static_root/assets/VCheckbox-Wdu19ZuZ.50f2bf3b5ce5.js.br +0 -0
  245. codex/static_root/assets/VCheckbox-Wdu19ZuZ.50f2bf3b5ce5.js.gz +0 -0
  246. codex/static_root/assets/VCheckbox-Wdu19ZuZ.js.br +0 -0
  247. codex/static_root/assets/VCheckbox-Wdu19ZuZ.js.gz +0 -0
  248. codex/static_root/assets/VCheckboxBtn-C7NngFC8.bd12ea5cdbb2.js.br +0 -0
  249. codex/static_root/assets/VCheckboxBtn-C7NngFC8.bd12ea5cdbb2.js.gz +0 -0
  250. codex/static_root/assets/VCheckboxBtn-C7NngFC8.js.br +0 -0
  251. codex/static_root/assets/VCheckboxBtn-C7NngFC8.js.gz +0 -0
  252. codex/static_root/assets/VCombobox-DxNlm_ji.11d317a5dbb0.js.br +0 -0
  253. codex/static_root/assets/VCombobox-DxNlm_ji.11d317a5dbb0.js.gz +0 -0
  254. codex/static_root/assets/VCombobox-DxNlm_ji.js.br +0 -0
  255. codex/static_root/assets/VCombobox-DxNlm_ji.js.gz +0 -0
  256. codex/static_root/assets/VDataTableVirtual-C4UTS-jp.4b2926f1461f.js.br +0 -0
  257. codex/static_root/assets/VDataTableVirtual-C4UTS-jp.4b2926f1461f.js.gz +0 -0
  258. codex/static_root/assets/VDataTableVirtual-C4UTS-jp.js.br +0 -0
  259. codex/static_root/assets/VDataTableVirtual-C4UTS-jp.js.gz +0 -0
  260. codex/static_root/assets/VExpansionPanel-1dRZTsNe.6213946f43dd.js.br +0 -0
  261. codex/static_root/assets/VExpansionPanel-1dRZTsNe.6213946f43dd.js.gz +0 -0
  262. codex/static_root/assets/VExpansionPanel-1dRZTsNe.js.br +0 -0
  263. codex/static_root/assets/VExpansionPanel-1dRZTsNe.js.gz +0 -0
  264. codex/static_root/assets/VMain-BVEH6Gtw.51ef468a0780.js.br +0 -0
  265. codex/static_root/assets/VMain-BVEH6Gtw.51ef468a0780.js.gz +0 -0
  266. codex/static_root/assets/VMain-BVEH6Gtw.js.br +0 -0
  267. codex/static_root/assets/VMain-BVEH6Gtw.js.gz +0 -0
  268. codex/static_root/assets/VRadioGroup-D1WV2cpK.83ba2e5689fd.js.br +0 -0
  269. codex/static_root/assets/VRadioGroup-D1WV2cpK.83ba2e5689fd.js.gz +0 -0
  270. codex/static_root/assets/VRadioGroup-D1WV2cpK.js.br +0 -0
  271. codex/static_root/assets/VRadioGroup-D1WV2cpK.js.gz +0 -0
  272. codex/static_root/assets/VSelect-BVyqMxyX.4a54cd987085.js.br +0 -0
  273. codex/static_root/assets/VSelect-BVyqMxyX.4a54cd987085.js.gz +0 -0
  274. codex/static_root/assets/VSelect-BVyqMxyX.js.br +0 -0
  275. codex/static_root/assets/VSelect-BVyqMxyX.js.gz +0 -0
  276. codex/static_root/assets/VSelectionControl-CC9aC7ZT.2db18d99af8b.js.br +0 -0
  277. codex/static_root/assets/VSelectionControl-CC9aC7ZT.2db18d99af8b.js.gz +0 -0
  278. codex/static_root/assets/VSelectionControl-CC9aC7ZT.js.br +0 -0
  279. codex/static_root/assets/VSelectionControl-CC9aC7ZT.js.gz +0 -0
  280. codex/static_root/assets/VSlideGroup-D4n-jSgi.686cc428f5fe.js.br +0 -0
  281. codex/static_root/assets/VSlideGroup-D4n-jSgi.686cc428f5fe.js.gz +0 -0
  282. codex/static_root/assets/VSlideGroup-D4n-jSgi.js.br +0 -0
  283. codex/static_root/assets/VSlideGroup-D4n-jSgi.js.gz +0 -0
  284. codex/static_root/assets/VTable-DioYRJkC.c8638b2267ed.js.br +0 -0
  285. codex/static_root/assets/VTable-DioYRJkC.c8638b2267ed.js.gz +0 -0
  286. codex/static_root/assets/VTable-DioYRJkC.js.br +0 -0
  287. codex/static_root/assets/VTable-DioYRJkC.js.gz +0 -0
  288. codex/static_root/assets/VToolbar-DLtG5Ngs.e32539656f6d.js.br +0 -0
  289. codex/static_root/assets/VToolbar-DLtG5Ngs.e32539656f6d.js.gz +0 -0
  290. codex/static_root/assets/VToolbar-DLtG5Ngs.js.br +0 -0
  291. codex/static_root/assets/VToolbar-DLtG5Ngs.js.gz +0 -0
  292. codex/static_root/assets/VWindowItem-D-OB7e0u.ef9bcb84a01e.js.br +0 -0
  293. codex/static_root/assets/VWindowItem-D-OB7e0u.ef9bcb84a01e.js.gz +0 -0
  294. codex/static_root/assets/VWindowItem-D-OB7e0u.js.br +0 -0
  295. codex/static_root/assets/VWindowItem-D-OB7e0u.js.gz +0 -0
  296. codex/static_root/assets/admin-BwXMQOyX.8c44117c2b63.js.br +0 -0
  297. codex/static_root/assets/admin-BwXMQOyX.8c44117c2b63.js.gz +0 -0
  298. codex/static_root/assets/admin-BwXMQOyX.js.br +0 -0
  299. codex/static_root/assets/admin-BwXMQOyX.js.gz +0 -0
  300. codex/static_root/assets/admin-drawer-panel-CGj6J0rX.cc680f2603da.js.br +0 -0
  301. codex/static_root/assets/admin-drawer-panel-CGj6J0rX.cc680f2603da.js.gz +0 -0
  302. codex/static_root/assets/admin-drawer-panel-CGj6J0rX.js.br +0 -0
  303. codex/static_root/assets/admin-drawer-panel-CGj6J0rX.js.gz +0 -0
  304. codex/static_root/assets/browser-BLCruguN.ca6300976f82.js +0 -1
  305. codex/static_root/assets/browser-BLCruguN.ca6300976f82.js.br +0 -0
  306. codex/static_root/assets/browser-BLCruguN.ca6300976f82.js.gz +0 -0
  307. codex/static_root/assets/browser-BLCruguN.js +0 -1
  308. codex/static_root/assets/browser-BLCruguN.js.br +0 -0
  309. codex/static_root/assets/browser-BLCruguN.js.gz +0 -0
  310. codex/static_root/assets/browser-CTxEKlCx.211d729d9165.css.br +0 -0
  311. codex/static_root/assets/browser-CTxEKlCx.211d729d9165.css.gz +0 -0
  312. codex/static_root/assets/browser-CTxEKlCx.css.br +0 -0
  313. codex/static_root/assets/browser-CTxEKlCx.css.gz +0 -0
  314. codex/static_root/assets/change-password-dialog-DDvVSrWH.915709700c5f.js.br +0 -0
  315. codex/static_root/assets/change-password-dialog-DDvVSrWH.915709700c5f.js.gz +0 -0
  316. codex/static_root/assets/change-password-dialog-DDvVSrWH.js.br +0 -0
  317. codex/static_root/assets/change-password-dialog-DDvVSrWH.js.gz +0 -0
  318. codex/static_root/assets/confirm-dialog-Bf3Sde_o.b437109b579e.js.br +0 -0
  319. codex/static_root/assets/confirm-dialog-Bf3Sde_o.b437109b579e.js.gz +0 -0
  320. codex/static_root/assets/confirm-dialog-Bf3Sde_o.js.br +0 -0
  321. codex/static_root/assets/confirm-dialog-Bf3Sde_o.js.gz +0 -0
  322. codex/static_root/assets/confirm-footer-CLwOC3F0.d25d9085b300.js.br +0 -0
  323. codex/static_root/assets/confirm-footer-CLwOC3F0.d25d9085b300.js.gz +0 -0
  324. codex/static_root/assets/confirm-footer-CLwOC3F0.js.br +0 -0
  325. codex/static_root/assets/confirm-footer-CLwOC3F0.js.gz +0 -0
  326. codex/static_root/assets/datetime-column-DGfoC2Ap.ef9499c6bca8.js.br +0 -0
  327. codex/static_root/assets/datetime-column-DGfoC2Ap.ef9499c6bca8.js.gz +0 -0
  328. codex/static_root/assets/datetime-column-DGfoC2Ap.js.br +0 -0
  329. codex/static_root/assets/datetime-column-DGfoC2Ap.js.gz +0 -0
  330. codex/static_root/assets/filter-DcOs3rVI.495426fbd29e.js.br +0 -0
  331. codex/static_root/assets/filter-DcOs3rVI.495426fbd29e.js.gz +0 -0
  332. codex/static_root/assets/filter-DcOs3rVI.js.br +0 -0
  333. codex/static_root/assets/filter-DcOs3rVI.js.gz +0 -0
  334. codex/static_root/assets/flag-tab-D77e2Ors.068789b9d816.js.br +0 -0
  335. codex/static_root/assets/flag-tab-D77e2Ors.068789b9d816.js.gz +0 -0
  336. codex/static_root/assets/flag-tab-D77e2Ors.js.br +0 -0
  337. codex/static_root/assets/flag-tab-D77e2Ors.js.gz +0 -0
  338. codex/static_root/assets/group-tab-SxqTtCGs.c23d57a22257.js.br +0 -0
  339. codex/static_root/assets/group-tab-SxqTtCGs.c23d57a22257.js.gz +0 -0
  340. codex/static_root/assets/group-tab-SxqTtCGs.js.br +0 -0
  341. codex/static_root/assets/group-tab-SxqTtCGs.js.gz +0 -0
  342. codex/static_root/assets/http-error-CKL2ByeE.c0333de973b1.js.br +0 -0
  343. codex/static_root/assets/http-error-CKL2ByeE.c0333de973b1.js.gz +0 -0
  344. codex/static_root/assets/http-error-CKL2ByeE.js.br +0 -0
  345. codex/static_root/assets/http-error-CKL2ByeE.js.gz +0 -0
  346. codex/static_root/assets/library-tab-jesPyoqi.453abce07ca3.js.br +0 -0
  347. codex/static_root/assets/library-tab-jesPyoqi.453abce07ca3.js.gz +0 -0
  348. codex/static_root/assets/library-tab-jesPyoqi.js.br +0 -0
  349. codex/static_root/assets/library-tab-jesPyoqi.js.gz +0 -0
  350. codex/static_root/assets/main-BXWucpmC.f8485541954a.js.br +0 -0
  351. codex/static_root/assets/main-BXWucpmC.f8485541954a.js.gz +0 -0
  352. codex/static_root/assets/main-BXWucpmC.js.br +0 -0
  353. codex/static_root/assets/main-BXWucpmC.js.gz +0 -0
  354. codex/static_root/assets/main-CGRrI5lh.4f849ef1c5db.css.br +0 -0
  355. codex/static_root/assets/main-CGRrI5lh.css.br +0 -0
  356. codex/static_root/assets/metadata-dialog-Dkadd19B.0c95b145042a.js +0 -1
  357. codex/static_root/assets/metadata-dialog-Dkadd19B.0c95b145042a.js.br +0 -0
  358. codex/static_root/assets/metadata-dialog-Dkadd19B.0c95b145042a.js.gz +0 -0
  359. codex/static_root/assets/metadata-dialog-Dkadd19B.js +0 -1
  360. codex/static_root/assets/metadata-dialog-Dkadd19B.js.br +0 -0
  361. codex/static_root/assets/metadata-dialog-Dkadd19B.js.gz +0 -0
  362. codex/static_root/assets/metadata-dialog-QTkQOBoB.2e6935edafee.css.br +0 -0
  363. codex/static_root/assets/metadata-dialog-QTkQOBoB.2e6935edafee.css.gz +0 -0
  364. codex/static_root/assets/metadata-dialog-QTkQOBoB.css.br +0 -0
  365. codex/static_root/assets/metadata-dialog-QTkQOBoB.css.gz +0 -0
  366. codex/static_root/assets/pdf-doc-DwPaMGER.d981a9066397.js.br +0 -0
  367. codex/static_root/assets/pdf-doc-DwPaMGER.d981a9066397.js.gz +0 -0
  368. codex/static_root/assets/pdf-doc-DwPaMGER.js.br +0 -0
  369. codex/static_root/assets/pdf-doc-DwPaMGER.js.gz +0 -0
  370. codex/static_root/assets/reader-7CNuDD9b.3593146c30b7.js.br +0 -0
  371. codex/static_root/assets/reader-7CNuDD9b.3593146c30b7.js.gz +0 -0
  372. codex/static_root/assets/reader-7CNuDD9b.js.br +0 -0
  373. codex/static_root/assets/reader-7CNuDD9b.js.gz +0 -0
  374. codex/static_root/assets/stats-tab-CyQ4G2G_.10e279711e77.js.br +0 -0
  375. codex/static_root/assets/stats-tab-CyQ4G2G_.10e279711e77.js.gz +0 -0
  376. codex/static_root/assets/stats-tab-CyQ4G2G_.js.br +0 -0
  377. codex/static_root/assets/stats-tab-CyQ4G2G_.js.gz +0 -0
  378. codex/static_root/assets/task-tab-ncnnRysH.13fa947767f5.js.br +0 -0
  379. codex/static_root/assets/task-tab-ncnnRysH.13fa947767f5.js.gz +0 -0
  380. codex/static_root/assets/task-tab-ncnnRysH.js.br +0 -0
  381. codex/static_root/assets/task-tab-ncnnRysH.js.gz +0 -0
  382. codex/static_root/assets/user-tab-BWjYndVM.503bf20bdbc0.js.br +0 -0
  383. codex/static_root/assets/user-tab-BWjYndVM.503bf20bdbc0.js.gz +0 -0
  384. codex/static_root/assets/user-tab-BWjYndVM.js.br +0 -0
  385. codex/static_root/assets/user-tab-BWjYndVM.js.gz +0 -0
  386. codex/static_root/js/choices.fedcbd1ec085.json +0 -1
  387. codex/static_root/js/choices.fedcbd1ec085.json.br +0 -0
  388. codex/static_root/js/choices.fedcbd1ec085.json.gz +0 -0
  389. codex/static_root/manifest.a5c8e7a036f3.json.br +0 -0
  390. codex/static_root/manifest.a5c8e7a036f3.json.gz +0 -0
  391. /codex/static_root/assets/{main-CGRrI5lh.4f849ef1c5db.css → main-CacfwsKA.4f849ef1c5db.css} +0 -0
  392. /codex/static_root/assets/{main-CGRrI5lh.4f849ef1c5db.css.gz → main-CacfwsKA.4f849ef1c5db.css.gz} +0 -0
  393. /codex/static_root/assets/{main-CGRrI5lh.css → main-CacfwsKA.css} +0 -0
  394. /codex/static_root/assets/{main-CGRrI5lh.css.gz → main-CacfwsKA.css.gz} +0 -0
  395. {codex-1.5.13.dist-info → codex-1.5.13a0.dist-info}/LICENSE +0 -0
  396. {codex-1.5.13.dist-info → codex-1.5.13a0.dist-info}/WHEEL +0 -0
  397. {codex-1.5.13.dist-info → codex-1.5.13a0.dist-info}/entry_points.txt +0 -0
Binary file
Binary file
@@ -1 +1 @@
1
- {"paths": {"rest_framework/docs/css/highlight.css": "rest_framework/docs/css/highlight.e0e4d973c6d7.css", "rest_framework/docs/css/base.css": "rest_framework/docs/css/base.e630f8f4990e.css", "rest_framework/docs/css/jquery.json-view.min.css": "rest_framework/docs/css/jquery.json-view.min.a2e6beeb6710.css", "rest_framework/docs/js/highlight.pack.js": "rest_framework/docs/js/highlight.pack.479b5f21dcba.js", "rest_framework/docs/js/api.js": "rest_framework/docs/js/api.18a5ba8a1bd8.js", "rest_framework/docs/js/jquery.json-view.min.js": "rest_framework/docs/js/jquery.json-view.min.b7c2d6981377.js", "rest_framework/docs/img/favicon.ico": "rest_framework/docs/img/favicon.5195b4d0f3eb.ico", "rest_framework/docs/img/grid.png": "rest_framework/docs/img/grid.a4b938cf382b.png", "rest_framework/css/bootstrap.min.css": "rest_framework/css/bootstrap.min.f17d4516b026.css", "rest_framework/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "rest_framework/css/bootstrap-theme.min.css.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "rest_framework/css/prettify.css": "rest_framework/css/prettify.a987f72342ee.css", "rest_framework/css/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/font-awesome-4.0.3.css": "rest_framework/css/font-awesome-4.0.3.c1e1ea213abf.css", "rest_framework/css/bootstrap-tweaks.css": "rest_framework/css/bootstrap-tweaks.ee4ee6acf9eb.css", "rest_framework/css/bootstrap-theme.min.css": "rest_framework/css/bootstrap-theme.min.1d4b05b397c3.css", "rest_framework/js/load-ajax-form.js": "rest_framework/js/load-ajax-form.8cdb3a9f3466.js", "rest_framework/js/ajax-form.js": "rest_framework/js/ajax-form.4e1cdcb7acab.js", "rest_framework/js/prettify-min.js": "rest_framework/js/prettify-min.709bfcc456c6.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "rest_framework/js/default.js": "rest_framework/js/default.5b08897dbdc3.js", "rest_framework/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/img/grid.png": "rest_framework/img/grid.a4b938cf382b.png", "rest_framework/img/glyphicons-halflings.png": "rest_framework/img/glyphicons-halflings.90233c9067e9.png", "rest_framework/img/glyphicons-halflings-white.png": "rest_framework/img/glyphicons-halflings-white.9bbc6e960299.png", "rest_framework/fonts/fontawesome-webfont.svg": "rest_framework/fonts/fontawesome-webfont.83e37a11f9d7.svg", "rest_framework/fonts/glyphicons-halflings-regular.woff": "rest_framework/fonts/glyphicons-halflings-regular.fa2772327f55.woff", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "rest_framework/fonts/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "rest_framework/fonts/glyphicons-halflings-regular.ttf": "rest_framework/fonts/glyphicons-halflings-regular.e18bbf611f2a.ttf", "rest_framework/fonts/fontawesome-webfont.ttf": "rest_framework/fonts/fontawesome-webfont.dcb26c7239d8.ttf", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "img/logo-32.webp": "img/logo-32.dbb98f6dfde4.webp", "img/missing-page.svg": "img/missing-page.71bb10f7c72a.svg", "img/missing-cover.webp": "img/missing-cover.8c8c1d4f6782.webp", "img/logo-maskable.svg": "img/logo-maskable.d618c2d7943f.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.201cbde62d55.webp", "img/logo.svg": "img/logo.3fb129bfbd92.svg", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "js/choices-admin.json": "js/choices-admin.bb730e4f26ac.json", "js/choices.json": "js/choices.fedcbd1ec085.json", "assets/VMain-BVEH6Gtw.js": "assets/VMain-BVEH6Gtw.51ef468a0780.js", "assets/VDataTableVirtual-C4UTS-jp.js": "assets/VDataTableVirtual-C4UTS-jp.4b2926f1461f.js", "assets/VSelect-BdGop3V2.css": "assets/VSelect-BdGop3V2.604c1785fbff.css", "assets/browser-CTxEKlCx.css": "assets/browser-CTxEKlCx.211d729d9165.css", "assets/VExpansionPanel-DsEXVcCv.css": "assets/VExpansionPanel-DsEXVcCv.20b475255e66.css", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/admin-drawer-panel-CGj6J0rX.js": "assets/admin-drawer-panel-CGj6J0rX.cc680f2603da.js", "assets/admin-Df82-Qcj.css": "assets/admin-Df82-Qcj.4c3f0406ee54.css", "assets/main-BXWucpmC.js": "assets/main-BXWucpmC.f8485541954a.js", "assets/VCheckboxBtn-C7NngFC8.js": "assets/VCheckboxBtn-C7NngFC8.bd12ea5cdbb2.js", "assets/change-password-dialog-BRmvkNir.css": "assets/change-password-dialog-BRmvkNir.2fead58a78c7.css", "assets/task-tab-ncnnRysH.js": "assets/task-tab-ncnnRysH.13fa947767f5.js", "assets/VTable-DioYRJkC.js": "assets/VTable-DioYRJkC.c8638b2267ed.js", "assets/flag-tab-DUXtbpA2.css": "assets/flag-tab-DUXtbpA2.8d52c0d4f9e2.css", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/flag-tab-D77e2Ors.js": "assets/flag-tab-D77e2Ors.068789b9d816.js", "assets/http-error-C25WdjWC.css": "assets/http-error-C25WdjWC.1c7337ad6e1d.css", "assets/VCheckbox-Wdu19ZuZ.js": "assets/VCheckbox-Wdu19ZuZ.50f2bf3b5ce5.js", "assets/VRadioGroup-D1WV2cpK.js": "assets/VRadioGroup-D1WV2cpK.83ba2e5689fd.js", "assets/stats-tab-CyQ4G2G_.js": "assets/stats-tab-CyQ4G2G_.10e279711e77.js", "assets/datetime-column-DGfoC2Ap.js": "assets/datetime-column-DGfoC2Ap.ef9499c6bca8.js", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/confirm-footer-CLwOC3F0.js": "assets/confirm-footer-CLwOC3F0.d25d9085b300.js", "assets/stats-tab-BTZLMBCU.css": "assets/stats-tab-BTZLMBCU.7e0a9547c12e.css", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/task-tab-DoX9OA37.css": "assets/task-tab-DoX9OA37.9bb355f36dbf.css", "assets/to-case-kUm8NPpW.js": "assets/to-case-kUm8NPpW.5b3369f511b8.js", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/VSlideGroup-D4n-jSgi.js": "assets/VSlideGroup-D4n-jSgi.686cc428f5fe.js", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/VSelect-BVyqMxyX.js": "assets/VSelect-BVyqMxyX.4a54cd987085.js", "assets/metadata-dialog-QTkQOBoB.css": "assets/metadata-dialog-QTkQOBoB.2e6935edafee.css", "assets/http-error-CKL2ByeE.js": "assets/http-error-CKL2ByeE.c0333de973b1.js", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/change-password-dialog-DDvVSrWH.js": "assets/change-password-dialog-DDvVSrWH.915709700c5f.js", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/group-tab-3DXxSetf.css": "assets/group-tab-3DXxSetf.5fc2cfa31669.css", "assets/VCombobox-DxNlm_ji.js": "assets/VCombobox-DxNlm_ji.11d317a5dbb0.js", "assets/admin-drawer-panel-Bk7z8uTR.css": "assets/admin-drawer-panel-Bk7z8uTR.1531b747003f.css", "assets/reader-7CNuDD9b.js": "assets/reader-7CNuDD9b.3593146c30b7.js", "assets/VToolbar-DqQLg1UA.css": "assets/VToolbar-DqQLg1UA.614d6a4a8a09.css", "assets/VMain-Byt37V4c.css": "assets/VMain-Byt37V4c.a00e206f3cfa.css", "assets/main-CGRrI5lh.css": "assets/main-CGRrI5lh.4f849ef1c5db.css", "assets/VDataTableVirtual-Cbj7IGxa.css": "assets/VDataTableVirtual-Cbj7IGxa.24039b2ebc61.css", "assets/browser-BLCruguN.js": "assets/browser-BLCruguN.ca6300976f82.js", "assets/confirm-dialog-Bf3Sde_o.js": "assets/confirm-dialog-Bf3Sde_o.b437109b579e.js", "assets/VSlideGroup-C3lY91uv.css": "assets/VSlideGroup-C3lY91uv.d268067bd078.css", "assets/index-DUjeNg4x.js": "assets/index-DUjeNg4x.36d50c91b2c1.js", "assets/VWindowItem-D-OB7e0u.js": "assets/VWindowItem-D-OB7e0u.ef9bcb84a01e.js", "assets/group-tab-SxqTtCGs.js": "assets/group-tab-SxqTtCGs.c23d57a22257.js", "assets/VExpansionPanel-1dRZTsNe.js": "assets/VExpansionPanel-1dRZTsNe.6213946f43dd.js", "assets/VTable-DflzroDq.css": "assets/VTable-DflzroDq.160504d82195.css", "assets/library-tab-jesPyoqi.js": "assets/library-tab-jesPyoqi.453abce07ca3.js", "assets/VSelectionControl-CC9aC7ZT.js": "assets/VSelectionControl-CC9aC7ZT.2db18d99af8b.js", "assets/reader-CG6zrLXl.css": "assets/reader-CG6zrLXl.ed017042cd53.css", "assets/admin-BwXMQOyX.js": "assets/admin-BwXMQOyX.8c44117c2b63.js", "assets/VToolbar-DLtG5Ngs.js": "assets/VToolbar-DLtG5Ngs.e32539656f6d.js", "assets/datetime-column-BWWfvyhn.css": "assets/datetime-column-BWWfvyhn.a4a94ba57c73.css", "assets/metadata-dialog-Dkadd19B.js": "assets/metadata-dialog-Dkadd19B.0c95b145042a.js", "assets/library-tab-DZKDtQ5v.css": "assets/library-tab-DZKDtQ5v.c8123e4bc5a4.css", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/confirm-footer-VFepxcJs.css": "assets/confirm-footer-VFepxcJs.4150131304bd.css", "assets/pdf-doc-DwPaMGER.js": "assets/pdf-doc-DwPaMGER.d981a9066397.js", "assets/user-tab-BWjYndVM.js": "assets/user-tab-BWjYndVM.503bf20bdbc0.js", "assets/filter-DcOs3rVI.js": "assets/filter-DcOs3rVI.495426fbd29e.js", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.a5c8e7a036f3.json"}, "version": "1.1", "hash": "54ff58bbb924"}
1
+ {"paths": {"rest_framework/docs/js/api.js": "rest_framework/docs/js/api.18a5ba8a1bd8.js", "rest_framework/docs/js/jquery.json-view.min.js": "rest_framework/docs/js/jquery.json-view.min.b7c2d6981377.js", "rest_framework/docs/js/highlight.pack.js": "rest_framework/docs/js/highlight.pack.479b5f21dcba.js", "rest_framework/docs/img/favicon.ico": "rest_framework/docs/img/favicon.5195b4d0f3eb.ico", "rest_framework/docs/img/grid.png": "rest_framework/docs/img/grid.a4b938cf382b.png", "rest_framework/docs/css/highlight.css": "rest_framework/docs/css/highlight.e0e4d973c6d7.css", "rest_framework/docs/css/base.css": "rest_framework/docs/css/base.e630f8f4990e.css", "rest_framework/docs/css/jquery.json-view.min.css": "rest_framework/docs/css/jquery.json-view.min.a2e6beeb6710.css", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "rest_framework/js/prettify-min.js": "rest_framework/js/prettify-min.709bfcc456c6.js", "rest_framework/js/ajax-form.js": "rest_framework/js/ajax-form.4e1cdcb7acab.js", "rest_framework/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/default.js": "rest_framework/js/default.5b08897dbdc3.js", "rest_framework/js/load-ajax-form.js": "rest_framework/js/load-ajax-form.8cdb3a9f3466.js", "rest_framework/img/glyphicons-halflings-white.png": "rest_framework/img/glyphicons-halflings-white.9bbc6e960299.png", "rest_framework/img/glyphicons-halflings.png": "rest_framework/img/glyphicons-halflings.90233c9067e9.png", "rest_framework/img/grid.png": "rest_framework/img/grid.a4b938cf382b.png", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.ttf": "rest_framework/fonts/glyphicons-halflings-regular.e18bbf611f2a.ttf", "rest_framework/fonts/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "rest_framework/fonts/fontawesome-webfont.ttf": "rest_framework/fonts/fontawesome-webfont.dcb26c7239d8.ttf", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "rest_framework/fonts/glyphicons-halflings-regular.woff": "rest_framework/fonts/glyphicons-halflings-regular.fa2772327f55.woff", "rest_framework/fonts/fontawesome-webfont.svg": "rest_framework/fonts/fontawesome-webfont.83e37a11f9d7.svg", "rest_framework/fonts/glyphicons-halflings-regular.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/css/prettify.css": "rest_framework/css/prettify.a987f72342ee.css", "rest_framework/css/font-awesome-4.0.3.css": "rest_framework/css/font-awesome-4.0.3.c1e1ea213abf.css", "rest_framework/css/bootstrap-theme.min.css": "rest_framework/css/bootstrap-theme.min.1d4b05b397c3.css", "rest_framework/css/bootstrap-theme.min.css.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "rest_framework/css/bootstrap.min.css": "rest_framework/css/bootstrap.min.f17d4516b026.css", "rest_framework/css/bootstrap-tweaks.css": "rest_framework/css/bootstrap-tweaks.ee4ee6acf9eb.css", "rest_framework/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "rest_framework/css/default.css": "rest_framework/css/default.789dfb5732d7.css", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "img/logo-maskable.svg": "img/logo-maskable.d618c2d7943f.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.201cbde62d55.webp", "img/logo.svg": "img/logo.3fb129bfbd92.svg", "img/missing-cover.webp": "img/missing-cover.8c8c1d4f6782.webp", "img/missing-page.svg": "img/missing-page.71bb10f7c72a.svg", "img/logo-32.webp": "img/logo-32.dbb98f6dfde4.webp", "js/choices.json": "js/choices.a4dcff295a04.json", "js/choices-admin.json": "js/choices-admin.bb730e4f26ac.json", "assets/reader-DRsYPz-3.js": "assets/reader-DRsYPz-3.b8ee57f2aefc.js", "assets/VToolbar-CAUhD2BO.js": "assets/VToolbar-CAUhD2BO.279f0b52347a.js", "assets/VExpansionPanel-DsEXVcCv.css": "assets/VExpansionPanel-DsEXVcCv.20b475255e66.css", "assets/VTable-CGuSv-Tv.js": "assets/VTable-CGuSv-Tv.eddaf5526d93.js", "assets/group-tab-BilDDNz5.js": "assets/group-tab-BilDDNz5.cba5ca15d7cf.js", "assets/VCheckbox-BMRDCYNv.js": "assets/VCheckbox-BMRDCYNv.7f791d7f065f.js", "assets/datetime-column-BWWfvyhn.css": "assets/datetime-column-BWWfvyhn.a4a94ba57c73.css", "assets/VSlideGroup-ztBraz6g.js": "assets/VSlideGroup-ztBraz6g.02a0bc55b207.js", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/VTable-DflzroDq.css": "assets/VTable-DflzroDq.160504d82195.css", "assets/VExpansionPanel-C593uXqT.js": "assets/VExpansionPanel-C593uXqT.d3bdc6a21208.js", "assets/VSelectionControl-CuM4okF6.js": "assets/VSelectionControl-CuM4okF6.0f246e35e86f.js", "assets/VSlideGroup-C3lY91uv.css": "assets/VSlideGroup-C3lY91uv.d268067bd078.css", "assets/VMain-Byt37V4c.css": "assets/VMain-Byt37V4c.a00e206f3cfa.css", "assets/VRadioGroup-Bi16yPEE.js": "assets/VRadioGroup-Bi16yPEE.69086b77f9b1.js", "assets/VMain-DmQvRj_k.js": "assets/VMain-DmQvRj_k.1e0480bed9a6.js", "assets/VWindowItem-YvmNwCNb.js": "assets/VWindowItem-YvmNwCNb.20a7e3b303de.js", "assets/stats-tab-BTZLMBCU.css": "assets/stats-tab-BTZLMBCU.7e0a9547c12e.css", "assets/confirm-footer-VFepxcJs.css": "assets/confirm-footer-VFepxcJs.4150131304bd.css", "assets/change-password-dialog-BRmvkNir.css": "assets/change-password-dialog-BRmvkNir.2fead58a78c7.css", "assets/library-tab-DZKDtQ5v.css": "assets/library-tab-DZKDtQ5v.c8123e4bc5a4.css", "assets/to-case-kUm8NPpW.js": "assets/to-case-kUm8NPpW.5b3369f511b8.js", "assets/task-tab-Kff6fz1t.js": "assets/task-tab-Kff6fz1t.28380a665ed7.js", "assets/admin-drawer-panel-B4VvGE4s.js": "assets/admin-drawer-panel-B4VvGE4s.2265b9de60ab.js", "assets/main-CacfwsKA.css": "assets/main-CacfwsKA.4f849ef1c5db.css", "assets/change-password-dialog-Dq6GjT1T.js": "assets/change-password-dialog-Dq6GjT1T.01b56b4b3e87.js", "assets/flag-tab-D5RcLFbQ.js": "assets/flag-tab-D5RcLFbQ.1073708ea164.js", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/user-tab-OAmZ6CQl.js": "assets/user-tab-OAmZ6CQl.eed3361aefb7.js", "assets/pdf-doc-CEOcuQZb.js": "assets/pdf-doc-CEOcuQZb.260e6671eb89.js", "assets/library-tab-dbcbv0--.js": "assets/library-tab-dbcbv0--.efa2d1d95b77.js", "assets/VCheckboxBtn-Dqp1u3GT.js": "assets/VCheckboxBtn-Dqp1u3GT.e80f145994b6.js", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/datetime-column-DCeBthsr.js": "assets/datetime-column-DCeBthsr.22ed49a999cc.js", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/main-CCY5Ix0K.js": "assets/main-CCY5Ix0K.b067e1d16cf5.js", "assets/VToolbar-DqQLg1UA.css": "assets/VToolbar-DqQLg1UA.614d6a4a8a09.css", "assets/http-error-DHmC7qgT.js": "assets/http-error-DHmC7qgT.bde1d32b55df.js", "assets/filter-Dw0fjwZi.js": "assets/filter-Dw0fjwZi.4d5f085435ab.js", "assets/metadata-dialog-DIhQctD5.css": "assets/metadata-dialog-DIhQctD5.67830cc94cf8.css", "assets/stats-tab-QTG23RuT.js": "assets/stats-tab-QTG23RuT.654f85e0b21d.js", "assets/metadata-dialog-PkTw4uLp.js": "assets/metadata-dialog-PkTw4uLp.ce5ee2377f27.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/admin-drawer-panel-Bk7z8uTR.css": "assets/admin-drawer-panel-Bk7z8uTR.1531b747003f.css", "assets/reader-CG6zrLXl.css": "assets/reader-CG6zrLXl.ed017042cd53.css", "assets/task-tab-DoX9OA37.css": "assets/task-tab-DoX9OA37.9bb355f36dbf.css", "assets/VDataTableVirtual-Cbj7IGxa.css": "assets/VDataTableVirtual-Cbj7IGxa.24039b2ebc61.css", "assets/index-DUjeNg4x.js": "assets/index-DUjeNg4x.36d50c91b2c1.js", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/browser-BTel3sYS.js": "assets/browser-BTel3sYS.8e1515bc039a.js", "assets/flag-tab-DUXtbpA2.css": "assets/flag-tab-DUXtbpA2.8d52c0d4f9e2.css", "assets/http-error-C25WdjWC.css": "assets/http-error-C25WdjWC.1c7337ad6e1d.css", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/admin-Ch9WezG1.js": "assets/admin-Ch9WezG1.bdace86b7c25.js", "assets/VSelect-BdGop3V2.css": "assets/VSelect-BdGop3V2.604c1785fbff.css", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/confirm-dialog-D-Fx-51m.js": "assets/confirm-dialog-D-Fx-51m.54b7d1059106.js", "assets/group-tab-3DXxSetf.css": "assets/group-tab-3DXxSetf.5fc2cfa31669.css", "assets/VDataTableVirtual-DhhCmPtf.js": "assets/VDataTableVirtual-DhhCmPtf.0735a1ab4c2f.js", "assets/VCombobox-DT52mZm3.js": "assets/VCombobox-DT52mZm3.309c77be4a55.js", "assets/browser-CVvV08AM.css": "assets/browser-CVvV08AM.7667051b18fa.css", "assets/confirm-footer-Yn7T9Tns.js": "assets/confirm-footer-Yn7T9Tns.75a17cd86ca9.js", "assets/admin-Df82-Qcj.css": "assets/admin-Df82-Qcj.4c3f0406ee54.css", "assets/VSelect-BdaijxdJ.js": "assets/VSelect-BdaijxdJ.b969ab260593.js", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.13219ea92507.json"}, "version": "1.1", "hash": "d55016a34609"}
@@ -6,7 +6,6 @@ from types import MappingProxyType
6
6
  from urllib.parse import unquote_plus
7
7
 
8
8
  from django.contrib.auth.models import User
9
- from django.db.models import Q
10
9
  from djangorestframework_camel_case.settings import api_settings
11
10
  from djangorestframework_camel_case.util import underscoreize
12
11
 
@@ -64,19 +63,23 @@ class BrowserBaseView(
64
63
  self._is_admin = user and isinstance(user, User) and user.is_staff
65
64
  return self._is_admin
66
65
 
67
- def get_query_filters_without_group(self, model, search_scores: dict):
66
+ def get_query_filters_without_group(
67
+ self,
68
+ model,
69
+ ):
68
70
  """Return all the filters except the group filter."""
69
71
  object_filter = self.get_group_acl_filter(model)
70
- object_filter &= self.get_search_filter(model, search_scores)
71
72
  object_filter &= self.get_bookmark_filter(model)
72
73
  object_filter &= self.get_comic_field_filter(self.rel_prefix)
73
74
  return object_filter
74
75
 
75
- def get_query_filters(self, model, search_scores: dict | None, choices=False):
76
+ def get_query_filters(
77
+ self,
78
+ model,
79
+ choices=False,
80
+ ):
76
81
  """Return the main object filter and the one for aggregates."""
77
- if search_scores is None:
78
- return Q(False)
79
- object_filter = self.get_query_filters_without_group(model, search_scores)
82
+ object_filter = self.get_query_filters_without_group(model)
80
83
  object_filter &= self.get_group_filter(choices)
81
84
  return object_filter
82
85
 
@@ -91,7 +94,6 @@ class BrowserBaseView(
91
94
  continue
92
95
  parsed_key = key
93
96
  elif key in ("q", "query"):
94
- # parse and strip query param
95
97
  # "query" is used by opds v2
96
98
  if "q" in result:
97
99
  continue
@@ -33,6 +33,7 @@ from codex.serializers.choices import DEFAULTS
33
33
  from codex.views.auth import IsAuthenticatedOrEnabledNonUsers
34
34
  from codex.views.browser.browser_annotations import BrowserAnnotationsView
35
35
  from codex.views.browser.const import MAX_OBJ_PER_PAGE
36
+ from codex.views.browser.filters.search import SearchScores
36
37
 
37
38
  LOG = get_logger(__name__)
38
39
  _ADMIN_FLAG_VALUE_KEY_MAP = MappingProxyType(
@@ -108,7 +109,12 @@ class BrowserView(BrowserAnnotationsView):
108
109
  value = "c" if model == Comic else self.model_group
109
110
  return queryset.annotate(group=Value(value, CharField(max_length=1)))
110
111
 
111
- def _add_annotations(self, queryset, model, search_scores: dict):
112
+ def _add_annotations(
113
+ self,
114
+ queryset,
115
+ model,
116
+ search_scores: SearchScores | None,
117
+ ):
112
118
  """Annotations for display and sorting."""
113
119
  queryset = self.annotate_common_aggregates(queryset, model, search_scores)
114
120
  queryset = self._annotate_group(queryset, model)
@@ -138,32 +144,35 @@ class BrowserView(BrowserAnnotationsView):
138
144
  self.model_group = self._get_model_group()
139
145
  self.model = self.GROUP_MODEL_MAP[self.model_group]
140
146
 
141
- def _get_common_queryset(self, model, search_scores):
147
+ def _get_common_queryset(self, model):
142
148
  """Create queryset common to group & books."""
143
- object_filter = self.get_query_filters(model, search_scores, False)
149
+ object_filter = self.get_query_filters(model, False)
144
150
  qs = model.objects.filter(object_filter)
151
+ binary = self.params.get("order_by") != "search_score"
152
+ search_scores = self.get_search_scores(binary=binary)
145
153
  qs = self._add_annotations(qs, model, search_scores)
154
+ qs = self.apply_search_filter(qs, model, search_scores)
146
155
  qs = self.add_order_by(qs, model)
147
156
  if limit := self.params.get("limit"):
148
157
  # limit only is set by some opds views
149
158
  qs = qs[:limit]
150
159
  return qs
151
160
 
152
- def _get_group_queryset(self, search_scores: dict | None):
161
+ def _get_group_queryset(self):
153
162
  """Create group queryset."""
154
163
  if not self.model:
155
164
  reason = "Model not set for browser queryset."
156
165
  raise ValueError(reason)
157
- if self.model == Comic or search_scores is None:
166
+ elif self.model == Comic: # noqa: RET506
158
167
  qs = self.model.objects.none()
159
168
  else:
160
- qs = self._get_common_queryset(self.model, search_scores)
169
+ qs = self._get_common_queryset(self.model)
161
170
  return qs
162
171
 
163
- def _get_book_queryset(self, search_scores: dict | None):
172
+ def _get_book_queryset(self):
164
173
  """Create book queryset."""
165
- if self.model in (Comic, Folder) and search_scores is not None:
166
- qs = self._get_common_queryset(Comic, search_scores)
174
+ if self.model in (Comic, Folder):
175
+ qs = self._get_common_queryset(Comic)
167
176
  else:
168
177
  qs = Comic.objects.none()
169
178
  return qs
@@ -202,6 +211,7 @@ class BrowserView(BrowserAnnotationsView):
202
211
  )
203
212
  except self.group_class.DoesNotExist:
204
213
  group = self.kwargs.get("group")
214
+ pk = self.kwargs.get("pk")
205
215
  page = self.kwargs.get("page")
206
216
  if group == "r" and pk == 0 and page == 1:
207
217
  self.group_instance: BrowserGroupModel | None = None
@@ -312,7 +322,7 @@ class BrowserView(BrowserAnnotationsView):
312
322
 
313
323
  def _paginate_section(self, model, qs, page):
314
324
  """Paginate a group or Comic section."""
315
- orphans = 0 if self.model_group == "f" or self.params.get("q") else 5
325
+ orphans = 5 if self.model_group != "f" else 0
316
326
  paginator = Paginator(qs, MAX_OBJ_PER_PAGE, orphans=orphans)
317
327
  try:
318
328
  qs = paginator.page(page).object_list
@@ -366,8 +376,6 @@ class BrowserView(BrowserAnnotationsView):
366
376
  if page < 1:
367
377
  self._page_out_of_bounds(1)
368
378
 
369
- page_obj_count = 0
370
-
371
379
  group_count = group_qs.count()
372
380
  book_count = book_qs.count()
373
381
 
@@ -376,7 +384,7 @@ class BrowserView(BrowserAnnotationsView):
376
384
  self._page_out_of_bounds(num_pages)
377
385
 
378
386
  page_group_qs = self._paginate_groups(group_qs, group_count)
379
- page_obj_count += page_group_qs.count()
387
+ page_obj_count = page_group_qs.count()
380
388
  page_book_qs = self._paginate_books(book_qs, group_count, page_obj_count)
381
389
  page_obj_count += page_book_qs.count()
382
390
 
@@ -388,11 +396,10 @@ class BrowserView(BrowserAnnotationsView):
388
396
  self.set_rel_prefix(self.model)
389
397
  self._set_group_instance() # Placed up here to invalidate earlier
390
398
  # Create the main query with the filters
391
- search_scores: dict | None = self.get_search_scores()
392
399
  group = self.kwargs.get("group")
393
400
 
394
- group_qs = self._get_group_queryset(search_scores)
395
- book_qs = self._get_book_queryset(search_scores)
401
+ group_qs = self._get_group_queryset()
402
+ book_qs = self._get_book_queryset()
396
403
 
397
404
  # Paginate
398
405
  group_qs, book_qs, num_pages, total_count = self._paginate(group_qs, book_qs)
@@ -575,7 +582,6 @@ class BrowserView(BrowserAnnotationsView):
575
582
  self.set_order_key()
576
583
  self._set_admin_flags()
577
584
  enable_folder_view = self.admin_flags["folder_view"]
578
-
579
585
  if group == self.FOLDER_GROUP:
580
586
  self._validate_folder_settings(enable_folder_view)
581
587
  elif group == self.STORY_ARC_GROUP:
@@ -24,6 +24,11 @@ from django.db.models.functions import Least, Lower, Reverse, Right, StrIndex, S
24
24
 
25
25
  from codex.models import Comic
26
26
  from codex.views.browser.browser_order_by import BrowserOrderByView
27
+ from codex.views.browser.filters.search import SearchScores
28
+
29
+ SEARCH_SCORE_MAX = 100.0
30
+ SEARCH_SCORE_MIN = 0.001
31
+ SEARCH_SCORE_EMPTY = 0.0
27
32
 
28
33
 
29
34
  class BrowserAnnotationsView(BrowserOrderByView):
@@ -51,7 +56,9 @@ class BrowserAnnotationsView(BrowserOrderByView):
51
56
 
52
57
  is_opds_1_acquisition = False
53
58
 
54
- def _annotate_search_score(self, queryset, search_scores, model):
59
+ def _annotate_search_score(
60
+ self, queryset, search_scores: SearchScores | None, model
61
+ ):
55
62
  """Annotate the search score for ordering by search score.
56
63
 
57
64
  Choose the maximum matching score for the group.
@@ -60,10 +67,15 @@ class BrowserAnnotationsView(BrowserOrderByView):
60
67
  return queryset
61
68
  whens = []
62
69
  prefix = "" if model == Comic else self.rel_prefix
63
- for pk, score in search_scores.items():
64
- when = {prefix + "pk": pk, "then": score}
65
- whens.append(When(**when))
66
- annotate = {"search_score": Max(Case(*whens, default=0.0))}
70
+ if search_scores:
71
+ for pk, score in search_scores.scores:
72
+ when = {prefix + "pk": pk, "then": score}
73
+ whens.append(When(**when))
74
+ if search_scores.prev_pks:
75
+ whens.append(When(pk__in=search_scores.prev_pks, then=SEARCH_SCORE_MAX))
76
+ if search_scores.next_pks:
77
+ whens.append(When(pk__in=search_scores.next_pks, then=SEARCH_SCORE_MIN))
78
+ annotate = {"search_score": Max(Case(*whens, default=SEARCH_SCORE_EMPTY))}
67
79
  return queryset.annotate(**annotate)
68
80
 
69
81
  def _annotate_cover_pk(self, queryset, model):
@@ -270,7 +282,7 @@ class BrowserAnnotationsView(BrowserOrderByView):
270
282
  def _annotate_mtime(queryset):
271
283
  return queryset.annotate(mtime=Max("updated_at"))
272
284
 
273
- def annotate_common_aggregates(self, qs, model, search_scores):
285
+ def annotate_common_aggregates(self, qs, model, search_scores: SearchScores | None):
274
286
  """Annotate common aggregates between browser and metadata."""
275
287
  qs = self._annotate_search_score(qs, search_scores, model)
276
288
  qs = self._annotate_child_count(qs, model)
@@ -280,8 +292,8 @@ class BrowserAnnotationsView(BrowserOrderByView):
280
292
  qs = self._annotate_bookmark_updated_at(qs, bm_rel, bm_filter)
281
293
  qs = self._annotate_sort_name(qs, model)
282
294
  qs = self._annotate_story_arc_number(qs)
295
+ # cover depends annotations for order-by, in metadata too
283
296
  qs = self._annotate_order_value(qs, model)
284
- # cover depends on the above annotations for order-by
285
297
  qs = self._annotate_cover_pk(qs, model)
286
298
  qs = self._annotate_bookmarks(qs, model, bm_rel, bm_filter)
287
299
  qs = self._annotate_mtime(qs)
@@ -123,11 +123,9 @@ class BrowserChoicesViewBase(BrowserBaseView):
123
123
 
124
124
  def get_object(self):
125
125
  """Get the comic subquery use for the choices."""
126
- search_scores = self.get_search_scores()
127
- if search_scores is None:
128
- return self.model.objects.none() # type: ignore
129
- object_filter = self.get_query_filters(self.model, search_scores, True)
130
- return self.model.objects.filter(object_filter) # type: ignore
126
+ object_filter = self.get_query_filters(self.model, choices=True)
127
+ qs = self.model.objects.filter(object_filter) # type: ignore
128
+ return self.apply_binary_search_filter(qs)
131
129
 
132
130
  def _set_model(self):
133
131
  """Set the model to query."""
@@ -1,52 +1,144 @@
1
1
  """Search Filters Methods."""
2
2
 
3
+ from dataclasses import dataclass
4
+ from time import time
5
+
3
6
  from django.db.models import Q
4
7
 
5
8
  from codex._vendor.haystack.query import SearchQuerySet
6
9
  from codex.logger.logging import get_logger
7
10
  from codex.models import Comic
11
+ from codex.settings.settings import DEBUG
12
+ from codex.views.browser.const import MAX_OBJ_PER_PAGE
8
13
 
9
14
  LOG = get_logger(__name__)
10
15
 
11
16
 
17
+ @dataclass
18
+ class SearchScores:
19
+ """Search Scores for annotation."""
20
+
21
+ scores: tuple[tuple[int, float], ...] = ()
22
+ scored_pks: tuple[int, ...] = ()
23
+ prev_pks: tuple[int, ...] = ()
24
+ next_pks: tuple[int, ...] = ()
25
+
26
+
12
27
  class SearchFilterMixin:
13
28
  """Search Filters Methods."""
14
29
 
15
- def get_search_scores(self) -> dict | None:
30
+ def _get_binary_search_scores(self, sqs):
31
+ """Get search scores for choices and metadata."""
32
+ sqs = sqs.values_list("pk", flat=True)
33
+ search_results_limit = self.params.get( # type: ignore
34
+ "search_results_limit",
35
+ MAX_OBJ_PER_PAGE, # type: ignore
36
+ )
37
+ if search_results_limit:
38
+ sqs = sqs[:search_results_limit] # type: ignore
39
+ return tuple(sqs)
40
+
41
+ def _get_browser_search_scores(self, sqs):
42
+ """Get search scores for the browser cards."""
43
+ page = self.kwargs.get("page", 1) # type: ignore
44
+ search_results_limit = self.params.get( # type: ignore
45
+ "search_results_limit",
46
+ MAX_OBJ_PER_PAGE, # type: ignore
47
+ )
48
+ if search_results_limit:
49
+ offset = 0
50
+ limit = search_results_limit
51
+ else:
52
+ offset = max(0, (page - 1) * MAX_OBJ_PER_PAGE) # type: ignore
53
+ limit = offset + MAX_OBJ_PER_PAGE # type: ignore
54
+
55
+ if DEBUG:
56
+ LOG.debug(
57
+ f"searching... {page=} page_{offset=} page_{limit=} {search_results_limit=}"
58
+ )
59
+
60
+ scores_pairs = []
61
+ prev_pks = []
62
+ next_pks = []
63
+
64
+ if DEBUG:
65
+ start_time = time()
66
+ scores_values = sqs.values_list("pk", "score")
67
+ if search_results_limit:
68
+ scores_values = scores_values[:limit]
69
+ for index, pair in enumerate(scores_values):
70
+ if index < offset:
71
+ prev_pks.append(pair[0])
72
+ elif index > limit:
73
+ next_pks.append(pair[0])
74
+ else:
75
+ scores_pairs.append(pair)
76
+
77
+ if DEBUG:
78
+ LOG.debug(
79
+ f"search {time() - start_time}s" # type: ignore
80
+ f" {len(scores_pairs)=} {len(prev_pks)=} {len(next_pks)=}"
81
+ )
82
+
83
+ return tuple(scores_pairs), tuple(prev_pks), tuple(next_pks)
84
+
85
+ def get_search_scores(self, binary=False) -> SearchScores | None:
16
86
  """Perform the search and return the scores as a dict."""
17
- search_scores = {}
18
87
  text = self.params.get("q", "") # type: ignore
19
88
  if not text:
20
- return search_scores
89
+ return None
21
90
 
22
- sqs = SearchQuerySet().auto_query(text)
23
- comic_scores = sqs.values("pk", "score")
91
+ scores_pairs = ()
92
+ scored_pks = ()
93
+ prev_pks = ()
94
+ next_pks = ()
24
95
  try:
25
- for comic_score in comic_scores:
26
- search_scores[comic_score["pk"]] = comic_score["score"]
96
+ sqs = SearchQuerySet()
97
+ sqs = sqs.auto_query(text) # .filter(score__gt=0.0)
98
+ if binary:
99
+ scored_pks = self._get_binary_search_scores(sqs)
100
+ else:
101
+ scores_pairs, prev_pks, next_pks = self._get_browser_search_scores(sqs)
102
+
27
103
  except MemoryError:
28
104
  LOG.warning("Search engine needs more memory, results truncated.")
29
105
  except Exception:
30
- LOG.exception("While Searching")
31
- if not search_scores:
32
- return None
33
- return search_scores
106
+ LOG.exception("Getting Search Scores")
107
+ return SearchScores(scores_pairs, scored_pks, prev_pks, next_pks)
34
108
 
35
- def _get_search_query_filter(self, model, search_scores: dict):
109
+ def _get_search_query_filter(
110
+ self,
111
+ model,
112
+ search_scores: SearchScores,
113
+ ):
36
114
  """Get the search filter and scores."""
37
- prefix = "" if model == Comic else self.rel_prefix # type: ignore
38
- rel = prefix + "pk__in"
39
- query_dict = {rel: search_scores.keys()}
40
- return Q(**query_dict)
115
+ if search_scores.scores:
116
+ query = Q(search_score__gt=0.0)
117
+ else:
118
+ prefix = "" if model == Comic else self.rel_prefix # type: ignore
119
+ rel = prefix + "pk__in"
120
+ query_dict = {rel: search_scores.scored_pks}
121
+ query = Q(**query_dict)
122
+ return query
41
123
 
42
- def get_search_filter(self, model, search_scores: dict):
124
+ def apply_search_filter(
125
+ self,
126
+ qs,
127
+ model,
128
+ search_scores: SearchScores | None,
129
+ ):
43
130
  """Preparse search, search and return the filter and scores."""
44
- search_filter = Q()
45
131
  try:
46
132
  if search_scores:
47
- # Query haystack
48
133
  search_filter = self._get_search_query_filter(model, search_scores)
49
- except Exception as exc:
50
- LOG.warning(exc)
134
+ qs = qs.filter(search_filter)
135
+ except Exception:
136
+ LOG.exception("Creating the search filter")
137
+
138
+ return qs
51
139
 
52
- return search_filter
140
+ def apply_binary_search_filter(self, qs):
141
+ """Apply scoreless search filter for choices & metadata."""
142
+ search_scores = self.get_search_scores(binary=True)
143
+ model = self.model # type: ignore
144
+ return self.apply_search_filter(qs, model, search_scores)
@@ -97,7 +97,7 @@ class MetadataView(BrowserAnnotationsView):
97
97
  if not self.is_model_comic:
98
98
  size_func = self.get_aggregate_func(self.model, "size")
99
99
  qs = qs.annotate(size=size_func)
100
- return self.annotate_common_aggregates(qs, self.model, {})
100
+ return self.annotate_common_aggregates(qs, self.model, None)
101
101
 
102
102
  def _annotate_values_and_fks(self, qs, simple_qs):
103
103
  """Annotate comic values and comic foreign key values."""
@@ -242,13 +242,11 @@ class MetadataView(BrowserAnnotationsView):
242
242
  if self.model is None:
243
243
  raise NotFound(detail=f"Cannot get metadata for {self.group=}")
244
244
 
245
- search_scores: dict | None = self.get_search_scores()
246
- if search_scores is None:
247
- self._raise_not_found()
248
- object_filter = self.get_query_filters_without_group(self.model, search_scores) # type: ignore
245
+ object_filter = self.get_query_filters_without_group(self.model)
249
246
  pk = self.kwargs["pk"]
250
247
  qs = self.model.objects.filter(object_filter, pk=pk)
251
-
248
+ if self.model != Comic:
249
+ qs = self.apply_binary_search_filter(qs)
252
250
  qs = self._annotate_aggregates(qs)
253
251
  simple_qs = qs
254
252
 
codex/views/error.py CHANGED
@@ -17,6 +17,7 @@ def codex_exception_handler(exc, context):
17
17
  if _OPDS_PREFIX in request.path:
18
18
  name = "opds:v2:feed" if _OPDS_PREFIX + "2" in request.path else "opds:v1:feed"
19
19
  opds_start = reverse(name)
20
+
20
21
  if isinstance(exc, SeeOtherRedirectError):
21
22
  response = exc.get_response(opds_start)
22
23
  elif hasattr(exc, "status_code") and exc.status_code in (
codex/views/session.py CHANGED
@@ -105,6 +105,7 @@ class BrowserSessionViewBase(SessionViewBaseBase):
105
105
  "order_reverse": False,
106
106
  "q": DEFAULTS["q"],
107
107
  "route": DEFAULTS["route"],
108
+ "search_results_limit": DEFAULTS["searchResultsLimit"],
108
109
  "show": DEFAULTS["show"],
109
110
  "twenty_four_hour_time": False,
110
111
  "top_group": DEFAULTS["topGroup"],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codex
3
- Version: 1.5.13
3
+ Version: 1.5.13a0
4
4
  Summary: A comic archive web server.
5
5
  Home-page: https://github.com/ajslater/codex
6
6
  License: GPL-3.0-only
@@ -30,6 +30,7 @@ Requires-Dist: case-converter (>=1.1.0,<2.0.0)
30
30
  Requires-Dist: channels (>=4.0.0,<5.0.0)
31
31
  Requires-Dist: comicbox[pdf] (>=1.1.4,<2.0.0)
32
32
  Requires-Dist: django (>=5.0.3,<6.0.0)
33
+ Requires-Dist: django-cachalot (>=2.6.2,<3.0.0)
33
34
  Requires-Dist: django-cors-headers (>=4.0,<5.0)
34
35
  Requires-Dist: django-rest-registration (>=0.8.0,<0.9.0)
35
36
  Requires-Dist: django-vite (>=3.0.1,<4.0.0)