codex 1.6.0a9__py3-none-any.whl → 1.6.0a10__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 (547) hide show
  1. codex/librarian/importer/cache.py +46 -133
  2. codex/librarian/importer/create_fks.py +3 -1
  3. codex/librarian/importer/importer.py +1 -1
  4. codex/librarian/importer/importerd.py +5 -5
  5. codex/librarian/importer/tasks.py +2 -2
  6. codex/librarian/janitor/janitor.py +0 -3
  7. codex/librarian/librariand.py +0 -2
  8. codex/librarian/notifier/notifierd.py +1 -1
  9. codex/librarian/notifier/tasks.py +4 -4
  10. codex/middleware.py +1 -2
  11. codex/migrations/0027_import_order_and_covers.py +1 -66
  12. codex/models/comic.py +0 -1
  13. codex/models/groups.py +0 -3
  14. codex/serializers/admin.py +41 -40
  15. codex/serializers/browser/choices.py +22 -6
  16. codex/serializers/browser/metadata.py +45 -1
  17. codex/serializers/browser/page.py +2 -4
  18. codex/serializers/browser/settings.py +34 -14
  19. codex/serializers/fields.py +19 -1
  20. codex/serializers/reader.py +11 -1
  21. codex/serializers/route.py +1 -1
  22. codex/serializers/settings.py +12 -0
  23. codex/settings/settings.py +10 -1
  24. codex/static_root/assets/VCheckbox-CY3rcqlS.de5154294920.js +1 -0
  25. codex/static_root/assets/VCheckbox-CY3rcqlS.de5154294920.js.br +0 -0
  26. codex/static_root/assets/VCheckbox-CY3rcqlS.de5154294920.js.gz +0 -0
  27. codex/static_root/assets/VCheckbox-CY3rcqlS.js +1 -0
  28. codex/static_root/assets/VCheckbox-CY3rcqlS.js.br +0 -0
  29. codex/static_root/assets/VCheckbox-CY3rcqlS.js.gz +0 -0
  30. codex/static_root/assets/{VCheckboxBtn-DLzF_WHB.9a47873b8548.js → VCheckboxBtn-D2tPTt6P.9a90d6818bf6.js} +1 -1
  31. codex/static_root/assets/VCheckboxBtn-D2tPTt6P.9a90d6818bf6.js.br +0 -0
  32. codex/static_root/assets/VCheckboxBtn-D2tPTt6P.9a90d6818bf6.js.gz +0 -0
  33. codex/static_root/assets/{VCheckboxBtn-DLzF_WHB.js → VCheckboxBtn-D2tPTt6P.js} +1 -1
  34. codex/static_root/assets/VCheckboxBtn-D2tPTt6P.js.br +0 -0
  35. codex/static_root/assets/VCheckboxBtn-D2tPTt6P.js.gz +0 -0
  36. codex/static_root/assets/VCombobox-aJr--Ou7.f290ccf2ce25.js +1 -0
  37. codex/static_root/assets/VCombobox-aJr--Ou7.f290ccf2ce25.js.br +0 -0
  38. codex/static_root/assets/VCombobox-aJr--Ou7.f290ccf2ce25.js.gz +0 -0
  39. codex/static_root/assets/VCombobox-aJr--Ou7.js +1 -0
  40. codex/static_root/assets/VCombobox-aJr--Ou7.js.br +0 -0
  41. codex/static_root/assets/VCombobox-aJr--Ou7.js.gz +0 -0
  42. codex/static_root/assets/VDialog-61pzfUB2.33f73beb5224.js +1 -0
  43. codex/static_root/assets/VDialog-61pzfUB2.33f73beb5224.js.br +0 -0
  44. codex/static_root/assets/VDialog-61pzfUB2.33f73beb5224.js.gz +0 -0
  45. codex/static_root/assets/VDialog-61pzfUB2.js +1 -0
  46. codex/static_root/assets/VDialog-61pzfUB2.js.br +0 -0
  47. codex/static_root/assets/VDialog-61pzfUB2.js.gz +0 -0
  48. codex/static_root/assets/{VDialog-C5Nxd_zP.css → VDialog-lQ13FnRR.1c801ad756b2.css} +1 -1
  49. codex/static_root/assets/VDialog-lQ13FnRR.1c801ad756b2.css.br +0 -0
  50. codex/static_root/assets/VDialog-lQ13FnRR.1c801ad756b2.css.gz +0 -0
  51. codex/static_root/assets/{VDialog-C5Nxd_zP.d327f505ef0e.css → VDialog-lQ13FnRR.css} +1 -1
  52. codex/static_root/assets/VDialog-lQ13FnRR.css.br +0 -0
  53. codex/static_root/assets/VDialog-lQ13FnRR.css.gz +0 -0
  54. codex/static_root/assets/VExpansionPanels-rewm0P4z.5c7680f815b6.js +1 -0
  55. codex/static_root/assets/VExpansionPanels-rewm0P4z.5c7680f815b6.js.br +0 -0
  56. codex/static_root/assets/VExpansionPanels-rewm0P4z.5c7680f815b6.js.gz +0 -0
  57. codex/static_root/assets/VExpansionPanels-rewm0P4z.js +1 -0
  58. codex/static_root/assets/VExpansionPanels-rewm0P4z.js.br +0 -0
  59. codex/static_root/assets/VExpansionPanels-rewm0P4z.js.gz +0 -0
  60. codex/static_root/assets/{VRadioGroup-B--7K_v5.4a4e9c2d6c42.js → VRadioGroup-QFQbK1qo.750a42b1b814.js} +1 -1
  61. codex/static_root/assets/VRadioGroup-QFQbK1qo.750a42b1b814.js.br +0 -0
  62. codex/static_root/assets/VRadioGroup-QFQbK1qo.750a42b1b814.js.gz +0 -0
  63. codex/static_root/assets/{VRadioGroup-B--7K_v5.js → VRadioGroup-QFQbK1qo.js} +1 -1
  64. codex/static_root/assets/VRadioGroup-QFQbK1qo.js.br +0 -0
  65. codex/static_root/assets/VRadioGroup-QFQbK1qo.js.gz +0 -0
  66. codex/static_root/assets/VSelect-Dixy6okt.5d53830daa8a.js +1 -0
  67. codex/static_root/assets/VSelect-Dixy6okt.5d53830daa8a.js.br +0 -0
  68. codex/static_root/assets/VSelect-Dixy6okt.5d53830daa8a.js.gz +0 -0
  69. codex/static_root/assets/VSelect-Dixy6okt.js +1 -0
  70. codex/static_root/assets/VSelect-Dixy6okt.js.br +0 -0
  71. codex/static_root/assets/VSelect-Dixy6okt.js.gz +0 -0
  72. codex/static_root/assets/{VSelectionControl-CVQ9wkE2.c02186cceba6.js → VSelectionControl-MNmxKc3J.08055d00917e.js} +1 -1
  73. codex/static_root/assets/VSelectionControl-MNmxKc3J.08055d00917e.js.br +0 -0
  74. codex/static_root/assets/VSelectionControl-MNmxKc3J.08055d00917e.js.gz +0 -0
  75. codex/static_root/assets/{VSelectionControl-CVQ9wkE2.js → VSelectionControl-MNmxKc3J.js} +1 -1
  76. codex/static_root/assets/VSelectionControl-MNmxKc3J.js.br +0 -0
  77. codex/static_root/assets/VSelectionControl-MNmxKc3J.js.gz +0 -0
  78. codex/static_root/assets/VSlideGroup-DZEV0FoV.5f996daf0e98.js +1 -0
  79. codex/static_root/assets/VSlideGroup-DZEV0FoV.5f996daf0e98.js.br +0 -0
  80. codex/static_root/assets/VSlideGroup-DZEV0FoV.5f996daf0e98.js.gz +0 -0
  81. codex/static_root/assets/VSlideGroup-DZEV0FoV.js +1 -0
  82. codex/static_root/assets/VSlideGroup-DZEV0FoV.js.br +0 -0
  83. codex/static_root/assets/VSlideGroup-DZEV0FoV.js.gz +0 -0
  84. codex/static_root/assets/{VTable-CrWkhkiP.6d530eea0c09.js → VTable-lcnYg9Ee.d72927b13c2e.js} +1 -1
  85. codex/static_root/assets/VTable-lcnYg9Ee.d72927b13c2e.js.br +0 -0
  86. codex/static_root/assets/VTable-lcnYg9Ee.d72927b13c2e.js.gz +0 -0
  87. codex/static_root/assets/{VTable-CrWkhkiP.js → VTable-lcnYg9Ee.js} +1 -1
  88. codex/static_root/assets/VTable-lcnYg9Ee.js.br +0 -0
  89. codex/static_root/assets/VTable-lcnYg9Ee.js.gz +0 -0
  90. codex/static_root/assets/VTextField-BkFrjhdV.b02653a9b3b7.js +1 -0
  91. codex/static_root/assets/VTextField-BkFrjhdV.b02653a9b3b7.js.br +0 -0
  92. codex/static_root/assets/VTextField-BkFrjhdV.b02653a9b3b7.js.gz +0 -0
  93. codex/static_root/assets/VTextField-BkFrjhdV.js +1 -0
  94. codex/static_root/assets/VTextField-BkFrjhdV.js.br +0 -0
  95. codex/static_root/assets/VTextField-BkFrjhdV.js.gz +0 -0
  96. codex/static_root/assets/VWindowItem-C__tAqdc.9791c128c3b7.js +1 -0
  97. codex/static_root/assets/VWindowItem-C__tAqdc.9791c128c3b7.js.br +0 -0
  98. codex/static_root/assets/VWindowItem-C__tAqdc.9791c128c3b7.js.gz +0 -0
  99. codex/static_root/assets/VWindowItem-C__tAqdc.js +1 -0
  100. codex/static_root/assets/VWindowItem-C__tAqdc.js.br +0 -0
  101. codex/static_root/assets/VWindowItem-C__tAqdc.js.gz +0 -0
  102. codex/static_root/assets/admin-CXES2HXe.9e48a9bf84e0.js +1 -0
  103. codex/static_root/assets/admin-CXES2HXe.9e48a9bf84e0.js.br +0 -0
  104. codex/static_root/assets/admin-CXES2HXe.9e48a9bf84e0.js.gz +0 -0
  105. codex/static_root/assets/admin-CXES2HXe.js +1 -0
  106. codex/static_root/assets/admin-CXES2HXe.js.br +0 -0
  107. codex/static_root/assets/admin-CXES2HXe.js.gz +0 -0
  108. codex/static_root/assets/{admin-drawer-panel-o87BwD38.ce39427c8201.css → admin-drawer-panel-mne3FIj6.561b3f75fe65.css} +1 -1
  109. codex/static_root/assets/admin-drawer-panel-mne3FIj6.561b3f75fe65.css.br +0 -0
  110. codex/static_root/assets/admin-drawer-panel-mne3FIj6.561b3f75fe65.css.gz +0 -0
  111. codex/static_root/assets/{admin-drawer-panel-o87BwD38.css → admin-drawer-panel-mne3FIj6.css} +1 -1
  112. codex/static_root/assets/admin-drawer-panel-mne3FIj6.css.br +0 -0
  113. codex/static_root/assets/admin-drawer-panel-mne3FIj6.css.gz +0 -0
  114. codex/static_root/assets/admin-drawer-panel-rrNKi_GE.e2b034db7934.js +30 -0
  115. codex/static_root/assets/admin-drawer-panel-rrNKi_GE.e2b034db7934.js.br +0 -0
  116. codex/static_root/assets/admin-drawer-panel-rrNKi_GE.e2b034db7934.js.gz +0 -0
  117. codex/static_root/assets/admin-drawer-panel-rrNKi_GE.js +30 -0
  118. codex/static_root/assets/admin-drawer-panel-rrNKi_GE.js.br +0 -0
  119. codex/static_root/assets/admin-drawer-panel-rrNKi_GE.js.gz +0 -0
  120. codex/static_root/assets/browser-BuDeXGEe.css +1 -0
  121. codex/static_root/assets/browser-BuDeXGEe.css.br +0 -0
  122. codex/static_root/assets/browser-BuDeXGEe.css.gz +0 -0
  123. codex/static_root/assets/browser-BuDeXGEe.f60854183b45.css +1 -0
  124. codex/static_root/assets/browser-BuDeXGEe.f60854183b45.css.br +0 -0
  125. codex/static_root/assets/browser-BuDeXGEe.f60854183b45.css.gz +0 -0
  126. codex/static_root/assets/browser-s6mFzrK9.0d2200b451af.js +1 -0
  127. codex/static_root/assets/browser-s6mFzrK9.0d2200b451af.js.br +0 -0
  128. codex/static_root/assets/browser-s6mFzrK9.0d2200b451af.js.gz +0 -0
  129. codex/static_root/assets/browser-s6mFzrK9.js +1 -0
  130. codex/static_root/assets/browser-s6mFzrK9.js.br +0 -0
  131. codex/static_root/assets/browser-s6mFzrK9.js.gz +0 -0
  132. codex/static_root/assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css +1 -0
  133. codex/static_root/assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css.br +0 -0
  134. codex/static_root/assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css.gz +0 -0
  135. codex/static_root/assets/change-password-dialog-0u6IJA87.css +1 -0
  136. codex/static_root/assets/change-password-dialog-0u6IJA87.css.br +0 -0
  137. codex/static_root/assets/change-password-dialog-0u6IJA87.css.gz +0 -0
  138. codex/static_root/assets/change-password-dialog-Bn20jYzD.593c5af1732b.js +1 -0
  139. codex/static_root/assets/change-password-dialog-Bn20jYzD.593c5af1732b.js.br +0 -0
  140. codex/static_root/assets/change-password-dialog-Bn20jYzD.593c5af1732b.js.gz +0 -0
  141. codex/static_root/assets/change-password-dialog-Bn20jYzD.js +1 -0
  142. codex/static_root/assets/change-password-dialog-Bn20jYzD.js.br +0 -0
  143. codex/static_root/assets/change-password-dialog-Bn20jYzD.js.gz +0 -0
  144. codex/static_root/assets/{confirm-dialog-jwL7B98r.1cfd579cbcfe.js → confirm-dialog-CWszioQE.859051c35dd9.js} +1 -1
  145. codex/static_root/assets/confirm-dialog-CWszioQE.859051c35dd9.js.br +0 -0
  146. codex/static_root/assets/confirm-dialog-CWszioQE.859051c35dd9.js.gz +0 -0
  147. codex/static_root/assets/{confirm-dialog-jwL7B98r.js → confirm-dialog-CWszioQE.js} +1 -1
  148. codex/static_root/assets/confirm-dialog-CWszioQE.js.br +0 -0
  149. codex/static_root/assets/confirm-dialog-CWszioQE.js.gz +0 -0
  150. codex/static_root/assets/datetime-column-BSdlLt-4.27ec2df67a0b.js +1 -0
  151. codex/static_root/assets/datetime-column-BSdlLt-4.27ec2df67a0b.js.br +0 -0
  152. codex/static_root/assets/datetime-column-BSdlLt-4.27ec2df67a0b.js.gz +0 -0
  153. codex/static_root/assets/datetime-column-BSdlLt-4.js +1 -0
  154. codex/static_root/assets/datetime-column-BSdlLt-4.js.br +0 -0
  155. codex/static_root/assets/datetime-column-BSdlLt-4.js.gz +0 -0
  156. codex/static_root/assets/filter-D3gaGf87.1f14dbfd9929.js +1 -0
  157. codex/static_root/assets/filter-D3gaGf87.1f14dbfd9929.js.br +0 -0
  158. codex/static_root/assets/filter-D3gaGf87.1f14dbfd9929.js.gz +0 -0
  159. codex/static_root/assets/filter-D3gaGf87.js +1 -0
  160. codex/static_root/assets/filter-D3gaGf87.js.br +0 -0
  161. codex/static_root/assets/filter-D3gaGf87.js.gz +0 -0
  162. codex/static_root/assets/{flag-tab-Da2DBNyz.ffbe5ca37e1c.js → flag-tab-8vzpdySX.a982c7f0776a.js} +1 -1
  163. codex/static_root/assets/flag-tab-8vzpdySX.a982c7f0776a.js.br +0 -0
  164. codex/static_root/assets/flag-tab-8vzpdySX.a982c7f0776a.js.gz +0 -0
  165. codex/static_root/assets/{flag-tab-Da2DBNyz.js → flag-tab-8vzpdySX.js} +1 -1
  166. codex/static_root/assets/flag-tab-8vzpdySX.js.br +0 -0
  167. codex/static_root/assets/flag-tab-8vzpdySX.js.gz +0 -0
  168. codex/static_root/assets/{group-tab-BONYWOc1.6ddf321a4a56.js → group-tab-Cz9t_ECi.a9e8aea79254.js} +1 -1
  169. codex/static_root/assets/group-tab-Cz9t_ECi.a9e8aea79254.js.br +0 -0
  170. codex/static_root/assets/group-tab-Cz9t_ECi.a9e8aea79254.js.gz +0 -0
  171. codex/static_root/assets/{group-tab-BONYWOc1.js → group-tab-Cz9t_ECi.js} +1 -1
  172. codex/static_root/assets/group-tab-Cz9t_ECi.js.br +0 -0
  173. codex/static_root/assets/group-tab-Cz9t_ECi.js.gz +0 -0
  174. codex/static_root/assets/{http-error-D2Jnc20C.32846bc3a43d.js → http-error-Cqtszzf1.b31df3d9c29f.js} +1 -1
  175. codex/static_root/assets/http-error-Cqtszzf1.b31df3d9c29f.js.br +0 -0
  176. codex/static_root/assets/http-error-Cqtszzf1.b31df3d9c29f.js.gz +0 -0
  177. codex/static_root/assets/{http-error-D2Jnc20C.js → http-error-Cqtszzf1.js} +1 -1
  178. codex/static_root/assets/http-error-Cqtszzf1.js.br +0 -0
  179. codex/static_root/assets/http-error-Cqtszzf1.js.gz +0 -0
  180. codex/static_root/assets/{library-tab-B419agXA.js → library-tab-DMlnswUU.30f454e84184.js} +1 -1
  181. codex/static_root/assets/library-tab-DMlnswUU.30f454e84184.js.br +0 -0
  182. codex/static_root/assets/library-tab-DMlnswUU.30f454e84184.js.gz +0 -0
  183. codex/static_root/assets/{library-tab-B419agXA.d4b778172aaa.js → library-tab-DMlnswUU.js} +1 -1
  184. codex/static_root/assets/library-tab-DMlnswUU.js.br +0 -0
  185. codex/static_root/assets/library-tab-DMlnswUU.js.gz +0 -0
  186. codex/static_root/assets/main-vjXu_QYL.548bd4c38799.js +32 -0
  187. codex/static_root/assets/main-vjXu_QYL.548bd4c38799.js.br +0 -0
  188. codex/static_root/assets/main-vjXu_QYL.548bd4c38799.js.gz +0 -0
  189. codex/static_root/assets/main-vjXu_QYL.js +32 -0
  190. codex/static_root/assets/main-vjXu_QYL.js.br +0 -0
  191. codex/static_root/assets/main-vjXu_QYL.js.gz +0 -0
  192. codex/static_root/assets/pagination-toolbar-DGdMiBRs.5829b01b8a2f.css +1 -0
  193. codex/static_root/assets/pagination-toolbar-DGdMiBRs.5829b01b8a2f.css.br +0 -0
  194. codex/static_root/assets/pagination-toolbar-DGdMiBRs.5829b01b8a2f.css.gz +0 -0
  195. codex/static_root/assets/pagination-toolbar-DGdMiBRs.css +1 -0
  196. codex/static_root/assets/pagination-toolbar-DGdMiBRs.css.br +0 -0
  197. codex/static_root/assets/pagination-toolbar-DGdMiBRs.css.gz +0 -0
  198. codex/static_root/assets/pagination-toolbar-JW78pa0q.91024effdab9.js +1 -0
  199. codex/static_root/assets/pagination-toolbar-JW78pa0q.91024effdab9.js.br +0 -0
  200. codex/static_root/assets/pagination-toolbar-JW78pa0q.91024effdab9.js.gz +0 -0
  201. codex/static_root/assets/pagination-toolbar-JW78pa0q.js +1 -0
  202. codex/static_root/assets/pagination-toolbar-JW78pa0q.js.br +0 -0
  203. codex/static_root/assets/pagination-toolbar-JW78pa0q.js.gz +0 -0
  204. codex/static_root/assets/{pdf-doc-8RVZqILx.2e7166dd26fb.js → pdf-doc-BiamrjRZ.4c9be1ade43c.js} +1 -1
  205. codex/static_root/assets/pdf-doc-BiamrjRZ.4c9be1ade43c.js.br +0 -0
  206. codex/static_root/assets/pdf-doc-BiamrjRZ.4c9be1ade43c.js.gz +0 -0
  207. codex/static_root/assets/{pdf-doc-8RVZqILx.js → pdf-doc-BiamrjRZ.js} +1 -1
  208. codex/static_root/assets/pdf-doc-BiamrjRZ.js.br +0 -0
  209. codex/static_root/assets/pdf-doc-BiamrjRZ.js.gz +0 -0
  210. codex/static_root/assets/{reader-CCCfpM3x.1553e45bd775.css → reader-BpsctRsY.5d72e393911a.css} +1 -1
  211. codex/static_root/assets/reader-BpsctRsY.5d72e393911a.css.br +0 -0
  212. codex/static_root/assets/reader-BpsctRsY.5d72e393911a.css.gz +0 -0
  213. codex/static_root/assets/{reader-CCCfpM3x.css → reader-BpsctRsY.css} +1 -1
  214. codex/static_root/assets/reader-BpsctRsY.css.br +0 -0
  215. codex/static_root/assets/reader-BpsctRsY.css.gz +0 -0
  216. codex/static_root/assets/reader-CDk8oZzB.ad62eebda920.js +2 -0
  217. codex/static_root/assets/reader-CDk8oZzB.ad62eebda920.js.br +0 -0
  218. codex/static_root/assets/reader-CDk8oZzB.ad62eebda920.js.gz +0 -0
  219. codex/static_root/assets/reader-CDk8oZzB.js +2 -0
  220. codex/static_root/assets/reader-CDk8oZzB.js.br +0 -0
  221. codex/static_root/assets/reader-CDk8oZzB.js.gz +0 -0
  222. codex/static_root/assets/relation-chips-C5acBjpy.dc67d4528868.js +1 -0
  223. codex/static_root/assets/relation-chips-C5acBjpy.dc67d4528868.js.br +0 -0
  224. codex/static_root/assets/relation-chips-C5acBjpy.dc67d4528868.js.gz +0 -0
  225. codex/static_root/assets/relation-chips-C5acBjpy.js +1 -0
  226. codex/static_root/assets/relation-chips-C5acBjpy.js.br +0 -0
  227. codex/static_root/assets/relation-chips-C5acBjpy.js.gz +0 -0
  228. codex/static_root/assets/settings-drawer-D_JuRi7F.f02f3f981f8f.js +2 -0
  229. codex/static_root/assets/settings-drawer-D_JuRi7F.f02f3f981f8f.js.br +0 -0
  230. codex/static_root/assets/settings-drawer-D_JuRi7F.f02f3f981f8f.js.gz +0 -0
  231. codex/static_root/assets/settings-drawer-D_JuRi7F.js +2 -0
  232. codex/static_root/assets/settings-drawer-D_JuRi7F.js.br +0 -0
  233. codex/static_root/assets/settings-drawer-D_JuRi7F.js.gz +0 -0
  234. codex/static_root/assets/stats-tab-B4yKuY0c.a5728396494b.css +1 -0
  235. codex/static_root/assets/stats-tab-B4yKuY0c.a5728396494b.css.br +0 -0
  236. codex/static_root/assets/stats-tab-B4yKuY0c.a5728396494b.css.gz +0 -0
  237. codex/static_root/assets/stats-tab-B4yKuY0c.css +1 -0
  238. codex/static_root/assets/stats-tab-B4yKuY0c.css.br +0 -0
  239. codex/static_root/assets/stats-tab-B4yKuY0c.css.gz +0 -0
  240. codex/static_root/assets/stats-tab-ClqRTk1z.c759ace65a87.js +1 -0
  241. codex/static_root/assets/stats-tab-ClqRTk1z.c759ace65a87.js.br +0 -0
  242. codex/static_root/assets/stats-tab-ClqRTk1z.c759ace65a87.js.gz +0 -0
  243. codex/static_root/assets/stats-tab-ClqRTk1z.js +1 -0
  244. codex/static_root/assets/stats-tab-ClqRTk1z.js.br +0 -0
  245. codex/static_root/assets/stats-tab-ClqRTk1z.js.gz +0 -0
  246. codex/static_root/assets/task-tab-DF9qa6LO.0b32cafde4ad.js +1 -0
  247. codex/static_root/assets/task-tab-DF9qa6LO.0b32cafde4ad.js.br +0 -0
  248. codex/static_root/assets/task-tab-DF9qa6LO.0b32cafde4ad.js.gz +0 -0
  249. codex/static_root/assets/task-tab-DF9qa6LO.js +1 -0
  250. codex/static_root/assets/task-tab-DF9qa6LO.js.br +0 -0
  251. codex/static_root/assets/task-tab-DF9qa6LO.js.gz +0 -0
  252. codex/static_root/assets/to-case-CGbULRaE.4c80644f460d.js +1 -0
  253. codex/static_root/assets/to-case-CGbULRaE.4c80644f460d.js.br +0 -0
  254. codex/static_root/assets/to-case-CGbULRaE.js +1 -0
  255. codex/static_root/assets/to-case-CGbULRaE.js.br +0 -0
  256. codex/static_root/assets/unauthorized-BjKuLH6k.2ae00ddd79fb.js +1 -0
  257. codex/static_root/assets/unauthorized-BjKuLH6k.2ae00ddd79fb.js.br +0 -0
  258. codex/static_root/assets/unauthorized-BjKuLH6k.2ae00ddd79fb.js.gz +0 -0
  259. codex/static_root/assets/unauthorized-BjKuLH6k.js +1 -0
  260. codex/static_root/assets/unauthorized-BjKuLH6k.js.br +0 -0
  261. codex/static_root/assets/unauthorized-BjKuLH6k.js.gz +0 -0
  262. codex/static_root/assets/{unauthorized-DHV6Q1n-.b7847b2872a1.css → unauthorized-CibJYD8o.4c2de98c2b53.css} +1 -1
  263. codex/static_root/assets/unauthorized-CibJYD8o.4c2de98c2b53.css.br +0 -0
  264. codex/static_root/assets/unauthorized-CibJYD8o.4c2de98c2b53.css.gz +0 -0
  265. codex/static_root/assets/{unauthorized-DHV6Q1n-.css → unauthorized-CibJYD8o.css} +1 -1
  266. codex/static_root/assets/unauthorized-CibJYD8o.css.br +0 -0
  267. codex/static_root/assets/unauthorized-CibJYD8o.css.gz +0 -0
  268. codex/static_root/assets/user-tab-Dpxe3ygA.7d90174631f0.js +1 -0
  269. codex/static_root/assets/user-tab-Dpxe3ygA.7d90174631f0.js.br +0 -0
  270. codex/static_root/assets/user-tab-Dpxe3ygA.7d90174631f0.js.gz +0 -0
  271. codex/static_root/assets/user-tab-Dpxe3ygA.js +1 -0
  272. codex/static_root/assets/user-tab-Dpxe3ygA.js.br +0 -0
  273. codex/static_root/assets/user-tab-Dpxe3ygA.js.gz +0 -0
  274. codex/static_root/js/choices-admin.3521e2a863df.json +1 -0
  275. codex/static_root/js/choices-admin.3521e2a863df.json.br +0 -0
  276. codex/static_root/js/choices-admin.3521e2a863df.json.gz +0 -0
  277. codex/static_root/js/choices-admin.json +1 -1
  278. codex/static_root/js/choices-admin.json.br +0 -0
  279. codex/static_root/js/choices-admin.json.gz +0 -0
  280. codex/static_root/manifest.35e46a3ec8fa.json +622 -0
  281. codex/static_root/manifest.35e46a3ec8fa.json.br +0 -0
  282. codex/static_root/manifest.35e46a3ec8fa.json.gz +0 -0
  283. codex/static_root/manifest.json +245 -252
  284. codex/static_root/manifest.json.br +0 -0
  285. codex/static_root/manifest.json.gz +0 -0
  286. codex/static_root/staticfiles.json +1 -1
  287. codex/views/admin/api_key.py +5 -2
  288. codex/views/admin/stats.py +13 -20
  289. codex/views/admin/tasks.py +2 -3
  290. codex/views/auth.py +1 -1
  291. codex/views/bookmark.py +30 -16
  292. codex/views/browser/annotations.py +2 -0
  293. codex/views/browser/base.py +22 -6
  294. codex/views/browser/breadcrumbs.py +5 -5
  295. codex/views/browser/browser.py +14 -22
  296. codex/views/browser/choices.py +18 -15
  297. codex/views/browser/cover.py +30 -66
  298. codex/views/browser/filters/annotations.py +14 -6
  299. codex/views/browser/filters/group.py +24 -15
  300. codex/views/browser/filters/search.py +3 -4
  301. codex/views/browser/metadata.py +86 -47
  302. codex/views/browser/mtime.py +3 -14
  303. codex/views/browser/order_by.py +1 -6
  304. codex/views/browser/settings.py +53 -0
  305. codex/views/browser/validate.py +3 -0
  306. codex/views/const.py +24 -1
  307. codex/views/opds/v1/feed.py +3 -5
  308. codex/views/opds/v2/feed.py +3 -3
  309. codex/views/reader/arcs.py +42 -51
  310. codex/views/reader/books.py +47 -63
  311. codex/views/reader/init.py +121 -0
  312. codex/views/reader/reader.py +9 -70
  313. codex/views/session.py +15 -11
  314. codex/views/settings.py +23 -10
  315. codex/views/util.py +2 -1
  316. codex/websockets/consumers.py +13 -9
  317. {codex-1.6.0a9.dist-info → codex-1.6.0a10.dist-info}/METADATA +1 -1
  318. {codex-1.6.0a9.dist-info → codex-1.6.0a10.dist-info}/RECORD +321 -317
  319. codex/static_root/assets/VCheckbox-eNspVUje.da8282a08876.js +0 -1
  320. codex/static_root/assets/VCheckbox-eNspVUje.da8282a08876.js.br +0 -0
  321. codex/static_root/assets/VCheckbox-eNspVUje.da8282a08876.js.gz +0 -0
  322. codex/static_root/assets/VCheckbox-eNspVUje.js +0 -1
  323. codex/static_root/assets/VCheckbox-eNspVUje.js.br +0 -0
  324. codex/static_root/assets/VCheckbox-eNspVUje.js.gz +0 -0
  325. codex/static_root/assets/VCheckboxBtn-DLzF_WHB.9a47873b8548.js.br +0 -0
  326. codex/static_root/assets/VCheckboxBtn-DLzF_WHB.9a47873b8548.js.gz +0 -0
  327. codex/static_root/assets/VCheckboxBtn-DLzF_WHB.js.br +0 -0
  328. codex/static_root/assets/VCheckboxBtn-DLzF_WHB.js.gz +0 -0
  329. codex/static_root/assets/VCombobox-BIO7lU_B.d607ada71b06.js +0 -1
  330. codex/static_root/assets/VCombobox-BIO7lU_B.d607ada71b06.js.br +0 -0
  331. codex/static_root/assets/VCombobox-BIO7lU_B.d607ada71b06.js.gz +0 -0
  332. codex/static_root/assets/VCombobox-BIO7lU_B.js +0 -1
  333. codex/static_root/assets/VCombobox-BIO7lU_B.js.br +0 -0
  334. codex/static_root/assets/VCombobox-BIO7lU_B.js.gz +0 -0
  335. codex/static_root/assets/VDialog-87AymJC5.4a46716358c0.js +0 -1
  336. codex/static_root/assets/VDialog-87AymJC5.4a46716358c0.js.br +0 -0
  337. codex/static_root/assets/VDialog-87AymJC5.4a46716358c0.js.gz +0 -0
  338. codex/static_root/assets/VDialog-87AymJC5.js +0 -1
  339. codex/static_root/assets/VDialog-87AymJC5.js.br +0 -0
  340. codex/static_root/assets/VDialog-87AymJC5.js.gz +0 -0
  341. codex/static_root/assets/VDialog-C5Nxd_zP.css.br +0 -0
  342. codex/static_root/assets/VDialog-C5Nxd_zP.css.gz +0 -0
  343. codex/static_root/assets/VDialog-C5Nxd_zP.d327f505ef0e.css.br +0 -0
  344. codex/static_root/assets/VDialog-C5Nxd_zP.d327f505ef0e.css.gz +0 -0
  345. codex/static_root/assets/VExpansionPanels-CgA3shsd.9e524c73726a.js +0 -1
  346. codex/static_root/assets/VExpansionPanels-CgA3shsd.9e524c73726a.js.br +0 -0
  347. codex/static_root/assets/VExpansionPanels-CgA3shsd.9e524c73726a.js.gz +0 -0
  348. codex/static_root/assets/VExpansionPanels-CgA3shsd.js +0 -1
  349. codex/static_root/assets/VExpansionPanels-CgA3shsd.js.br +0 -0
  350. codex/static_root/assets/VExpansionPanels-CgA3shsd.js.gz +0 -0
  351. codex/static_root/assets/VRadioGroup-B--7K_v5.4a4e9c2d6c42.js.br +0 -0
  352. codex/static_root/assets/VRadioGroup-B--7K_v5.4a4e9c2d6c42.js.gz +0 -0
  353. codex/static_root/assets/VRadioGroup-B--7K_v5.js.br +0 -0
  354. codex/static_root/assets/VRadioGroup-B--7K_v5.js.gz +0 -0
  355. codex/static_root/assets/VSelect-BoJq222l.fc714657e214.js +0 -1
  356. codex/static_root/assets/VSelect-BoJq222l.fc714657e214.js.br +0 -0
  357. codex/static_root/assets/VSelect-BoJq222l.fc714657e214.js.gz +0 -0
  358. codex/static_root/assets/VSelect-BoJq222l.js +0 -1
  359. codex/static_root/assets/VSelect-BoJq222l.js.br +0 -0
  360. codex/static_root/assets/VSelect-BoJq222l.js.gz +0 -0
  361. codex/static_root/assets/VSelectionControl-CVQ9wkE2.c02186cceba6.js.br +0 -0
  362. codex/static_root/assets/VSelectionControl-CVQ9wkE2.c02186cceba6.js.gz +0 -0
  363. codex/static_root/assets/VSelectionControl-CVQ9wkE2.js.br +0 -0
  364. codex/static_root/assets/VSelectionControl-CVQ9wkE2.js.gz +0 -0
  365. codex/static_root/assets/VSlideGroup-Ce0j2BKK.85e64443a928.js +0 -1
  366. codex/static_root/assets/VSlideGroup-Ce0j2BKK.85e64443a928.js.br +0 -0
  367. codex/static_root/assets/VSlideGroup-Ce0j2BKK.85e64443a928.js.gz +0 -0
  368. codex/static_root/assets/VSlideGroup-Ce0j2BKK.js +0 -1
  369. codex/static_root/assets/VSlideGroup-Ce0j2BKK.js.br +0 -0
  370. codex/static_root/assets/VSlideGroup-Ce0j2BKK.js.gz +0 -0
  371. codex/static_root/assets/VTable-CrWkhkiP.6d530eea0c09.js.br +0 -0
  372. codex/static_root/assets/VTable-CrWkhkiP.6d530eea0c09.js.gz +0 -0
  373. codex/static_root/assets/VTable-CrWkhkiP.js.br +0 -0
  374. codex/static_root/assets/VTable-CrWkhkiP.js.gz +0 -0
  375. codex/static_root/assets/VTextField-CkWbil3K.2cac13161dfe.js +0 -1
  376. codex/static_root/assets/VTextField-CkWbil3K.2cac13161dfe.js.br +0 -0
  377. codex/static_root/assets/VTextField-CkWbil3K.2cac13161dfe.js.gz +0 -0
  378. codex/static_root/assets/VTextField-CkWbil3K.js +0 -1
  379. codex/static_root/assets/VTextField-CkWbil3K.js.br +0 -0
  380. codex/static_root/assets/VTextField-CkWbil3K.js.gz +0 -0
  381. codex/static_root/assets/VWindowItem-7z55Y4lK.98eb7487e039.js +0 -1
  382. codex/static_root/assets/VWindowItem-7z55Y4lK.98eb7487e039.js.br +0 -0
  383. codex/static_root/assets/VWindowItem-7z55Y4lK.98eb7487e039.js.gz +0 -0
  384. codex/static_root/assets/VWindowItem-7z55Y4lK.js +0 -1
  385. codex/static_root/assets/VWindowItem-7z55Y4lK.js.br +0 -0
  386. codex/static_root/assets/VWindowItem-7z55Y4lK.js.gz +0 -0
  387. codex/static_root/assets/admin-D3OK784R.f69891726ec5.js +0 -1
  388. codex/static_root/assets/admin-D3OK784R.f69891726ec5.js.br +0 -0
  389. codex/static_root/assets/admin-D3OK784R.f69891726ec5.js.gz +0 -0
  390. codex/static_root/assets/admin-D3OK784R.js +0 -1
  391. codex/static_root/assets/admin-D3OK784R.js.br +0 -0
  392. codex/static_root/assets/admin-D3OK784R.js.gz +0 -0
  393. codex/static_root/assets/admin-drawer-panel-1pnfvY8O.5438f252970e.js +0 -30
  394. codex/static_root/assets/admin-drawer-panel-1pnfvY8O.5438f252970e.js.br +0 -0
  395. codex/static_root/assets/admin-drawer-panel-1pnfvY8O.5438f252970e.js.gz +0 -0
  396. codex/static_root/assets/admin-drawer-panel-1pnfvY8O.js +0 -30
  397. codex/static_root/assets/admin-drawer-panel-1pnfvY8O.js.br +0 -0
  398. codex/static_root/assets/admin-drawer-panel-1pnfvY8O.js.gz +0 -0
  399. codex/static_root/assets/admin-drawer-panel-o87BwD38.ce39427c8201.css.br +0 -0
  400. codex/static_root/assets/admin-drawer-panel-o87BwD38.ce39427c8201.css.gz +0 -0
  401. codex/static_root/assets/admin-drawer-panel-o87BwD38.css.br +0 -0
  402. codex/static_root/assets/admin-drawer-panel-o87BwD38.css.gz +0 -0
  403. codex/static_root/assets/browser-BuU2x9y7.css +0 -1
  404. codex/static_root/assets/browser-BuU2x9y7.css.br +0 -0
  405. codex/static_root/assets/browser-BuU2x9y7.css.gz +0 -0
  406. codex/static_root/assets/browser-BuU2x9y7.f67595d24664.css +0 -1
  407. codex/static_root/assets/browser-BuU2x9y7.f67595d24664.css.br +0 -0
  408. codex/static_root/assets/browser-BuU2x9y7.f67595d24664.css.gz +0 -0
  409. codex/static_root/assets/browser-CO9EYHIr.be49367c6a75.js +0 -1
  410. codex/static_root/assets/browser-CO9EYHIr.be49367c6a75.js.br +0 -0
  411. codex/static_root/assets/browser-CO9EYHIr.be49367c6a75.js.gz +0 -0
  412. codex/static_root/assets/browser-CO9EYHIr.js +0 -1
  413. codex/static_root/assets/browser-CO9EYHIr.js.br +0 -0
  414. codex/static_root/assets/browser-CO9EYHIr.js.gz +0 -0
  415. codex/static_root/assets/change-password-dialog-CjZdzaIk.188c765431ab.js +0 -1
  416. codex/static_root/assets/change-password-dialog-CjZdzaIk.188c765431ab.js.br +0 -0
  417. codex/static_root/assets/change-password-dialog-CjZdzaIk.188c765431ab.js.gz +0 -0
  418. codex/static_root/assets/change-password-dialog-CjZdzaIk.js +0 -1
  419. codex/static_root/assets/change-password-dialog-CjZdzaIk.js.br +0 -0
  420. codex/static_root/assets/change-password-dialog-CjZdzaIk.js.gz +0 -0
  421. codex/static_root/assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css +0 -1
  422. codex/static_root/assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css.br +0 -0
  423. codex/static_root/assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css.gz +0 -0
  424. codex/static_root/assets/change-password-dialog-HvIvmmIE.css +0 -1
  425. codex/static_root/assets/change-password-dialog-HvIvmmIE.css.br +0 -0
  426. codex/static_root/assets/change-password-dialog-HvIvmmIE.css.gz +0 -0
  427. codex/static_root/assets/confirm-dialog-jwL7B98r.1cfd579cbcfe.js.br +0 -0
  428. codex/static_root/assets/confirm-dialog-jwL7B98r.1cfd579cbcfe.js.gz +0 -0
  429. codex/static_root/assets/confirm-dialog-jwL7B98r.js.br +0 -0
  430. codex/static_root/assets/confirm-dialog-jwL7B98r.js.gz +0 -0
  431. codex/static_root/assets/datetime-column-9w3GcKvo.f9172256f091.js +0 -1
  432. codex/static_root/assets/datetime-column-9w3GcKvo.f9172256f091.js.br +0 -0
  433. codex/static_root/assets/datetime-column-9w3GcKvo.f9172256f091.js.gz +0 -0
  434. codex/static_root/assets/datetime-column-9w3GcKvo.js +0 -1
  435. codex/static_root/assets/datetime-column-9w3GcKvo.js.br +0 -0
  436. codex/static_root/assets/datetime-column-9w3GcKvo.js.gz +0 -0
  437. codex/static_root/assets/filter-C-pghOri.eeb7c2ecf398.js +0 -1
  438. codex/static_root/assets/filter-C-pghOri.eeb7c2ecf398.js.br +0 -0
  439. codex/static_root/assets/filter-C-pghOri.eeb7c2ecf398.js.gz +0 -0
  440. codex/static_root/assets/filter-C-pghOri.js +0 -1
  441. codex/static_root/assets/filter-C-pghOri.js.br +0 -0
  442. codex/static_root/assets/filter-C-pghOri.js.gz +0 -0
  443. codex/static_root/assets/flag-tab-Da2DBNyz.ffbe5ca37e1c.js.br +0 -0
  444. codex/static_root/assets/flag-tab-Da2DBNyz.ffbe5ca37e1c.js.gz +0 -0
  445. codex/static_root/assets/flag-tab-Da2DBNyz.js.br +0 -0
  446. codex/static_root/assets/flag-tab-Da2DBNyz.js.gz +0 -0
  447. codex/static_root/assets/group-tab-BONYWOc1.6ddf321a4a56.js.br +0 -0
  448. codex/static_root/assets/group-tab-BONYWOc1.6ddf321a4a56.js.gz +0 -0
  449. codex/static_root/assets/group-tab-BONYWOc1.js.br +0 -0
  450. codex/static_root/assets/group-tab-BONYWOc1.js.gz +0 -0
  451. codex/static_root/assets/http-error-D2Jnc20C.32846bc3a43d.js.br +0 -0
  452. codex/static_root/assets/http-error-D2Jnc20C.32846bc3a43d.js.gz +0 -0
  453. codex/static_root/assets/http-error-D2Jnc20C.js.br +0 -0
  454. codex/static_root/assets/http-error-D2Jnc20C.js.gz +0 -0
  455. codex/static_root/assets/library-tab-B419agXA.d4b778172aaa.js.br +0 -0
  456. codex/static_root/assets/library-tab-B419agXA.d4b778172aaa.js.gz +0 -0
  457. codex/static_root/assets/library-tab-B419agXA.js.br +0 -0
  458. codex/static_root/assets/library-tab-B419agXA.js.gz +0 -0
  459. codex/static_root/assets/main-CMQwJ9aG.9836fe81c80a.js +0 -32
  460. codex/static_root/assets/main-CMQwJ9aG.9836fe81c80a.js.br +0 -0
  461. codex/static_root/assets/main-CMQwJ9aG.9836fe81c80a.js.gz +0 -0
  462. codex/static_root/assets/main-CMQwJ9aG.js +0 -32
  463. codex/static_root/assets/main-CMQwJ9aG.js.br +0 -0
  464. codex/static_root/assets/main-CMQwJ9aG.js.gz +0 -0
  465. codex/static_root/assets/pagination-toolbar-DWdp_kmz.css +0 -1
  466. codex/static_root/assets/pagination-toolbar-DWdp_kmz.css.br +0 -0
  467. codex/static_root/assets/pagination-toolbar-DWdp_kmz.css.gz +0 -0
  468. codex/static_root/assets/pagination-toolbar-DWdp_kmz.f98f47e87612.css +0 -1
  469. codex/static_root/assets/pagination-toolbar-DWdp_kmz.f98f47e87612.css.br +0 -0
  470. codex/static_root/assets/pagination-toolbar-DWdp_kmz.f98f47e87612.css.gz +0 -0
  471. codex/static_root/assets/pagination-toolbar-LTuj5U-G.a295defbcd2f.js +0 -1
  472. codex/static_root/assets/pagination-toolbar-LTuj5U-G.a295defbcd2f.js.br +0 -0
  473. codex/static_root/assets/pagination-toolbar-LTuj5U-G.a295defbcd2f.js.gz +0 -0
  474. codex/static_root/assets/pagination-toolbar-LTuj5U-G.js +0 -1
  475. codex/static_root/assets/pagination-toolbar-LTuj5U-G.js.br +0 -0
  476. codex/static_root/assets/pagination-toolbar-LTuj5U-G.js.gz +0 -0
  477. codex/static_root/assets/pdf-doc-8RVZqILx.2e7166dd26fb.js.br +0 -0
  478. codex/static_root/assets/pdf-doc-8RVZqILx.2e7166dd26fb.js.gz +0 -0
  479. codex/static_root/assets/pdf-doc-8RVZqILx.js.br +0 -0
  480. codex/static_root/assets/pdf-doc-8RVZqILx.js.gz +0 -0
  481. codex/static_root/assets/reader-CCCfpM3x.1553e45bd775.css.br +0 -0
  482. codex/static_root/assets/reader-CCCfpM3x.1553e45bd775.css.gz +0 -0
  483. codex/static_root/assets/reader-CCCfpM3x.css.br +0 -0
  484. codex/static_root/assets/reader-CCCfpM3x.css.gz +0 -0
  485. codex/static_root/assets/reader-DNnK_Chr.114d0e321547.js +0 -2
  486. codex/static_root/assets/reader-DNnK_Chr.114d0e321547.js.br +0 -0
  487. codex/static_root/assets/reader-DNnK_Chr.114d0e321547.js.gz +0 -0
  488. codex/static_root/assets/reader-DNnK_Chr.js +0 -2
  489. codex/static_root/assets/reader-DNnK_Chr.js.br +0 -0
  490. codex/static_root/assets/reader-DNnK_Chr.js.gz +0 -0
  491. codex/static_root/assets/relation-chips-PYua7aXv.428ba0b5861e.js +0 -1
  492. codex/static_root/assets/relation-chips-PYua7aXv.428ba0b5861e.js.br +0 -0
  493. codex/static_root/assets/relation-chips-PYua7aXv.428ba0b5861e.js.gz +0 -0
  494. codex/static_root/assets/relation-chips-PYua7aXv.js +0 -1
  495. codex/static_root/assets/relation-chips-PYua7aXv.js.br +0 -0
  496. codex/static_root/assets/relation-chips-PYua7aXv.js.gz +0 -0
  497. codex/static_root/assets/settings-drawer-DbN6ISRH.d14f525d8eee.js +0 -2
  498. codex/static_root/assets/settings-drawer-DbN6ISRH.d14f525d8eee.js.br +0 -0
  499. codex/static_root/assets/settings-drawer-DbN6ISRH.d14f525d8eee.js.gz +0 -0
  500. codex/static_root/assets/settings-drawer-DbN6ISRH.js +0 -2
  501. codex/static_root/assets/settings-drawer-DbN6ISRH.js.br +0 -0
  502. codex/static_root/assets/settings-drawer-DbN6ISRH.js.gz +0 -0
  503. codex/static_root/assets/stats-tab-DImNhH8O.d5026283841a.js +0 -1
  504. codex/static_root/assets/stats-tab-DImNhH8O.d5026283841a.js.br +0 -0
  505. codex/static_root/assets/stats-tab-DImNhH8O.d5026283841a.js.gz +0 -0
  506. codex/static_root/assets/stats-tab-DImNhH8O.js +0 -1
  507. codex/static_root/assets/stats-tab-DImNhH8O.js.br +0 -0
  508. codex/static_root/assets/stats-tab-DImNhH8O.js.gz +0 -0
  509. codex/static_root/assets/stats-tab-TsyG3wH_.b93c080356fc.css +0 -1
  510. codex/static_root/assets/stats-tab-TsyG3wH_.b93c080356fc.css.br +0 -2
  511. codex/static_root/assets/stats-tab-TsyG3wH_.b93c080356fc.css.gz +0 -0
  512. codex/static_root/assets/stats-tab-TsyG3wH_.css +0 -1
  513. codex/static_root/assets/stats-tab-TsyG3wH_.css.br +0 -2
  514. codex/static_root/assets/stats-tab-TsyG3wH_.css.gz +0 -0
  515. codex/static_root/assets/task-tab-DPD53kjv.e56a35ff1691.js +0 -1
  516. codex/static_root/assets/task-tab-DPD53kjv.e56a35ff1691.js.br +0 -0
  517. codex/static_root/assets/task-tab-DPD53kjv.e56a35ff1691.js.gz +0 -0
  518. codex/static_root/assets/task-tab-DPD53kjv.js +0 -1
  519. codex/static_root/assets/task-tab-DPD53kjv.js.br +0 -0
  520. codex/static_root/assets/task-tab-DPD53kjv.js.gz +0 -0
  521. codex/static_root/assets/to-case-ehC9Ccyj.a7b8e25b391f.js +0 -1
  522. codex/static_root/assets/to-case-ehC9Ccyj.js +0 -1
  523. codex/static_root/assets/unauthorized-BOIx7Y18.ee3961abfccb.js +0 -1
  524. codex/static_root/assets/unauthorized-BOIx7Y18.ee3961abfccb.js.br +0 -0
  525. codex/static_root/assets/unauthorized-BOIx7Y18.ee3961abfccb.js.gz +0 -0
  526. codex/static_root/assets/unauthorized-BOIx7Y18.js +0 -1
  527. codex/static_root/assets/unauthorized-BOIx7Y18.js.br +0 -0
  528. codex/static_root/assets/unauthorized-BOIx7Y18.js.gz +0 -0
  529. codex/static_root/assets/unauthorized-DHV6Q1n-.b7847b2872a1.css.br +0 -0
  530. codex/static_root/assets/unauthorized-DHV6Q1n-.b7847b2872a1.css.gz +0 -0
  531. codex/static_root/assets/unauthorized-DHV6Q1n-.css.br +0 -0
  532. codex/static_root/assets/unauthorized-DHV6Q1n-.css.gz +0 -0
  533. codex/static_root/assets/user-tab-BABwfxLO.37dd0440fbdd.js +0 -1
  534. codex/static_root/assets/user-tab-BABwfxLO.37dd0440fbdd.js.br +0 -0
  535. codex/static_root/assets/user-tab-BABwfxLO.37dd0440fbdd.js.gz +0 -0
  536. codex/static_root/assets/user-tab-BABwfxLO.js +0 -1
  537. codex/static_root/assets/user-tab-BABwfxLO.js.br +0 -0
  538. codex/static_root/assets/user-tab-BABwfxLO.js.gz +0 -0
  539. codex/static_root/js/choices-admin.d790df01c20a.json +0 -1
  540. codex/static_root/js/choices-admin.d790df01c20a.json.br +0 -0
  541. codex/static_root/js/choices-admin.d790df01c20a.json.gz +0 -0
  542. codex/static_root/manifest.cbea5663003a.json +0 -629
  543. codex/static_root/manifest.cbea5663003a.json.br +0 -0
  544. codex/static_root/manifest.cbea5663003a.json.gz +0 -0
  545. {codex-1.6.0a9.dist-info → codex-1.6.0a10.dist-info}/LICENSE +0 -0
  546. {codex-1.6.0a9.dist-info → codex-1.6.0a10.dist-info}/WHEEL +0 -0
  547. {codex-1.6.0a9.dist-info → codex-1.6.0a10.dist-info}/entry_points.txt +0 -0
Binary file
Binary file
@@ -1 +1 @@
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/jquery.json-view.min.css": "rest_framework/docs/css/jquery.json-view.min.a2e6beeb6710.css", "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/js/ajax-form.js": "rest_framework/js/ajax-form.4e1cdcb7acab.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/prettify-min.js": "rest_framework/js/prettify-min.709bfcc456c6.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/default.js": "rest_framework/js/default.5b08897dbdc3.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "rest_framework/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/load-ajax-form.js": "rest_framework/js/load-ajax-form.8cdb3a9f3466.js", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "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/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "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.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "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/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "rest_framework/css/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/bootstrap.min.css": "rest_framework/css/bootstrap.min.f17d4516b026.css", "rest_framework/css/prettify.css": "rest_framework/css/prettify.a987f72342ee.css", "rest_framework/css/bootstrap-theme.min.css": "rest_framework/css/bootstrap-theme.min.1d4b05b397c3.css", "rest_framework/css/bootstrap-tweaks.css": "rest_framework/css/bootstrap-tweaks.ee4ee6acf9eb.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.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "img/publisher.svg": "img/publisher.82d378fcd601.svg", "img/logo-32.webp": "img/logo-32.5688944495bf.webp", "img/logo.svg": "img/logo.0f5344a028ca.svg", "img/story-arc.svg": "img/story-arc.ca10014355ef.svg", "img/missing-cover-165.webp": "img/missing-cover-165.0743171f2148.webp", "img/series.svg": "img/series.ec8a889b8f95.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.c58d966aa64e.webp", "img/missing-cover.svg": "img/missing-cover.ddb038cc2c56.svg", "img/folder.svg": "img/folder.f28936a3701d.svg", "img/volume.svg": "img/volume.814e4c79461a.svg", "img/logo-maskable.svg": "img/logo-maskable.8f7de7f1c6a8.svg", "img/imprint.svg": "img/imprint.7c2adebb76d6.svg", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "js/choices.json": "js/choices.a0aaaa6c7ef7.json", "js/choices-admin.json": "js/choices-admin.d790df01c20a.json", "assets/relation-chips-Bsc-gUxE.css": "assets/relation-chips-Bsc-gUxE.98e65384c3c9.css", "assets/group-tab-CBKuS3Iv.css": "assets/group-tab-CBKuS3Iv.7e4746634782.css", "assets/main-CMQwJ9aG.js": "assets/main-CMQwJ9aG.9836fe81c80a.js", "assets/http-error-DKulXuTl.css": "assets/http-error-DKulXuTl.95e42988d5d5.css", "assets/VSelect-ARDhJiQK.css": "assets/VSelect-ARDhJiQK.372c098fb475.css", "assets/flag-tab-BNwbLfrN.css": "assets/flag-tab-BNwbLfrN.b755a99fff7e.css", "assets/VCheckbox-eNspVUje.js": "assets/VCheckbox-eNspVUje.da8282a08876.js", "assets/pagination-toolbar-LTuj5U-G.js": "assets/pagination-toolbar-LTuj5U-G.a295defbcd2f.js", "assets/VTable-CrWkhkiP.js": "assets/VTable-CrWkhkiP.6d530eea0c09.js", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/unauthorized-DHV6Q1n-.css": "assets/unauthorized-DHV6Q1n-.b7847b2872a1.css", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/VSlideGroup-Dk_1upHt.css": "assets/VSlideGroup-Dk_1upHt.2c836070ec75.css", "assets/VTable-DflzroDq.css": "assets/VTable-DflzroDq.160504d82195.css", "assets/settings-drawer-nZ9HvKSZ.css": "assets/settings-drawer-nZ9HvKSZ.01744e131806.css", "assets/main-Ztp855PW.css": "assets/main-Ztp855PW.d46d718fac45.css", "assets/admin-drawer-panel-1pnfvY8O.js": "assets/admin-drawer-panel-1pnfvY8O.5438f252970e.js", "assets/task-tab-DPD53kjv.js": "assets/task-tab-DPD53kjv.e56a35ff1691.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/change-password-dialog-HvIvmmIE.css": "assets/change-password-dialog-HvIvmmIE.73be0c8a8278.css", "assets/pdf-doc-8RVZqILx.js": "assets/pdf-doc-8RVZqILx.2e7166dd26fb.js", "assets/VTextField-CkWbil3K.js": "assets/VTextField-CkWbil3K.2cac13161dfe.js", "assets/settings-drawer-DbN6ISRH.js": "assets/settings-drawer-DbN6ISRH.d14f525d8eee.js", "assets/user-tab-BABwfxLO.js": "assets/user-tab-BABwfxLO.37dd0440fbdd.js", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/VSelectionControl-CVQ9wkE2.js": "assets/VSelectionControl-CVQ9wkE2.c02186cceba6.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/to-case-ehC9Ccyj.js": "assets/to-case-ehC9Ccyj.a7b8e25b391f.js", "assets/datetime-column-9w3GcKvo.js": "assets/datetime-column-9w3GcKvo.f9172256f091.js", "assets/stats-tab-DImNhH8O.js": "assets/stats-tab-DImNhH8O.d5026283841a.js", "assets/stats-tab-TsyG3wH_.css": "assets/stats-tab-TsyG3wH_.b93c080356fc.css", "assets/browser-BuU2x9y7.css": "assets/browser-BuU2x9y7.f67595d24664.css", "assets/reader-DNnK_Chr.js": "assets/reader-DNnK_Chr.114d0e321547.js", "assets/VWindowItem-7z55Y4lK.js": "assets/VWindowItem-7z55Y4lK.98eb7487e039.js", "assets/browser-CO9EYHIr.js": "assets/browser-CO9EYHIr.be49367c6a75.js", "assets/confirm-dialog-jwL7B98r.js": "assets/confirm-dialog-jwL7B98r.1cfd579cbcfe.js", "assets/library-tab-BN0SfPcH.css": "assets/library-tab-BN0SfPcH.913e236f625e.css", "assets/admin-D3OK784R.js": "assets/admin-D3OK784R.f69891726ec5.js", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/group-tab-BONYWOc1.js": "assets/group-tab-BONYWOc1.6ddf321a4a56.js", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/reader-CCCfpM3x.css": "assets/reader-CCCfpM3x.1553e45bd775.css", "assets/change-password-dialog-CjZdzaIk.js": "assets/change-password-dialog-CjZdzaIk.188c765431ab.js", "assets/relation-chips-PYua7aXv.js": "assets/relation-chips-PYua7aXv.428ba0b5861e.js", "assets/VCheckboxBtn-DLzF_WHB.js": "assets/VCheckboxBtn-DLzF_WHB.9a47873b8548.js", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/filter-C-pghOri.js": "assets/filter-C-pghOri.eeb7c2ecf398.js", "assets/admin-drawer-panel-o87BwD38.css": "assets/admin-drawer-panel-o87BwD38.ce39427c8201.css", "assets/VSelect-BoJq222l.js": "assets/VSelect-BoJq222l.fc714657e214.js", "assets/pagination-toolbar-DWdp_kmz.css": "assets/pagination-toolbar-DWdp_kmz.f98f47e87612.css", "assets/flag-tab-Da2DBNyz.js": "assets/flag-tab-Da2DBNyz.ffbe5ca37e1c.js", "assets/admin-B8Bp2Uih.css": "assets/admin-B8Bp2Uih.82c98714bcf1.css", "assets/http-error-D2Jnc20C.js": "assets/http-error-D2Jnc20C.32846bc3a43d.js", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/VDialog-87AymJC5.js": "assets/VDialog-87AymJC5.4a46716358c0.js", "assets/datetime-column-DeCthByU.css": "assets/datetime-column-DeCthByU.1f3bf499e063.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/library-tab-B419agXA.js": "assets/library-tab-B419agXA.d4b778172aaa.js", "assets/VSlideGroup-Ce0j2BKK.js": "assets/VSlideGroup-Ce0j2BKK.85e64443a928.js", "assets/VCombobox-BIO7lU_B.js": "assets/VCombobox-BIO7lU_B.d607ada71b06.js", "assets/VExpansionPanels-CgA3shsd.js": "assets/VExpansionPanels-CgA3shsd.9e524c73726a.js", "assets/VExpansionPanels-DsEXVcCv.css": "assets/VExpansionPanels-DsEXVcCv.20b475255e66.css", "assets/VDialog-C5Nxd_zP.css": "assets/VDialog-C5Nxd_zP.d327f505ef0e.css", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/VTextField-BssVoDhB.css": "assets/VTextField-BssVoDhB.4cc388b4aa3c.css", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/VRadioGroup-B--7K_v5.js": "assets/VRadioGroup-B--7K_v5.4a4e9c2d6c42.js", "assets/unauthorized-BOIx7Y18.js": "assets/unauthorized-BOIx7Y18.ee3961abfccb.js", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.cbea5663003a.json"}, "version": "1.1", "hash": "469437147ea5"}
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/jquery.json-view.min.css": "rest_framework/docs/css/jquery.json-view.min.a2e6beeb6710.css", "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/js/ajax-form.js": "rest_framework/js/ajax-form.4e1cdcb7acab.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/prettify-min.js": "rest_framework/js/prettify-min.709bfcc456c6.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/default.js": "rest_framework/js/default.5b08897dbdc3.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "rest_framework/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/load-ajax-form.js": "rest_framework/js/load-ajax-form.8cdb3a9f3466.js", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "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/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "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.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "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/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "rest_framework/css/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/bootstrap.min.css": "rest_framework/css/bootstrap.min.f17d4516b026.css", "rest_framework/css/prettify.css": "rest_framework/css/prettify.a987f72342ee.css", "rest_framework/css/bootstrap-theme.min.css": "rest_framework/css/bootstrap-theme.min.1d4b05b397c3.css", "rest_framework/css/bootstrap-tweaks.css": "rest_framework/css/bootstrap-tweaks.ee4ee6acf9eb.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.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "img/publisher.svg": "img/publisher.82d378fcd601.svg", "img/logo-32.webp": "img/logo-32.5688944495bf.webp", "img/logo.svg": "img/logo.0f5344a028ca.svg", "img/story-arc.svg": "img/story-arc.ca10014355ef.svg", "img/missing-cover-165.webp": "img/missing-cover-165.0743171f2148.webp", "img/series.svg": "img/series.ec8a889b8f95.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.c58d966aa64e.webp", "img/missing-cover.svg": "img/missing-cover.ddb038cc2c56.svg", "img/folder.svg": "img/folder.f28936a3701d.svg", "img/volume.svg": "img/volume.814e4c79461a.svg", "img/logo-maskable.svg": "img/logo-maskable.8f7de7f1c6a8.svg", "img/imprint.svg": "img/imprint.7c2adebb76d6.svg", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "js/choices.json": "js/choices.a0aaaa6c7ef7.json", "js/choices-admin.json": "js/choices-admin.3521e2a863df.json", "assets/relation-chips-Bsc-gUxE.css": "assets/relation-chips-Bsc-gUxE.98e65384c3c9.css", "assets/group-tab-CBKuS3Iv.css": "assets/group-tab-CBKuS3Iv.7e4746634782.css", "assets/http-error-DKulXuTl.css": "assets/http-error-DKulXuTl.95e42988d5d5.css", "assets/VSelect-ARDhJiQK.css": "assets/VSelect-ARDhJiQK.372c098fb475.css", "assets/flag-tab-BNwbLfrN.css": "assets/flag-tab-BNwbLfrN.b755a99fff7e.css", "assets/VSelect-Dixy6okt.js": "assets/VSelect-Dixy6okt.5d53830daa8a.js", "assets/browser-s6mFzrK9.js": "assets/browser-s6mFzrK9.0d2200b451af.js", "assets/settings-drawer-D_JuRi7F.js": "assets/settings-drawer-D_JuRi7F.f02f3f981f8f.js", "assets/change-password-dialog-Bn20jYzD.js": "assets/change-password-dialog-Bn20jYzD.593c5af1732b.js", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/VSelectionControl-MNmxKc3J.js": "assets/VSelectionControl-MNmxKc3J.08055d00917e.js", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/VSlideGroup-Dk_1upHt.css": "assets/VSlideGroup-Dk_1upHt.2c836070ec75.css", "assets/stats-tab-ClqRTk1z.js": "assets/stats-tab-ClqRTk1z.c759ace65a87.js", "assets/admin-drawer-panel-mne3FIj6.css": "assets/admin-drawer-panel-mne3FIj6.561b3f75fe65.css", "assets/VTable-DflzroDq.css": "assets/VTable-DflzroDq.160504d82195.css", "assets/settings-drawer-nZ9HvKSZ.css": "assets/settings-drawer-nZ9HvKSZ.01744e131806.css", "assets/VDialog-lQ13FnRR.css": "assets/VDialog-lQ13FnRR.1c801ad756b2.css", "assets/relation-chips-C5acBjpy.js": "assets/relation-chips-C5acBjpy.dc67d4528868.js", "assets/main-Ztp855PW.css": "assets/main-Ztp855PW.d46d718fac45.css", "assets/reader-BpsctRsY.css": "assets/reader-BpsctRsY.5d72e393911a.css", "assets/VTable-lcnYg9Ee.js": "assets/VTable-lcnYg9Ee.d72927b13c2e.js", "assets/reader-CDk8oZzB.js": "assets/reader-CDk8oZzB.ad62eebda920.js", "assets/VRadioGroup-QFQbK1qo.js": "assets/VRadioGroup-QFQbK1qo.750a42b1b814.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/unauthorized-BjKuLH6k.js": "assets/unauthorized-BjKuLH6k.2ae00ddd79fb.js", "assets/VWindowItem-C__tAqdc.js": "assets/VWindowItem-C__tAqdc.9791c128c3b7.js", "assets/group-tab-Cz9t_ECi.js": "assets/group-tab-Cz9t_ECi.a9e8aea79254.js", "assets/VTextField-BkFrjhdV.js": "assets/VTextField-BkFrjhdV.b02653a9b3b7.js", "assets/VSlideGroup-DZEV0FoV.js": "assets/VSlideGroup-DZEV0FoV.5f996daf0e98.js", "assets/datetime-column-BSdlLt-4.js": "assets/datetime-column-BSdlLt-4.27ec2df67a0b.js", "assets/change-password-dialog-0u6IJA87.css": "assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css", "assets/VCombobox-aJr--Ou7.js": "assets/VCombobox-aJr--Ou7.f290ccf2ce25.js", "assets/user-tab-Dpxe3ygA.js": "assets/user-tab-Dpxe3ygA.7d90174631f0.js", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/library-tab-DMlnswUU.js": "assets/library-tab-DMlnswUU.30f454e84184.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/main-vjXu_QYL.js": "assets/main-vjXu_QYL.548bd4c38799.js", "assets/pagination-toolbar-DGdMiBRs.css": "assets/pagination-toolbar-DGdMiBRs.5829b01b8a2f.css", "assets/pagination-toolbar-JW78pa0q.js": "assets/pagination-toolbar-JW78pa0q.91024effdab9.js", "assets/flag-tab-8vzpdySX.js": "assets/flag-tab-8vzpdySX.a982c7f0776a.js", "assets/admin-drawer-panel-rrNKi_GE.js": "assets/admin-drawer-panel-rrNKi_GE.e2b034db7934.js", "assets/VDialog-61pzfUB2.js": "assets/VDialog-61pzfUB2.33f73beb5224.js", "assets/confirm-dialog-CWszioQE.js": "assets/confirm-dialog-CWszioQE.859051c35dd9.js", "assets/VCheckbox-CY3rcqlS.js": "assets/VCheckbox-CY3rcqlS.de5154294920.js", "assets/library-tab-BN0SfPcH.css": "assets/library-tab-BN0SfPcH.913e236f625e.css", "assets/VExpansionPanels-rewm0P4z.js": "assets/VExpansionPanels-rewm0P4z.5c7680f815b6.js", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/to-case-CGbULRaE.js": "assets/to-case-CGbULRaE.4c80644f460d.js", "assets/admin-CXES2HXe.js": "assets/admin-CXES2HXe.9e48a9bf84e0.js", "assets/pdf-doc-BiamrjRZ.js": "assets/pdf-doc-BiamrjRZ.4c9be1ade43c.js", "assets/admin-B8Bp2Uih.css": "assets/admin-B8Bp2Uih.82c98714bcf1.css", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/stats-tab-B4yKuY0c.css": "assets/stats-tab-B4yKuY0c.a5728396494b.css", "assets/browser-BuDeXGEe.css": "assets/browser-BuDeXGEe.f60854183b45.css", "assets/datetime-column-DeCthByU.css": "assets/datetime-column-DeCthByU.1f3bf499e063.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/task-tab-DF9qa6LO.js": "assets/task-tab-DF9qa6LO.0b32cafde4ad.js", "assets/http-error-Cqtszzf1.js": "assets/http-error-Cqtszzf1.b31df3d9c29f.js", "assets/VCheckboxBtn-D2tPTt6P.js": "assets/VCheckboxBtn-D2tPTt6P.9a90d6818bf6.js", "assets/VExpansionPanels-DsEXVcCv.css": "assets/VExpansionPanels-DsEXVcCv.20b475255e66.css", "assets/unauthorized-CibJYD8o.css": "assets/unauthorized-CibJYD8o.4c2de98c2b53.css", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/filter-D3gaGf87.js": "assets/filter-D3gaGf87.1f14dbfd9929.js", "assets/VTextField-BssVoDhB.css": "assets/VTextField-BssVoDhB.4cc388b4aa3c.css", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.35e46a3ec8fa.json"}, "version": "1.1", "hash": "3eaef7cc048e"}
@@ -14,8 +14,11 @@ class AdminAPIKey(AdminGenericAPIView):
14
14
  serializer_class = APIKeySerializer
15
15
  input_serializer_class = None
16
16
 
17
- @extend_schema(request=input_serializer_class)
18
- def post(self, *_args, **_kwargs):
17
+ @extend_schema(
18
+ # parameters=[input_serializer_class],
19
+ request=input_serializer_class
20
+ )
21
+ def put(self, *_args, **_kwargs):
19
22
  """Regenerate the API Key."""
20
23
  ts = Timestamp.objects.get(key=Timestamp.TimestampChoices.API_KEY.value)
21
24
  ts.save_uuid_version()
@@ -21,9 +21,18 @@ from codex.permissions import HasAPIKeyOrIsAdminUser
21
21
  from codex.serializers.admin import AdminStatsRequestSerializer, AdminStatsSerializer
22
22
  from codex.version import VERSION
23
23
  from codex.views.admin.auth import AdminGenericAPIView
24
- from codex.views.const import CONFIG_MODELS, GROUP_MODELS, METADATA_MODELS
24
+ from codex.views.const import CONFIG_MODELS, METADATA_MODELS, STATS_GROUP_MODELS
25
25
 
26
26
  LOG = get_logger(__name__)
27
+ _KEY_MODELS_MAP = MappingProxyType(
28
+ {
29
+ "config": CONFIG_MODELS,
30
+ "groups": STATS_GROUP_MODELS,
31
+ "metadata": METADATA_MODELS,
32
+ }
33
+ )
34
+ _DOCKERENV_PATH = Path("/.dockerenv")
35
+ _CGROUP_PATH = Path("/proc/self/cgroup")
27
36
 
28
37
 
29
38
  class AdminStatsView(AdminGenericAPIView):
@@ -33,24 +42,11 @@ class AdminStatsView(AdminGenericAPIView):
33
42
  serializer_class = AdminStatsSerializer
34
43
  input_serializer_class = AdminStatsRequestSerializer
35
44
 
36
- _KEY_MODELS_MAP = MappingProxyType(
37
- {
38
- "config": CONFIG_MODELS,
39
- "groups": GROUP_MODELS,
40
- "metadata": METADATA_MODELS,
41
- }
42
- )
43
- _DOCKERENV_PATH = Path("/.dockerenv")
44
- _CGROUP_PATH = Path("/proc/self/cgroup")
45
-
46
45
  @classmethod
47
46
  def _is_docker(cls):
48
47
  """Test if we're in a docker container."""
49
48
  try:
50
- return (
51
- cls._DOCKERENV_PATH.is_file()
52
- or "docker" in cls._CGROUP_PATH.read_text()
53
- )
49
+ return _DOCKERENV_PATH.is_file() or "docker" in _CGROUP_PATH.read_text()
54
50
  except Exception:
55
51
  return False
56
52
 
@@ -66,7 +62,7 @@ class AdminStatsView(AdminGenericAPIView):
66
62
  def _get_models(self, key):
67
63
  """Get models from request params."""
68
64
  request_model_list = self.request.GET.get(key)
69
- all_models = self._KEY_MODELS_MAP[key]
65
+ all_models = _KEY_MODELS_MAP[key]
70
66
  if request_model_list:
71
67
  models = []
72
68
  for model_name in request_model_list.split(","):
@@ -176,10 +172,7 @@ class AdminStatsView(AdminGenericAPIView):
176
172
  self._get_metadata(obj)
177
173
  return obj
178
174
 
179
- @extend_schema(
180
- parameters=[input_serializer_class],
181
- request=input_serializer_class,
182
- )
175
+ @extend_schema(parameters=[input_serializer_class])
183
176
  def get(self, *_args, **_kwargs):
184
177
  """Get the stats object and serialize it."""
185
178
  input_serializer = self.input_serializer_class(data=self.request.GET)
@@ -13,7 +13,7 @@ from codex.librarian.covers.tasks import (
13
13
  )
14
14
  from codex.librarian.importer.tasks import (
15
15
  AdoptOrphanFoldersTask,
16
- UpdateGroupsFirstComic,
16
+ UpdateGroupsTask,
17
17
  )
18
18
  from codex.librarian.janitor.tasks import (
19
19
  ForceUpdateAllFailedImportsTask,
@@ -102,8 +102,7 @@ class AdminLibrarianTaskView(AdminAPIView):
102
102
  "poll": WatchdogPollLibrariesTask(frozenset(), False),
103
103
  "poll_force": WatchdogPollLibrariesTask(frozenset(), True),
104
104
  "janitor_nightly": JanitorNightlyTask(),
105
- "update_first_covers": UpdateGroupsFirstComic(),
106
- "force_update_first_covers": UpdateGroupsFirstComic(start_time=EPOCH_START),
105
+ "force_update_groups": UpdateGroupsTask(start_time=EPOCH_START),
107
106
  "adopt_folders": AdoptOrphanFoldersTask(),
108
107
  }
109
108
  )
codex/views/auth.py CHANGED
@@ -52,7 +52,7 @@ class TimezoneView(AuthGenericAPIView):
52
52
  serializer_class = OKSerializer
53
53
 
54
54
  @extend_schema(request=input_serializer_class)
55
- def post(self, request, *args, **kwargs):
55
+ def put(self, request, *args, **kwargs):
56
56
  """Get the user info for the current user."""
57
57
  data = self.request.data # type: ignore
58
58
  serializer = self.input_serializer_class(data=data)
codex/views/bookmark.py CHANGED
@@ -5,6 +5,8 @@ from django.db.models.functions import Now
5
5
  from drf_spectacular.utils import extend_schema
6
6
  from rest_framework.response import Response
7
7
 
8
+ from codex.librarian.mp_queue import LIBRARIAN_QUEUE
9
+ from codex.librarian.notifier.tasks import NotifierTask
8
10
  from codex.logger.logging import get_logger
9
11
  from codex.models import Bookmark, Comic
10
12
  from codex.serializers.models.bookmark import (
@@ -14,7 +16,7 @@ from codex.serializers.models.bookmark import (
14
16
  from codex.views.auth import (
15
17
  AuthFilterGenericAPIView,
16
18
  )
17
- from codex.views.const import GROUP_RELATION
19
+ from codex.views.const import FOLDER_GROUP, GROUP_RELATION
18
20
 
19
21
  LOG = get_logger(__name__)
20
22
  VERTICAL_READING_DIRECTIONS = frozenset({"ttb", "btt"})
@@ -47,7 +49,7 @@ class BookmarkBaseView(AuthFilterGenericAPIView):
47
49
  if not self.request.session or not self.request.session.session_key:
48
50
  LOG.debug("no session, make one")
49
51
  self.request.session.save()
50
- search_kwargs["session__session_key"] = self.request.session.session_key
52
+ search_kwargs["session_id"] = self.request.session.session_key
51
53
  return search_kwargs
52
54
 
53
55
  @staticmethod
@@ -74,8 +76,20 @@ class BookmarkBaseView(AuthFilterGenericAPIView):
74
76
  ):
75
77
  updates["two_pages"] = None
76
78
 
79
+ def notify_library_changed(self):
80
+ """Notify one user that their library changed."""
81
+ if user := self.request.user:
82
+ uid = user.id # type: ignore
83
+ else:
84
+ uid = self.request.session.session_key
85
+ group = f"user_{uid}"
86
+ task = NotifierTask("LIBRARY_CHANGED", group)
87
+ LIBRARIAN_QUEUE.put(task)
88
+
77
89
  def _update_bookmarks(self, search_kwargs, updates):
78
90
  """Update existing bookmarks."""
91
+ if not updates:
92
+ return 0
79
93
  group_acl_filter = self.get_group_acl_filter(Bookmark)
80
94
  update_fields = set(updates.keys()) & _BOOKMARK_UPDATE_FIELDS
81
95
  update_fields.add("updated_at")
@@ -87,7 +101,6 @@ class BookmarkBaseView(AuthFilterGenericAPIView):
87
101
  existing_bookmarks = existing_bookmarks.annotate(
88
102
  page_count=F("comic__page_count")
89
103
  )
90
- # only_fields = (*only_fields, "page_count")
91
104
  existing_bookmarks = existing_bookmarks.only(*only_fields)
92
105
  update_bookmarks = []
93
106
  for bm in existing_bookmarks:
@@ -100,7 +113,8 @@ class BookmarkBaseView(AuthFilterGenericAPIView):
100
113
  count = len(update_bookmarks)
101
114
  if count:
102
115
  Bookmark.objects.bulk_update(update_bookmarks, tuple(update_fields))
103
- LOG.debug(f"Updated {count} bookmarks.")
116
+ return count
117
+ # LOG.debug(f"Updated {count} bookmarks.")
104
118
 
105
119
  @staticmethod
106
120
  def _create_bookmarks_validate_two_pages(updates):
@@ -115,17 +129,12 @@ class BookmarkBaseView(AuthFilterGenericAPIView):
115
129
  """Create new bookmarks for comics that don't exist yet."""
116
130
  self._create_bookmarks_validate_two_pages(updates)
117
131
  if not updates:
118
- return
132
+ return 0
119
133
  create_bookmarks = []
120
134
  group_acl_filter = self.get_group_acl_filter(Comic)
135
+ exclude = {}
121
136
  for key, value in search_kwargs.items():
122
- exclude = {"bookmark__" + key: value}
123
- break
124
- else:
125
- reason = (
126
- f"No user or session_id found for creating bookmarks: {search_kwargs}"
127
- )
128
- raise ValueError(reason)
137
+ exclude["bookmark__" + key] = value
129
138
  create_bookmark_comics = (
130
139
  Comic.objects.filter(group_acl_filter)
131
140
  .filter(**comic_filter)
@@ -152,13 +161,16 @@ class BookmarkBaseView(AuthFilterGenericAPIView):
152
161
  update_fields=tuple(_BOOKMARK_UPDATE_FIELDS),
153
162
  unique_fields=Bookmark._meta.unique_together[0], # type: ignore
154
163
  )
155
- LOG.debug(f"Create {count} bookmarks.")
164
+ # LOG.debug(f"Create {count} bookmarks.")
165
+ return count
156
166
 
157
167
  def update_bookmarks(self, updates, comic_filter):
158
168
  """Update a user bookmark."""
159
169
  search_kwargs = self.get_bookmark_search_kwargs(comic_filter)
160
- self._update_bookmarks(search_kwargs, updates)
161
- self._create_bookmarks(comic_filter, search_kwargs, updates)
170
+ count = self._update_bookmarks(search_kwargs, updates)
171
+ count += self._create_bookmarks(comic_filter, search_kwargs, updates)
172
+ if count and "finished" in updates:
173
+ self.notify_library_changed()
162
174
 
163
175
 
164
176
  class BookmarkView(BookmarkBaseView):
@@ -187,7 +199,9 @@ class BookmarkView(BookmarkBaseView):
187
199
 
188
200
  pks = self.kwargs.get("pks")
189
201
 
190
- relation = "folders__in" if group == "f" else GROUP_RELATION[group] + "__in"
202
+ relation = (
203
+ "folders__in" if group == FOLDER_GROUP else GROUP_RELATION[group] + "__in"
204
+ )
191
205
  comic_filter = {relation: pks}
192
206
 
193
207
  self.update_bookmarks(updates, comic_filter=comic_filter)
@@ -187,6 +187,8 @@ class BrowserAnnotationsView(BrowserOrderByView, SharedAnnotationsMixin):
187
187
  def _annotate_order_value(self, qs, model):
188
188
  """Annotate a main key for sorting and browser card display."""
189
189
  # Determine order func
190
+ if self.TARGET == "metadata":
191
+ return qs
190
192
  if model == Folder and self.order_key == "filename":
191
193
  order_value = F("name")
192
194
  elif model == Comic or self.order_key in _ANNOTATED_ORDER_FIELDS:
@@ -14,7 +14,7 @@ from codex.models import (
14
14
  )
15
15
  from codex.serializers.browser.settings import BrowserSettingsSerializer
16
16
  from codex.views.browser.filters.search import SearchFilterView
17
- from codex.views.const import GROUP_MODEL_MAP, ROOT_GROUP
17
+ from codex.views.const import FOLDER_GROUP, GROUP_MODEL_MAP, ROOT_GROUP, STORY_ARC_GROUP
18
18
  from codex.views.util import reparse_json_query_params
19
19
 
20
20
  LOG = get_logger(__name__)
@@ -29,9 +29,7 @@ class BrowserBaseView(SearchFilterView):
29
29
  input_serializer_class = BrowserSettingsSerializer
30
30
 
31
31
  ADMIN_FLAG_VALUE_KEY_MAP = MappingProxyType({})
32
- REPARSE_JSON_FIELDS = frozenset({"filters", "show"})
33
-
34
- _GET_JSON_KEYS = frozenset({"filters", "show"})
32
+ REPARSE_JSON_FIELDS = frozenset({"breadcrumbs", "filters", "show"})
35
33
 
36
34
  def __init__(self, *args, **kwargs):
37
35
  """Set params for the type checker."""
@@ -87,9 +85,27 @@ class BrowserBaseView(SearchFilterView):
87
85
  data = self._parse_query_params()
88
86
  serializer = self.input_serializer_class(data=data)
89
87
  serializer.is_valid(raise_exception=True)
90
- self.load_params_from_session(serializer.validated_data)
88
+
89
+ params: dict[str, Any] = {}
90
+ defaults = self.SESSION_DEFAULTS[self.SESSION_KEY]
91
+ params.update(defaults)
92
+ group = self.kwargs.get("group")
93
+ if group:
94
+ # order_by has a dynamic group based default
95
+ order_defaults = {
96
+ "order_by": "filename"
97
+ if group == FOLDER_GROUP
98
+ else "story_arc_number"
99
+ if group == STORY_ARC_GROUP
100
+ else "sort_name"
101
+ }
102
+ params.update(order_defaults)
103
+ validated_data = serializer.validated_data
104
+
105
+ if validated_data:
106
+ params.update(validated_data) # type: ignore
107
+ self.params = MappingProxyType(params)
91
108
  self.is_bookmark_filtered = bool(self.params.get("filters", {}).get("bookmark"))
92
- return serializer.validated_data
93
109
 
94
110
  def set_order_key(self):
95
111
  """Unused until browser."""
@@ -18,10 +18,10 @@ class BrowserBreadcrumbsView(BrowserPaginateView):
18
18
  """Load breadcrumbs and determine if they should be searched for a graft."""
19
19
  breadcrumbs: list[Route] = list(self.params.get("breadcrumbs", []))
20
20
  old_breadcrumbs = [Route(**crumb) for crumb in breadcrumbs]
21
- changed = bool(old_breadcrumbs) and old_breadcrumbs[-1].group in valid_groups
22
- if changed:
21
+ invalid = not old_breadcrumbs or old_breadcrumbs[-1].group not in valid_groups
22
+ if invalid:
23
23
  old_breadcrumbs = []
24
- return old_breadcrumbs, changed
24
+ return old_breadcrumbs, invalid
25
25
 
26
26
  def _breadcrumbs_save(self, breadcrumbs):
27
27
  """Save the breadcrumbs to params."""
@@ -184,7 +184,7 @@ class BrowserBreadcrumbsView(BrowserPaginateView):
184
184
 
185
185
  return tuple(new_breadcrumbs), changed
186
186
 
187
- def get_parent_breadcrumbs(
187
+ def get_breadcrumbs(
188
188
  self,
189
189
  ) -> tuple[Route, ...]:
190
190
  """Graft or create breadcrumbs by browser mode."""
@@ -199,4 +199,4 @@ class BrowserBreadcrumbsView(BrowserPaginateView):
199
199
  if changed:
200
200
  self._breadcrumbs_save(breadcrumbs)
201
201
 
202
- return breadcrumbs[:-1] if breadcrumbs else ()
202
+ return breadcrumbs
@@ -16,9 +16,6 @@ from codex.models import (
16
16
  Folder,
17
17
  Imprint,
18
18
  Library,
19
- Publisher,
20
- Series,
21
- StoryArc,
22
19
  Volume,
23
20
  )
24
21
  from codex.serializers.browser.page import BrowserPageSerializer
@@ -34,6 +31,15 @@ if TYPE_CHECKING:
34
31
 
35
32
 
36
33
  LOG = get_logger(__name__)
34
+ _GROUP_INSTANCE_SELECT_RELATED: MappingProxyType[
35
+ type[BrowserGroupModel], tuple[str | None, ...]
36
+ ] = MappingProxyType(
37
+ {
38
+ Comic: ("series", "volume"),
39
+ Volume: ("series",),
40
+ Imprint: ("publisher",),
41
+ }
42
+ )
37
43
 
38
44
 
39
45
  class BrowserView(BrowserTitleView):
@@ -48,19 +54,6 @@ class BrowserView(BrowserTitleView):
48
54
  }
49
55
  )
50
56
  TARGET = "browser"
51
- _GROUP_INSTANCE_SELECT_RELATED: MappingProxyType[
52
- type[BrowserGroupModel], tuple[str | None, ...]
53
- ] = MappingProxyType(
54
- {
55
- Comic: ("series", "volume"),
56
- Volume: ("series",),
57
- Series: (None,),
58
- Imprint: ("publisher",),
59
- Publisher: (None,),
60
- Folder: ("parent_folder",),
61
- StoryArc: (None,),
62
- }
63
- )
64
57
 
65
58
  def __init__(self, *args, **kwargs):
66
59
  """Set params for the type checker."""
@@ -75,7 +68,7 @@ class BrowserView(BrowserTitleView):
75
68
  if pks and self.group_class:
76
69
  try:
77
70
  select_related: tuple[str | None, ...] = (
78
- self._GROUP_INSTANCE_SELECT_RELATED[self.group_class]
71
+ _GROUP_INSTANCE_SELECT_RELATED.get(self.group_class, (None,))
79
72
  )
80
73
  self.group_query = self.group_class.objects.select_related(
81
74
  *select_related
@@ -162,7 +155,7 @@ class BrowserView(BrowserTitleView):
162
155
  return self.group_instance.updated_at
163
156
 
164
157
  group_model = self.group_class if self.group_class else self.model
165
- return self.get_group_mtime(group_model)
158
+ return self.get_group_mtime(group_model, page_mtime=True)
166
159
 
167
160
  @staticmethod
168
161
  def _get_zero_pad(book_qs):
@@ -205,7 +198,7 @@ class BrowserView(BrowserTitleView):
205
198
  )
206
199
 
207
200
  # get additional context
208
- parent_breadcrumbs = self.get_parent_breadcrumbs()
201
+ breadcrumbs = self.get_breadcrumbs()
209
202
  title = self.get_browser_page_title()
210
203
  # needs to happen after pagination
211
204
  # runs obj list query twice :/
@@ -214,7 +207,7 @@ class BrowserView(BrowserTitleView):
214
207
  # construct final data structure
215
208
  return MappingProxyType(
216
209
  {
217
- "breadcrumbs": parent_breadcrumbs,
210
+ "breadcrumbs": breadcrumbs,
218
211
  "title": title,
219
212
  "model_group": self.model_group,
220
213
  "groups": group_qs,
@@ -228,11 +221,10 @@ class BrowserView(BrowserTitleView):
228
221
  }
229
222
  )
230
223
 
231
- @extend_schema(request=BrowserTitleView.input_serializer_class)
224
+ @extend_schema(parameters=[BrowserTitleView.input_serializer_class])
232
225
  def get(self, *_args, **_kwargs):
233
226
  """Get browser settings."""
234
227
  self.init_request()
235
228
  data = self.get_object()
236
229
  serializer = self.get_serializer(data)
237
- self.save_params_to_session(self.params)
238
230
  return Response(serializer.data)
@@ -15,11 +15,13 @@ from codex.models import (
15
15
  StoryArc,
16
16
  )
17
17
  from codex.models.named import IdentifierType
18
- from codex.serializers.browser.choices import CHOICES_SERIALIZER_CLASS_MAP
18
+ from codex.serializers.browser.choices import (
19
+ BrowserChoicesFilterSerializer,
20
+ )
19
21
  from codex.serializers.browser.filters import (
20
22
  BrowserFilterChoicesSerializer,
21
- CharListField,
22
23
  )
24
+ from codex.serializers.browser.settings import BrowserFilterChoicesInputSerilalizer
23
25
  from codex.serializers.models.pycountry import PyCountrySerializer
24
26
  from codex.views.browser.filters.annotations import (
25
27
  BrowserAnnotationsFilterView,
@@ -56,9 +58,15 @@ _NULL_NAMED_ROW = MappingProxyType({"pk": -1, "name": "_none_"})
56
58
  class BrowserChoicesViewBase(BrowserAnnotationsFilterView):
57
59
  """Get choices for filter dialog."""
58
60
 
59
- SERIALIZER_MANY = False
61
+ input_serializer_class = BrowserFilterChoicesInputSerilalizer
60
62
  TARGET = "choices"
61
63
 
64
+ def init_request(self):
65
+ """Initialieze request."""
66
+ self.parse_params()
67
+ self.set_model()
68
+ self.set_rel_prefix()
69
+
62
70
  @staticmethod
63
71
  def get_field_choices_query(comic_qs, field_name):
64
72
  """Get distinct values for the field."""
@@ -97,12 +105,12 @@ class BrowserChoicesViewBase(BrowserAnnotationsFilterView):
97
105
  """Get the comic subquery use for the choices."""
98
106
  return self.get_filtered_queryset(Comic)
99
107
 
100
- @extend_schema(request=BrowserAnnotationsFilterView.input_serializer_class)
108
+ @extend_schema(parameters=[input_serializer_class])
101
109
  def get(self, *_args, **_kwargs):
102
110
  """Return choices."""
103
111
  self.init_request()
104
112
  obj = self.get_object()
105
- serializer = self.get_serializer(obj, many=self.SERIALIZER_MANY)
113
+ serializer = self.get_serializer(obj)
106
114
  return Response(serializer.data)
107
115
 
108
116
 
@@ -160,10 +168,7 @@ class BrowserChoicesAvailableView(BrowserChoicesViewBase):
160
168
  class BrowserChoicesView(BrowserChoicesViewBase):
161
169
  """Get choices for filter dialog."""
162
170
 
163
- # serializer_class = Dynamic class determined in get()
164
- SERIALIZER_MANY = True
165
- # HACK get_serializer(data, many=True) requires this to be set for the debug API view
166
- queryset = Comic.objects.none()
171
+ serializer_class = BrowserChoicesFilterSerializer
167
172
 
168
173
  def _get_field_choices(self, comic_qs, field_name):
169
174
  """Create a pk:name object for fields without tables."""
@@ -202,11 +207,6 @@ class BrowserChoicesView(BrowserChoicesViewBase):
202
207
  field_name = self.kwargs.get("field_name", "")
203
208
  return snakecase(field_name)
204
209
 
205
- def get_serializer_class(self): # type: ignore
206
- """Dynamic serializer class."""
207
- field_name = self._get_field_name()
208
- return CHOICES_SERIALIZER_CLASS_MAP.get(field_name, CharListField)
209
-
210
210
  def get_object(self):
211
211
  """Return choices with more than one choice."""
212
212
  qs = super().get_object()
@@ -217,4 +217,7 @@ class BrowserChoicesView(BrowserChoicesViewBase):
217
217
  choices = self._get_m2m_field_choices(m2m_model, qs, rel)
218
218
  else:
219
219
  choices = self._get_field_choices(qs, rel)
220
- return choices
220
+ return {
221
+ "field_name": field_name,
222
+ "choices": choices,
223
+ }