codex 1.7.0a2__py3-none-any.whl → 1.7.2__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 (574) hide show
  1. codex/choices.py +2 -17
  2. codex/db.py +1 -2
  3. codex/librarian/bookmark/bookmarkd.py +1 -1
  4. codex/librarian/bookmark/update.py +14 -1
  5. codex/librarian/janitor/integrity.py +11 -10
  6. codex/librarian/janitor/tasks.py +1 -1
  7. codex/serializers/browser/choices.py +9 -11
  8. codex/serializers/browser/metadata.py +1 -1
  9. codex/serializers/browser/page.py +1 -0
  10. codex/static_root/assets/VCheckbox-DLMzIII1.1ff8fc2d9a21.js +1 -0
  11. codex/static_root/assets/VCheckbox-DLMzIII1.1ff8fc2d9a21.js.br +0 -0
  12. codex/static_root/assets/VCheckbox-DLMzIII1.1ff8fc2d9a21.js.gz +0 -0
  13. codex/static_root/assets/VCheckbox-DLMzIII1.js +1 -0
  14. codex/static_root/assets/VCheckbox-DLMzIII1.js.br +0 -0
  15. codex/static_root/assets/VCheckbox-DLMzIII1.js.gz +0 -0
  16. codex/static_root/assets/{VCheckboxBtn-DnBH3a96.876fda35b85a.js → VCheckboxBtn-BzoQl8XC.094679a3624b.js} +1 -1
  17. codex/static_root/assets/VCheckboxBtn-BzoQl8XC.094679a3624b.js.br +0 -0
  18. codex/static_root/assets/VCheckboxBtn-BzoQl8XC.094679a3624b.js.gz +0 -0
  19. codex/static_root/assets/{VCheckboxBtn-DnBH3a96.js → VCheckboxBtn-BzoQl8XC.js} +1 -1
  20. codex/static_root/assets/VCheckboxBtn-BzoQl8XC.js.br +0 -0
  21. codex/static_root/assets/VCheckboxBtn-BzoQl8XC.js.gz +0 -0
  22. codex/static_root/assets/VCombobox-CBY8K5CP.fcf2221a9edd.js +1 -0
  23. codex/static_root/assets/VCombobox-CBY8K5CP.fcf2221a9edd.js.br +0 -0
  24. codex/static_root/assets/VCombobox-CBY8K5CP.fcf2221a9edd.js.gz +0 -0
  25. codex/static_root/assets/VCombobox-CBY8K5CP.js +1 -0
  26. codex/static_root/assets/VCombobox-CBY8K5CP.js.br +0 -0
  27. codex/static_root/assets/VCombobox-CBY8K5CP.js.gz +0 -0
  28. codex/static_root/assets/VDialog-DXQz0Ylp.7b23d86dbd0d.css +1 -0
  29. codex/static_root/assets/VDialog-DXQz0Ylp.7b23d86dbd0d.css.br +0 -0
  30. codex/static_root/assets/VDialog-DXQz0Ylp.7b23d86dbd0d.css.gz +0 -0
  31. codex/static_root/assets/VDialog-DXQz0Ylp.css +1 -0
  32. codex/static_root/assets/VDialog-DXQz0Ylp.css.br +0 -0
  33. codex/static_root/assets/VDialog-DXQz0Ylp.css.gz +0 -0
  34. codex/static_root/assets/VDialog-Db4tJYqR.e21a79a5030e.js +1 -0
  35. codex/static_root/assets/VDialog-Db4tJYqR.e21a79a5030e.js.br +0 -0
  36. codex/static_root/assets/VDialog-Db4tJYqR.e21a79a5030e.js.gz +0 -0
  37. codex/static_root/assets/VDialog-Db4tJYqR.js +1 -0
  38. codex/static_root/assets/VDialog-Db4tJYqR.js.br +0 -0
  39. codex/static_root/assets/VDialog-Db4tJYqR.js.gz +0 -0
  40. codex/static_root/assets/{VExpansionPanels-CBPnoy7O.212f4cad7d78.js → VExpansionPanels-DN4yGbOt.163e59e38865.js} +1 -1
  41. codex/static_root/assets/VExpansionPanels-DN4yGbOt.163e59e38865.js.br +0 -0
  42. codex/static_root/assets/VExpansionPanels-DN4yGbOt.163e59e38865.js.gz +0 -0
  43. codex/static_root/assets/{VExpansionPanels-CBPnoy7O.js → VExpansionPanels-DN4yGbOt.js} +1 -1
  44. codex/static_root/assets/VExpansionPanels-DN4yGbOt.js.br +0 -0
  45. codex/static_root/assets/VExpansionPanels-DN4yGbOt.js.gz +0 -0
  46. codex/static_root/assets/{VRadioGroup-C7Zu_Eup.b42735892aec.js → VRadioGroup-D2-PWEfs.ce7644863c25.js} +1 -1
  47. codex/static_root/assets/VRadioGroup-D2-PWEfs.ce7644863c25.js.br +0 -0
  48. codex/static_root/assets/VRadioGroup-D2-PWEfs.ce7644863c25.js.gz +0 -0
  49. codex/static_root/assets/{VRadioGroup-C7Zu_Eup.js → VRadioGroup-D2-PWEfs.js} +1 -1
  50. codex/static_root/assets/VRadioGroup-D2-PWEfs.js.br +0 -0
  51. codex/static_root/assets/VRadioGroup-D2-PWEfs.js.gz +0 -0
  52. codex/static_root/assets/VSelect-DqXJ23Pc.a1360cbed050.js +1 -0
  53. codex/static_root/assets/VSelect-DqXJ23Pc.a1360cbed050.js.br +0 -0
  54. codex/static_root/assets/VSelect-DqXJ23Pc.a1360cbed050.js.gz +0 -0
  55. codex/static_root/assets/VSelect-DqXJ23Pc.js +1 -0
  56. codex/static_root/assets/VSelect-DqXJ23Pc.js.br +0 -0
  57. codex/static_root/assets/VSelect-DqXJ23Pc.js.gz +0 -0
  58. codex/static_root/assets/{VSelectionControl-B42mmzLA.bf64d259ddef.js → VSelectionControl-CxhDNufT.dd7ca99567fc.js} +1 -1
  59. codex/static_root/assets/VSelectionControl-CxhDNufT.dd7ca99567fc.js.br +0 -0
  60. codex/static_root/assets/VSelectionControl-CxhDNufT.dd7ca99567fc.js.gz +0 -0
  61. codex/static_root/assets/{VSelectionControl-B42mmzLA.js → VSelectionControl-CxhDNufT.js} +1 -1
  62. codex/static_root/assets/VSelectionControl-CxhDNufT.js.br +0 -0
  63. codex/static_root/assets/VSelectionControl-CxhDNufT.js.gz +0 -0
  64. codex/static_root/assets/{VSlideGroup-BtfHoWCn.33e2bd94e34a.js → VSlideGroup-DRbthp6q.7365c5542d47.js} +1 -1
  65. codex/static_root/assets/VSlideGroup-DRbthp6q.7365c5542d47.js.br +0 -0
  66. codex/static_root/assets/VSlideGroup-DRbthp6q.7365c5542d47.js.gz +0 -0
  67. codex/static_root/assets/{VSlideGroup-BtfHoWCn.js → VSlideGroup-DRbthp6q.js} +1 -1
  68. codex/static_root/assets/VSlideGroup-DRbthp6q.js.br +0 -0
  69. codex/static_root/assets/VSlideGroup-DRbthp6q.js.gz +0 -0
  70. codex/static_root/assets/{VTable-R3X0iPjV.ee07d9c2ca5f.js → VTable-Cbq-yJos.c884706cac21.js} +1 -1
  71. codex/static_root/assets/VTable-Cbq-yJos.c884706cac21.js.br +0 -0
  72. codex/static_root/assets/VTable-Cbq-yJos.c884706cac21.js.gz +0 -0
  73. codex/static_root/assets/{VTable-R3X0iPjV.js → VTable-Cbq-yJos.js} +1 -1
  74. codex/static_root/assets/VTable-Cbq-yJos.js.br +0 -0
  75. codex/static_root/assets/VTable-Cbq-yJos.js.gz +0 -0
  76. codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css +1 -0
  77. codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css.br +0 -0
  78. codex/static_root/assets/VTextField-Crc3gdNh.39995ccf4d52.css.gz +0 -0
  79. codex/static_root/assets/VTextField-Crc3gdNh.css +1 -0
  80. codex/static_root/assets/VTextField-Crc3gdNh.css.br +0 -0
  81. codex/static_root/assets/VTextField-Crc3gdNh.css.gz +0 -0
  82. codex/static_root/assets/VTextField-X5yAw35c.155e276dd747.js +1 -0
  83. codex/static_root/assets/VTextField-X5yAw35c.155e276dd747.js.br +0 -0
  84. codex/static_root/assets/VTextField-X5yAw35c.155e276dd747.js.gz +0 -0
  85. codex/static_root/assets/VTextField-X5yAw35c.js +1 -0
  86. codex/static_root/assets/VTextField-X5yAw35c.js.br +0 -0
  87. codex/static_root/assets/VTextField-X5yAw35c.js.gz +0 -0
  88. codex/static_root/assets/{VWindowItem-DHTDdYfK.f6bf6b893442.js → VWindowItem-CRqhVh-9.cd73d01e0591.js} +1 -1
  89. codex/static_root/assets/VWindowItem-CRqhVh-9.cd73d01e0591.js.br +0 -0
  90. codex/static_root/assets/VWindowItem-CRqhVh-9.cd73d01e0591.js.gz +0 -0
  91. codex/static_root/assets/{VWindowItem-DHTDdYfK.js → VWindowItem-CRqhVh-9.js} +1 -1
  92. codex/static_root/assets/VWindowItem-CRqhVh-9.js.br +0 -0
  93. codex/static_root/assets/VWindowItem-CRqhVh-9.js.gz +0 -0
  94. codex/static_root/assets/{admin-CIWyRJnH.dde0ee029f08.js → admin-BFvQwinN.6cfff21f780a.js} +1 -1
  95. codex/static_root/assets/admin-BFvQwinN.6cfff21f780a.js.br +0 -0
  96. codex/static_root/assets/admin-BFvQwinN.6cfff21f780a.js.gz +0 -0
  97. codex/static_root/assets/{admin-CIWyRJnH.js → admin-BFvQwinN.js} +1 -1
  98. codex/static_root/assets/admin-BFvQwinN.js.br +0 -0
  99. codex/static_root/assets/admin-BFvQwinN.js.gz +0 -0
  100. codex/static_root/assets/admin-menu-Jfmp_Yd8.39fa7a18b3b4.js +1 -0
  101. codex/static_root/assets/admin-menu-Jfmp_Yd8.39fa7a18b3b4.js.br +0 -0
  102. codex/static_root/assets/admin-menu-Jfmp_Yd8.39fa7a18b3b4.js.gz +0 -0
  103. codex/static_root/assets/admin-menu-Jfmp_Yd8.js +1 -0
  104. codex/static_root/assets/admin-menu-Jfmp_Yd8.js.br +0 -0
  105. codex/static_root/assets/admin-menu-Jfmp_Yd8.js.gz +0 -0
  106. codex/static_root/assets/{admin-settings-button-progress-DHIl0C8k.85a213c96423.js → admin-settings-button-progress-BAk-B1sR.cbf73c71330d.js} +1 -1
  107. codex/static_root/assets/admin-settings-button-progress-BAk-B1sR.cbf73c71330d.js.br +0 -0
  108. codex/static_root/assets/admin-settings-button-progress-BAk-B1sR.cbf73c71330d.js.gz +0 -0
  109. codex/static_root/assets/{admin-settings-button-progress-DHIl0C8k.js → admin-settings-button-progress-BAk-B1sR.js} +1 -1
  110. codex/static_root/assets/admin-settings-button-progress-BAk-B1sR.js.br +0 -0
  111. codex/static_root/assets/admin-settings-button-progress-BAk-B1sR.js.gz +0 -0
  112. codex/static_root/assets/browser-CctlSJji.css +1 -0
  113. codex/static_root/assets/browser-CctlSJji.css.br +0 -0
  114. codex/static_root/assets/browser-CctlSJji.css.gz +0 -0
  115. codex/static_root/assets/browser-CctlSJji.d42d796476d2.css +1 -0
  116. codex/static_root/assets/browser-CctlSJji.d42d796476d2.css.br +0 -0
  117. codex/static_root/assets/browser-CctlSJji.d42d796476d2.css.gz +0 -0
  118. codex/static_root/assets/browser-DJnEeVHz.a78c47516b08.js +1 -0
  119. codex/static_root/assets/browser-DJnEeVHz.a78c47516b08.js.br +0 -0
  120. codex/static_root/assets/browser-DJnEeVHz.a78c47516b08.js.gz +0 -0
  121. codex/static_root/assets/browser-DJnEeVHz.js +1 -0
  122. codex/static_root/assets/browser-DJnEeVHz.js.br +0 -0
  123. codex/static_root/assets/browser-DJnEeVHz.js.gz +0 -0
  124. codex/static_root/assets/change-password-dialog-C_EOKOn9.a30e68c6e303.css +1 -0
  125. codex/static_root/assets/change-password-dialog-C_EOKOn9.a30e68c6e303.css.br +0 -0
  126. codex/static_root/assets/change-password-dialog-C_EOKOn9.a30e68c6e303.css.gz +0 -0
  127. codex/static_root/assets/change-password-dialog-C_EOKOn9.css +1 -0
  128. codex/static_root/assets/change-password-dialog-C_EOKOn9.css.br +0 -0
  129. codex/static_root/assets/change-password-dialog-C_EOKOn9.css.gz +0 -0
  130. codex/static_root/assets/change-password-dialog-DJtOQw7K.be7fa5ec653d.js +1 -0
  131. codex/static_root/assets/change-password-dialog-DJtOQw7K.be7fa5ec653d.js.br +0 -0
  132. codex/static_root/assets/change-password-dialog-DJtOQw7K.be7fa5ec653d.js.gz +0 -0
  133. codex/static_root/assets/change-password-dialog-DJtOQw7K.js +1 -0
  134. codex/static_root/assets/change-password-dialog-DJtOQw7K.js.br +0 -0
  135. codex/static_root/assets/change-password-dialog-DJtOQw7K.js.gz +0 -0
  136. codex/static_root/assets/confirm-dialog-54rblwf7.9b5915b112c0.css +1 -0
  137. codex/static_root/assets/confirm-dialog-54rblwf7.9b5915b112c0.css.br +0 -0
  138. codex/static_root/assets/confirm-dialog-54rblwf7.css +1 -0
  139. codex/static_root/assets/confirm-dialog-54rblwf7.css.br +0 -0
  140. codex/static_root/assets/confirm-dialog-CME4gKSZ.1606233e784c.js +1 -0
  141. codex/static_root/assets/confirm-dialog-CME4gKSZ.1606233e784c.js.br +0 -0
  142. codex/static_root/assets/confirm-dialog-CME4gKSZ.1606233e784c.js.gz +0 -0
  143. codex/static_root/assets/confirm-dialog-CME4gKSZ.js +1 -0
  144. codex/static_root/assets/confirm-dialog-CME4gKSZ.js.br +0 -0
  145. codex/static_root/assets/confirm-dialog-CME4gKSZ.js.gz +0 -0
  146. codex/static_root/assets/{datetime-column-Dnxh9sRh.b6a92a6bcce9.js → datetime-column-D_F30OLW.09cdce0ef96e.js} +1 -1
  147. codex/static_root/assets/datetime-column-D_F30OLW.09cdce0ef96e.js.br +2 -0
  148. codex/static_root/assets/datetime-column-D_F30OLW.09cdce0ef96e.js.gz +0 -0
  149. codex/static_root/assets/{datetime-column-Dnxh9sRh.js → datetime-column-D_F30OLW.js} +1 -1
  150. codex/static_root/assets/datetime-column-D_F30OLW.js.br +2 -0
  151. codex/static_root/assets/datetime-column-D_F30OLW.js.gz +0 -0
  152. codex/static_root/assets/{filter-CmOjoKbH.ea79c4727d92.js → filter-ud5mPZpn.0f0a537959aa.js} +1 -1
  153. codex/static_root/assets/filter-ud5mPZpn.0f0a537959aa.js.br +0 -0
  154. codex/static_root/assets/filter-ud5mPZpn.0f0a537959aa.js.gz +0 -0
  155. codex/static_root/assets/{filter-CmOjoKbH.js → filter-ud5mPZpn.js} +1 -1
  156. codex/static_root/assets/filter-ud5mPZpn.js.br +0 -0
  157. codex/static_root/assets/filter-ud5mPZpn.js.gz +0 -0
  158. codex/static_root/assets/{flag-tab-1PeNvDA9.2fc60db57915.js → flag-tab-k2g6u_vi.3e1da9318af9.js} +1 -1
  159. codex/static_root/assets/flag-tab-k2g6u_vi.3e1da9318af9.js.br +0 -0
  160. codex/static_root/assets/flag-tab-k2g6u_vi.3e1da9318af9.js.gz +0 -0
  161. codex/static_root/assets/{flag-tab-1PeNvDA9.js → flag-tab-k2g6u_vi.js} +1 -1
  162. codex/static_root/assets/flag-tab-k2g6u_vi.js.br +0 -0
  163. codex/static_root/assets/flag-tab-k2g6u_vi.js.gz +0 -0
  164. codex/static_root/assets/{group-tab-Zl_C7M7Z.dbeed7f2d08f.js → group-tab-C6Ykf03Z.ff0cc204013a.js} +1 -1
  165. codex/static_root/assets/group-tab-C6Ykf03Z.ff0cc204013a.js.br +0 -0
  166. codex/static_root/assets/group-tab-C6Ykf03Z.ff0cc204013a.js.gz +0 -0
  167. codex/static_root/assets/{group-tab-Zl_C7M7Z.js → group-tab-C6Ykf03Z.js} +1 -1
  168. codex/static_root/assets/group-tab-C6Ykf03Z.js.br +0 -0
  169. codex/static_root/assets/group-tab-C6Ykf03Z.js.gz +0 -0
  170. codex/static_root/assets/http-error-Ctcws1xe.cfd378a792d2.css +1 -0
  171. codex/static_root/assets/{http-error-DKulXuTl.95e42988d5d5.css.br → http-error-Ctcws1xe.cfd378a792d2.css.br} +0 -0
  172. codex/static_root/assets/http-error-Ctcws1xe.cfd378a792d2.css.gz +0 -0
  173. codex/static_root/assets/http-error-Ctcws1xe.css +1 -0
  174. codex/static_root/assets/{http-error-DKulXuTl.css.br → http-error-Ctcws1xe.css.br} +0 -0
  175. codex/static_root/assets/http-error-Ctcws1xe.css.gz +0 -0
  176. codex/static_root/assets/{http-error-YNrrsTPg.73e9978dc0ce.js → http-error-DQBHK8v5.aea50b1327fd.js} +1 -1
  177. codex/static_root/assets/http-error-DQBHK8v5.aea50b1327fd.js.br +0 -0
  178. codex/static_root/assets/http-error-DQBHK8v5.aea50b1327fd.js.gz +0 -0
  179. codex/static_root/assets/{http-error-YNrrsTPg.js → http-error-DQBHK8v5.js} +1 -1
  180. codex/static_root/assets/http-error-DQBHK8v5.js.br +0 -0
  181. codex/static_root/assets/http-error-DQBHK8v5.js.gz +0 -0
  182. codex/static_root/assets/index-ClGiHwWc.0717bacf5135.js +1 -0
  183. codex/static_root/assets/index-ClGiHwWc.0717bacf5135.js.br +0 -0
  184. codex/static_root/assets/index-ClGiHwWc.0717bacf5135.js.gz +0 -0
  185. codex/static_root/assets/index-ClGiHwWc.js +1 -0
  186. codex/static_root/assets/index-ClGiHwWc.js.br +0 -0
  187. codex/static_root/assets/index-ClGiHwWc.js.gz +0 -0
  188. codex/static_root/assets/library-tab-BpinbqAu.53fa2625e727.js +1 -0
  189. codex/static_root/assets/library-tab-BpinbqAu.53fa2625e727.js.br +0 -0
  190. codex/static_root/assets/library-tab-BpinbqAu.53fa2625e727.js.gz +0 -0
  191. codex/static_root/assets/library-tab-BpinbqAu.js +1 -0
  192. codex/static_root/assets/library-tab-BpinbqAu.js.br +0 -0
  193. codex/static_root/assets/library-tab-BpinbqAu.js.gz +0 -0
  194. codex/static_root/assets/library-tab-Cat0MAK5.5911f022188e.css +1 -0
  195. codex/static_root/assets/library-tab-Cat0MAK5.5911f022188e.css.br +0 -0
  196. codex/static_root/assets/library-tab-Cat0MAK5.5911f022188e.css.gz +0 -0
  197. codex/static_root/assets/library-tab-Cat0MAK5.css +1 -0
  198. codex/static_root/assets/library-tab-Cat0MAK5.css.br +0 -0
  199. codex/static_root/assets/library-tab-Cat0MAK5.css.gz +0 -0
  200. codex/static_root/assets/main-BVKrDunc.1c6f8cdc3afb.js +35 -0
  201. codex/static_root/assets/main-BVKrDunc.1c6f8cdc3afb.js.br +0 -0
  202. codex/static_root/assets/main-BVKrDunc.1c6f8cdc3afb.js.gz +0 -0
  203. codex/static_root/assets/main-BVKrDunc.js +35 -0
  204. codex/static_root/assets/main-BVKrDunc.js.br +0 -0
  205. codex/static_root/assets/main-BVKrDunc.js.gz +0 -0
  206. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.f2e95b19621c.js +1 -0
  207. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.f2e95b19621c.js.br +0 -0
  208. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.f2e95b19621c.js.gz +0 -0
  209. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.js +1 -0
  210. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.js.br +0 -0
  211. codex/static_root/assets/pager-full-pdf-C1ZSyXfG.js.gz +0 -0
  212. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.546121fa7a0d.css +1 -0
  213. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.546121fa7a0d.css.br +0 -0
  214. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.546121fa7a0d.css.gz +0 -0
  215. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.css +1 -0
  216. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.css.br +0 -0
  217. codex/static_root/assets/pagination-toolbar-Cx_9nh6D.css.gz +0 -0
  218. codex/static_root/assets/pagination-toolbar-Diad0EdD.140911bf86af.js +1 -0
  219. codex/static_root/assets/pagination-toolbar-Diad0EdD.140911bf86af.js.br +0 -0
  220. codex/static_root/assets/pagination-toolbar-Diad0EdD.140911bf86af.js.gz +0 -0
  221. codex/static_root/assets/pagination-toolbar-Diad0EdD.js +1 -0
  222. codex/static_root/assets/pagination-toolbar-Diad0EdD.js.br +0 -0
  223. codex/static_root/assets/pagination-toolbar-Diad0EdD.js.gz +0 -0
  224. codex/static_root/assets/{pdf-doc-BbuJd_VS.225d8590d020.js → pdf-doc-b-GyNR6z.c9d18f0d36ed.js} +1 -1
  225. codex/static_root/assets/pdf-doc-b-GyNR6z.c9d18f0d36ed.js.br +0 -0
  226. codex/static_root/assets/pdf-doc-b-GyNR6z.c9d18f0d36ed.js.gz +0 -0
  227. codex/static_root/assets/{pdf-doc-BbuJd_VS.js → pdf-doc-b-GyNR6z.js} +1 -1
  228. codex/static_root/assets/pdf-doc-b-GyNR6z.js.br +0 -0
  229. codex/static_root/assets/pdf-doc-b-GyNR6z.js.gz +0 -0
  230. codex/static_root/assets/reader-2up6WEuE.c56ad81d14c6.js +2 -0
  231. codex/static_root/assets/reader-2up6WEuE.c56ad81d14c6.js.br +0 -0
  232. codex/static_root/assets/reader-2up6WEuE.c56ad81d14c6.js.gz +0 -0
  233. codex/static_root/assets/reader-2up6WEuE.js +2 -0
  234. codex/static_root/assets/reader-2up6WEuE.js.br +0 -0
  235. codex/static_root/assets/reader-2up6WEuE.js.gz +0 -0
  236. codex/static_root/assets/reader-Dd2KmdCN.115d4bfe9280.css +1 -0
  237. codex/static_root/assets/reader-Dd2KmdCN.115d4bfe9280.css.br +0 -0
  238. codex/static_root/assets/reader-Dd2KmdCN.115d4bfe9280.css.gz +0 -0
  239. codex/static_root/assets/reader-Dd2KmdCN.css +1 -0
  240. codex/static_root/assets/reader-Dd2KmdCN.css.br +0 -0
  241. codex/static_root/assets/reader-Dd2KmdCN.css.gz +0 -0
  242. codex/static_root/assets/relation-chips-piYv1IcD.f8a2ae79de89.js +1 -0
  243. codex/static_root/assets/relation-chips-piYv1IcD.f8a2ae79de89.js.br +0 -0
  244. codex/static_root/assets/relation-chips-piYv1IcD.f8a2ae79de89.js.gz +0 -0
  245. codex/static_root/assets/relation-chips-piYv1IcD.js +1 -0
  246. codex/static_root/assets/relation-chips-piYv1IcD.js.br +0 -0
  247. codex/static_root/assets/relation-chips-piYv1IcD.js.gz +0 -0
  248. codex/static_root/assets/{settings-drawer-C-hgtHJt.0eaf7e00ee9b.js → settings-drawer-yVoY-WCS.1240cc47a246.js} +2 -2
  249. codex/static_root/assets/settings-drawer-yVoY-WCS.1240cc47a246.js.br +0 -0
  250. codex/static_root/assets/settings-drawer-yVoY-WCS.1240cc47a246.js.gz +0 -0
  251. codex/static_root/assets/{settings-drawer-C-hgtHJt.js → settings-drawer-yVoY-WCS.js} +2 -2
  252. codex/static_root/assets/settings-drawer-yVoY-WCS.js.br +0 -0
  253. codex/static_root/assets/settings-drawer-yVoY-WCS.js.gz +0 -0
  254. codex/static_root/assets/{stats-tab-BAYTqQNg.5f715428c394.css → stats-tab-BlXGStge.9fdb0106124d.css} +1 -1
  255. codex/static_root/assets/stats-tab-BlXGStge.9fdb0106124d.css.br +0 -0
  256. codex/static_root/assets/stats-tab-BlXGStge.9fdb0106124d.css.gz +0 -0
  257. codex/static_root/assets/{stats-tab-BAYTqQNg.css → stats-tab-BlXGStge.css} +1 -1
  258. codex/static_root/assets/stats-tab-BlXGStge.css.br +0 -0
  259. codex/static_root/assets/stats-tab-BlXGStge.css.gz +0 -0
  260. codex/static_root/assets/{stats-tab-C7iJCFa5.f1039eba03c2.js → stats-tab-bqSPLvTp.05106cb03ef0.js} +1 -1
  261. codex/static_root/assets/stats-tab-bqSPLvTp.05106cb03ef0.js.br +0 -0
  262. codex/static_root/assets/stats-tab-bqSPLvTp.05106cb03ef0.js.gz +0 -0
  263. codex/static_root/assets/{stats-tab-C7iJCFa5.js → stats-tab-bqSPLvTp.js} +1 -1
  264. codex/static_root/assets/stats-tab-bqSPLvTp.js.br +0 -0
  265. codex/static_root/assets/stats-tab-bqSPLvTp.js.gz +0 -0
  266. codex/static_root/assets/task-tab-DWPKaGPT.da4df28dde5c.js +1 -0
  267. codex/static_root/assets/task-tab-DWPKaGPT.da4df28dde5c.js.br +0 -0
  268. codex/static_root/assets/task-tab-DWPKaGPT.da4df28dde5c.js.gz +0 -0
  269. codex/static_root/assets/task-tab-DWPKaGPT.js +1 -0
  270. codex/static_root/assets/task-tab-DWPKaGPT.js.br +0 -0
  271. codex/static_root/assets/task-tab-DWPKaGPT.js.gz +0 -0
  272. codex/static_root/assets/task-tab-EGlhcKTH.478e74041f80.css +1 -0
  273. codex/static_root/assets/{task-tab--cXi48kg.5dfd6890a1c2.css.br → task-tab-EGlhcKTH.478e74041f80.css.br} +1 -1
  274. codex/static_root/assets/task-tab-EGlhcKTH.478e74041f80.css.gz +0 -0
  275. codex/static_root/assets/task-tab-EGlhcKTH.css +1 -0
  276. codex/static_root/assets/{task-tab--cXi48kg.css.br → task-tab-EGlhcKTH.css.br} +1 -1
  277. codex/static_root/assets/task-tab-EGlhcKTH.css.gz +0 -0
  278. codex/static_root/assets/{transition-CQVFPpmZ.ba35e475243a.js → transition-DWVQ2EZ3.0bdfaa37b937.js} +1 -1
  279. codex/static_root/assets/transition-DWVQ2EZ3.0bdfaa37b937.js.br +0 -0
  280. codex/static_root/assets/transition-DWVQ2EZ3.0bdfaa37b937.js.gz +0 -0
  281. codex/static_root/assets/{transition-CQVFPpmZ.js → transition-DWVQ2EZ3.js} +1 -1
  282. codex/static_root/assets/transition-DWVQ2EZ3.js.br +0 -0
  283. codex/static_root/assets/transition-DWVQ2EZ3.js.gz +0 -0
  284. codex/static_root/assets/unauthorized-CEGD20tR.064b0993a944.js +1 -0
  285. codex/static_root/assets/unauthorized-CEGD20tR.064b0993a944.js.br +0 -0
  286. codex/static_root/assets/unauthorized-CEGD20tR.064b0993a944.js.gz +0 -0
  287. codex/static_root/assets/unauthorized-CEGD20tR.js +1 -0
  288. codex/static_root/assets/unauthorized-CEGD20tR.js.br +0 -0
  289. codex/static_root/assets/unauthorized-CEGD20tR.js.gz +0 -0
  290. codex/static_root/assets/{unauthorized-BjhIc97q.728511c92cd0.css → unauthorized-DyojW2ic.css} +1 -1
  291. codex/static_root/assets/unauthorized-DyojW2ic.css.br +0 -0
  292. codex/static_root/assets/unauthorized-DyojW2ic.css.gz +0 -0
  293. codex/static_root/assets/{unauthorized-BjhIc97q.css → unauthorized-DyojW2ic.feefa7628a23.css} +1 -1
  294. codex/static_root/assets/unauthorized-DyojW2ic.feefa7628a23.css.br +0 -0
  295. codex/static_root/assets/unauthorized-DyojW2ic.feefa7628a23.css.gz +0 -0
  296. codex/static_root/assets/{user-tab-icKcK_Qd.c29142ed5212.js → user-tab-EsokzMCB.b0acc46b56a3.js} +1 -1
  297. codex/static_root/assets/user-tab-EsokzMCB.b0acc46b56a3.js.br +0 -0
  298. codex/static_root/assets/user-tab-EsokzMCB.b0acc46b56a3.js.gz +0 -0
  299. codex/static_root/assets/{user-tab-icKcK_Qd.js → user-tab-EsokzMCB.js} +1 -1
  300. codex/static_root/assets/user-tab-EsokzMCB.js.br +0 -0
  301. codex/static_root/assets/user-tab-EsokzMCB.js.gz +0 -0
  302. codex/static_root/{manifest.3eee2b4822b7.json → manifest.4a38de3db1c5.json} +275 -275
  303. codex/static_root/manifest.4a38de3db1c5.json.br +0 -0
  304. codex/static_root/manifest.4a38de3db1c5.json.gz +0 -0
  305. codex/static_root/manifest.json +275 -275
  306. codex/static_root/manifest.json.br +0 -0
  307. codex/static_root/manifest.json.gz +0 -0
  308. codex/static_root/staticfiles.json +1 -1
  309. codex/urls/api/browser.py +9 -0
  310. codex/urls/api/reader.py +8 -4
  311. codex/util.py +11 -0
  312. codex/views/admin/tasks.py +1 -2
  313. codex/views/bookmark.py +1 -1
  314. codex/views/browser/annotate/card.py +12 -0
  315. codex/views/browser/annotate/order.py +13 -9
  316. codex/views/browser/download.py +64 -0
  317. codex/views/browser/filters/group.py +2 -0
  318. codex/views/browser/validate.py +7 -3
  319. codex/views/download.py +5 -5
  320. codex/views/reader/page.py +11 -6
  321. codex/views/reader/params.py +1 -1
  322. codex/views/session.py +2 -1
  323. codex/views/timezone.py +2 -14
  324. {codex-1.7.0a2.dist-info → codex-1.7.2.dist-info}/METADATA +5 -7
  325. {codex-1.7.0a2.dist-info → codex-1.7.2.dist-info}/RECORD +328 -325
  326. codex/static_root/assets/VCheckbox-CCOzQpCw.a65ad95bd21a.js +0 -1
  327. codex/static_root/assets/VCheckbox-CCOzQpCw.a65ad95bd21a.js.br +0 -0
  328. codex/static_root/assets/VCheckbox-CCOzQpCw.a65ad95bd21a.js.gz +0 -0
  329. codex/static_root/assets/VCheckbox-CCOzQpCw.js +0 -1
  330. codex/static_root/assets/VCheckbox-CCOzQpCw.js.br +0 -0
  331. codex/static_root/assets/VCheckbox-CCOzQpCw.js.gz +0 -0
  332. codex/static_root/assets/VCheckboxBtn-DnBH3a96.876fda35b85a.js.br +0 -0
  333. codex/static_root/assets/VCheckboxBtn-DnBH3a96.876fda35b85a.js.gz +0 -0
  334. codex/static_root/assets/VCheckboxBtn-DnBH3a96.js.br +0 -0
  335. codex/static_root/assets/VCheckboxBtn-DnBH3a96.js.gz +0 -0
  336. codex/static_root/assets/VCombobox-DwwoR4yO.e7a4db7ab7f0.js +0 -1
  337. codex/static_root/assets/VCombobox-DwwoR4yO.e7a4db7ab7f0.js.br +0 -0
  338. codex/static_root/assets/VCombobox-DwwoR4yO.e7a4db7ab7f0.js.gz +0 -0
  339. codex/static_root/assets/VCombobox-DwwoR4yO.js +0 -1
  340. codex/static_root/assets/VCombobox-DwwoR4yO.js.br +0 -0
  341. codex/static_root/assets/VCombobox-DwwoR4yO.js.gz +0 -0
  342. codex/static_root/assets/VDialog-CSvrKKb2.css +0 -1
  343. codex/static_root/assets/VDialog-CSvrKKb2.css.br +0 -0
  344. codex/static_root/assets/VDialog-CSvrKKb2.css.gz +0 -0
  345. codex/static_root/assets/VDialog-CSvrKKb2.fd4d50904b17.css +0 -1
  346. codex/static_root/assets/VDialog-CSvrKKb2.fd4d50904b17.css.br +0 -0
  347. codex/static_root/assets/VDialog-CSvrKKb2.fd4d50904b17.css.gz +0 -0
  348. codex/static_root/assets/VDialog-DbN2FfmF.b2843f79d90f.js +0 -1
  349. codex/static_root/assets/VDialog-DbN2FfmF.b2843f79d90f.js.br +0 -0
  350. codex/static_root/assets/VDialog-DbN2FfmF.b2843f79d90f.js.gz +0 -0
  351. codex/static_root/assets/VDialog-DbN2FfmF.js +0 -1
  352. codex/static_root/assets/VDialog-DbN2FfmF.js.br +0 -0
  353. codex/static_root/assets/VDialog-DbN2FfmF.js.gz +0 -0
  354. codex/static_root/assets/VExpansionPanels-CBPnoy7O.212f4cad7d78.js.br +0 -0
  355. codex/static_root/assets/VExpansionPanels-CBPnoy7O.212f4cad7d78.js.gz +0 -0
  356. codex/static_root/assets/VExpansionPanels-CBPnoy7O.js.br +0 -0
  357. codex/static_root/assets/VExpansionPanels-CBPnoy7O.js.gz +0 -0
  358. codex/static_root/assets/VRadioGroup-C7Zu_Eup.b42735892aec.js.br +0 -0
  359. codex/static_root/assets/VRadioGroup-C7Zu_Eup.b42735892aec.js.gz +0 -0
  360. codex/static_root/assets/VRadioGroup-C7Zu_Eup.js.br +0 -0
  361. codex/static_root/assets/VRadioGroup-C7Zu_Eup.js.gz +0 -0
  362. codex/static_root/assets/VSelect-BTy7SKk0.dee138de5dd0.js +0 -1
  363. codex/static_root/assets/VSelect-BTy7SKk0.dee138de5dd0.js.br +0 -0
  364. codex/static_root/assets/VSelect-BTy7SKk0.dee138de5dd0.js.gz +0 -0
  365. codex/static_root/assets/VSelect-BTy7SKk0.js +0 -1
  366. codex/static_root/assets/VSelect-BTy7SKk0.js.br +0 -0
  367. codex/static_root/assets/VSelect-BTy7SKk0.js.gz +0 -0
  368. codex/static_root/assets/VSelectionControl-B42mmzLA.bf64d259ddef.js.br +0 -0
  369. codex/static_root/assets/VSelectionControl-B42mmzLA.bf64d259ddef.js.gz +0 -0
  370. codex/static_root/assets/VSelectionControl-B42mmzLA.js.br +0 -0
  371. codex/static_root/assets/VSelectionControl-B42mmzLA.js.gz +0 -0
  372. codex/static_root/assets/VSlideGroup-BtfHoWCn.33e2bd94e34a.js.br +0 -0
  373. codex/static_root/assets/VSlideGroup-BtfHoWCn.33e2bd94e34a.js.gz +0 -0
  374. codex/static_root/assets/VSlideGroup-BtfHoWCn.js.br +0 -0
  375. codex/static_root/assets/VSlideGroup-BtfHoWCn.js.gz +0 -0
  376. codex/static_root/assets/VTable-R3X0iPjV.ee07d9c2ca5f.js.br +0 -0
  377. codex/static_root/assets/VTable-R3X0iPjV.ee07d9c2ca5f.js.gz +0 -0
  378. codex/static_root/assets/VTable-R3X0iPjV.js.br +0 -0
  379. codex/static_root/assets/VTable-R3X0iPjV.js.gz +0 -0
  380. codex/static_root/assets/VTextField-BnCEPZIq.b0c32b2c0b14.css +0 -1
  381. codex/static_root/assets/VTextField-BnCEPZIq.b0c32b2c0b14.css.br +0 -0
  382. codex/static_root/assets/VTextField-BnCEPZIq.b0c32b2c0b14.css.gz +0 -0
  383. codex/static_root/assets/VTextField-BnCEPZIq.css +0 -1
  384. codex/static_root/assets/VTextField-BnCEPZIq.css.br +0 -0
  385. codex/static_root/assets/VTextField-BnCEPZIq.css.gz +0 -0
  386. codex/static_root/assets/VTextField-D9pqgz_R.47beb9e7e547.js +0 -1
  387. codex/static_root/assets/VTextField-D9pqgz_R.47beb9e7e547.js.br +0 -0
  388. codex/static_root/assets/VTextField-D9pqgz_R.47beb9e7e547.js.gz +0 -0
  389. codex/static_root/assets/VTextField-D9pqgz_R.js +0 -1
  390. codex/static_root/assets/VTextField-D9pqgz_R.js.br +0 -0
  391. codex/static_root/assets/VTextField-D9pqgz_R.js.gz +0 -0
  392. codex/static_root/assets/VWindowItem-DHTDdYfK.f6bf6b893442.js.br +0 -0
  393. codex/static_root/assets/VWindowItem-DHTDdYfK.f6bf6b893442.js.gz +0 -0
  394. codex/static_root/assets/VWindowItem-DHTDdYfK.js.br +0 -0
  395. codex/static_root/assets/VWindowItem-DHTDdYfK.js.gz +0 -0
  396. codex/static_root/assets/admin-CIWyRJnH.dde0ee029f08.js.br +0 -0
  397. codex/static_root/assets/admin-CIWyRJnH.dde0ee029f08.js.gz +0 -0
  398. codex/static_root/assets/admin-CIWyRJnH.js.br +0 -0
  399. codex/static_root/assets/admin-CIWyRJnH.js.gz +0 -0
  400. codex/static_root/assets/admin-menu-BHOUwxhf.1ed26b58fb9f.js +0 -1
  401. codex/static_root/assets/admin-menu-BHOUwxhf.1ed26b58fb9f.js.br +0 -0
  402. codex/static_root/assets/admin-menu-BHOUwxhf.1ed26b58fb9f.js.gz +0 -0
  403. codex/static_root/assets/admin-menu-BHOUwxhf.js +0 -1
  404. codex/static_root/assets/admin-menu-BHOUwxhf.js.br +0 -0
  405. codex/static_root/assets/admin-menu-BHOUwxhf.js.gz +0 -0
  406. codex/static_root/assets/admin-settings-button-progress-DHIl0C8k.85a213c96423.js.br +0 -0
  407. codex/static_root/assets/admin-settings-button-progress-DHIl0C8k.85a213c96423.js.gz +0 -0
  408. codex/static_root/assets/admin-settings-button-progress-DHIl0C8k.js.br +0 -0
  409. codex/static_root/assets/admin-settings-button-progress-DHIl0C8k.js.gz +0 -0
  410. codex/static_root/assets/browser-6T4uwUjJ.7dd4a7f74df6.js +0 -1
  411. codex/static_root/assets/browser-6T4uwUjJ.7dd4a7f74df6.js.br +0 -0
  412. codex/static_root/assets/browser-6T4uwUjJ.7dd4a7f74df6.js.gz +0 -0
  413. codex/static_root/assets/browser-6T4uwUjJ.js +0 -1
  414. codex/static_root/assets/browser-6T4uwUjJ.js.br +0 -0
  415. codex/static_root/assets/browser-6T4uwUjJ.js.gz +0 -0
  416. codex/static_root/assets/browser-Br5CorL4.6e2a416309d5.css +0 -1
  417. codex/static_root/assets/browser-Br5CorL4.6e2a416309d5.css.br +0 -0
  418. codex/static_root/assets/browser-Br5CorL4.6e2a416309d5.css.gz +0 -0
  419. codex/static_root/assets/browser-Br5CorL4.css +0 -1
  420. codex/static_root/assets/browser-Br5CorL4.css.br +0 -0
  421. codex/static_root/assets/browser-Br5CorL4.css.gz +0 -0
  422. codex/static_root/assets/change-password-dialog-BfiQBpUn.48db4c906920.js +0 -1
  423. codex/static_root/assets/change-password-dialog-BfiQBpUn.48db4c906920.js.br +0 -0
  424. codex/static_root/assets/change-password-dialog-BfiQBpUn.48db4c906920.js.gz +0 -0
  425. codex/static_root/assets/change-password-dialog-BfiQBpUn.js +0 -1
  426. codex/static_root/assets/change-password-dialog-BfiQBpUn.js.br +0 -0
  427. codex/static_root/assets/change-password-dialog-BfiQBpUn.js.gz +0 -0
  428. codex/static_root/assets/change-password-dialog-DrIXdKUC.217574b45b02.css +0 -1
  429. codex/static_root/assets/change-password-dialog-DrIXdKUC.217574b45b02.css.br +0 -0
  430. codex/static_root/assets/change-password-dialog-DrIXdKUC.217574b45b02.css.gz +0 -0
  431. codex/static_root/assets/change-password-dialog-DrIXdKUC.css +0 -1
  432. codex/static_root/assets/change-password-dialog-DrIXdKUC.css.br +0 -0
  433. codex/static_root/assets/change-password-dialog-DrIXdKUC.css.gz +0 -0
  434. codex/static_root/assets/confirm-dialog-B7w6z2rf.472011c06253.css +0 -1
  435. codex/static_root/assets/confirm-dialog-B7w6z2rf.css +0 -1
  436. codex/static_root/assets/confirm-dialog-Iyuhxfyi.cf28325e58b7.js +0 -1
  437. codex/static_root/assets/confirm-dialog-Iyuhxfyi.cf28325e58b7.js.br +0 -0
  438. codex/static_root/assets/confirm-dialog-Iyuhxfyi.cf28325e58b7.js.gz +0 -0
  439. codex/static_root/assets/confirm-dialog-Iyuhxfyi.js +0 -1
  440. codex/static_root/assets/confirm-dialog-Iyuhxfyi.js.br +0 -0
  441. codex/static_root/assets/confirm-dialog-Iyuhxfyi.js.gz +0 -0
  442. codex/static_root/assets/datetime-column-Dnxh9sRh.b6a92a6bcce9.js.br +0 -0
  443. codex/static_root/assets/datetime-column-Dnxh9sRh.b6a92a6bcce9.js.gz +0 -0
  444. codex/static_root/assets/datetime-column-Dnxh9sRh.js.br +0 -0
  445. codex/static_root/assets/datetime-column-Dnxh9sRh.js.gz +0 -0
  446. codex/static_root/assets/filter-CmOjoKbH.ea79c4727d92.js.br +0 -0
  447. codex/static_root/assets/filter-CmOjoKbH.ea79c4727d92.js.gz +0 -0
  448. codex/static_root/assets/filter-CmOjoKbH.js.br +0 -0
  449. codex/static_root/assets/filter-CmOjoKbH.js.gz +0 -0
  450. codex/static_root/assets/flag-tab-1PeNvDA9.2fc60db57915.js.br +0 -0
  451. codex/static_root/assets/flag-tab-1PeNvDA9.2fc60db57915.js.gz +0 -0
  452. codex/static_root/assets/flag-tab-1PeNvDA9.js.br +0 -0
  453. codex/static_root/assets/flag-tab-1PeNvDA9.js.gz +0 -0
  454. codex/static_root/assets/group-tab-Zl_C7M7Z.dbeed7f2d08f.js.br +0 -0
  455. codex/static_root/assets/group-tab-Zl_C7M7Z.dbeed7f2d08f.js.gz +0 -0
  456. codex/static_root/assets/group-tab-Zl_C7M7Z.js.br +0 -0
  457. codex/static_root/assets/group-tab-Zl_C7M7Z.js.gz +0 -0
  458. codex/static_root/assets/http-error-DKulXuTl.95e42988d5d5.css +0 -1
  459. codex/static_root/assets/http-error-DKulXuTl.95e42988d5d5.css.gz +0 -0
  460. codex/static_root/assets/http-error-DKulXuTl.css +0 -1
  461. codex/static_root/assets/http-error-DKulXuTl.css.gz +0 -0
  462. codex/static_root/assets/http-error-YNrrsTPg.73e9978dc0ce.js.br +0 -0
  463. codex/static_root/assets/http-error-YNrrsTPg.73e9978dc0ce.js.gz +0 -0
  464. codex/static_root/assets/http-error-YNrrsTPg.js.br +0 -0
  465. codex/static_root/assets/http-error-YNrrsTPg.js.gz +0 -0
  466. codex/static_root/assets/index-j5K-C_JC.65c2dc5af141.js +0 -1
  467. codex/static_root/assets/index-j5K-C_JC.65c2dc5af141.js.br +0 -0
  468. codex/static_root/assets/index-j5K-C_JC.65c2dc5af141.js.gz +0 -0
  469. codex/static_root/assets/index-j5K-C_JC.js +0 -1
  470. codex/static_root/assets/index-j5K-C_JC.js.br +0 -0
  471. codex/static_root/assets/index-j5K-C_JC.js.gz +0 -0
  472. codex/static_root/assets/library-tab-CxKs8G-K.c6bfd6d53b17.js +0 -1
  473. codex/static_root/assets/library-tab-CxKs8G-K.c6bfd6d53b17.js.br +0 -0
  474. codex/static_root/assets/library-tab-CxKs8G-K.c6bfd6d53b17.js.gz +0 -0
  475. codex/static_root/assets/library-tab-CxKs8G-K.js +0 -1
  476. codex/static_root/assets/library-tab-CxKs8G-K.js.br +0 -0
  477. codex/static_root/assets/library-tab-CxKs8G-K.js.gz +0 -0
  478. codex/static_root/assets/library-tab-Wew8YOLv.0c1780a6b68e.css +0 -1
  479. codex/static_root/assets/library-tab-Wew8YOLv.0c1780a6b68e.css.br +0 -0
  480. codex/static_root/assets/library-tab-Wew8YOLv.0c1780a6b68e.css.gz +0 -0
  481. codex/static_root/assets/library-tab-Wew8YOLv.css +0 -1
  482. codex/static_root/assets/library-tab-Wew8YOLv.css.br +0 -0
  483. codex/static_root/assets/library-tab-Wew8YOLv.css.gz +0 -0
  484. codex/static_root/assets/main-H14uUxuN.cc1511f0f146.js +0 -35
  485. codex/static_root/assets/main-H14uUxuN.cc1511f0f146.js.br +0 -0
  486. codex/static_root/assets/main-H14uUxuN.cc1511f0f146.js.gz +0 -0
  487. codex/static_root/assets/main-H14uUxuN.js +0 -35
  488. codex/static_root/assets/main-H14uUxuN.js.br +0 -0
  489. codex/static_root/assets/main-H14uUxuN.js.gz +0 -0
  490. codex/static_root/assets/pager-full-pdf-DcRg28qt.ca9cdb9619ff.js +0 -1
  491. codex/static_root/assets/pager-full-pdf-DcRg28qt.ca9cdb9619ff.js.br +0 -0
  492. codex/static_root/assets/pager-full-pdf-DcRg28qt.ca9cdb9619ff.js.gz +0 -0
  493. codex/static_root/assets/pager-full-pdf-DcRg28qt.js +0 -1
  494. codex/static_root/assets/pager-full-pdf-DcRg28qt.js.br +0 -0
  495. codex/static_root/assets/pager-full-pdf-DcRg28qt.js.gz +0 -0
  496. codex/static_root/assets/pagination-toolbar-BgoV4zqc.ab5fa1be17a3.js +0 -1
  497. codex/static_root/assets/pagination-toolbar-BgoV4zqc.ab5fa1be17a3.js.br +0 -0
  498. codex/static_root/assets/pagination-toolbar-BgoV4zqc.ab5fa1be17a3.js.gz +0 -0
  499. codex/static_root/assets/pagination-toolbar-BgoV4zqc.js +0 -1
  500. codex/static_root/assets/pagination-toolbar-BgoV4zqc.js.br +0 -0
  501. codex/static_root/assets/pagination-toolbar-BgoV4zqc.js.gz +0 -0
  502. codex/static_root/assets/pagination-toolbar-DGrxp2OD.css +0 -1
  503. codex/static_root/assets/pagination-toolbar-DGrxp2OD.css.br +0 -0
  504. codex/static_root/assets/pagination-toolbar-DGrxp2OD.css.gz +0 -0
  505. codex/static_root/assets/pagination-toolbar-DGrxp2OD.f960a624f04f.css +0 -1
  506. codex/static_root/assets/pagination-toolbar-DGrxp2OD.f960a624f04f.css.br +0 -0
  507. codex/static_root/assets/pagination-toolbar-DGrxp2OD.f960a624f04f.css.gz +0 -0
  508. codex/static_root/assets/pdf-doc-BbuJd_VS.225d8590d020.js.br +0 -0
  509. codex/static_root/assets/pdf-doc-BbuJd_VS.225d8590d020.js.gz +0 -0
  510. codex/static_root/assets/pdf-doc-BbuJd_VS.js.br +0 -0
  511. codex/static_root/assets/pdf-doc-BbuJd_VS.js.gz +0 -0
  512. codex/static_root/assets/reader-DORea4Al.d8e756bb0027.js +0 -2
  513. codex/static_root/assets/reader-DORea4Al.d8e756bb0027.js.br +0 -0
  514. codex/static_root/assets/reader-DORea4Al.d8e756bb0027.js.gz +0 -0
  515. codex/static_root/assets/reader-DORea4Al.js +0 -2
  516. codex/static_root/assets/reader-DORea4Al.js.br +0 -0
  517. codex/static_root/assets/reader-DORea4Al.js.gz +0 -0
  518. codex/static_root/assets/reader-OpKdTZ_B.css +0 -1
  519. codex/static_root/assets/reader-OpKdTZ_B.css.br +0 -0
  520. codex/static_root/assets/reader-OpKdTZ_B.css.gz +0 -0
  521. codex/static_root/assets/reader-OpKdTZ_B.ebd1512b7014.css +0 -1
  522. codex/static_root/assets/reader-OpKdTZ_B.ebd1512b7014.css.br +0 -0
  523. codex/static_root/assets/reader-OpKdTZ_B.ebd1512b7014.css.gz +0 -0
  524. codex/static_root/assets/relation-chips-kqofGdNg.0c7a53962f2b.js +0 -1
  525. codex/static_root/assets/relation-chips-kqofGdNg.0c7a53962f2b.js.br +0 -0
  526. codex/static_root/assets/relation-chips-kqofGdNg.0c7a53962f2b.js.gz +0 -0
  527. codex/static_root/assets/relation-chips-kqofGdNg.js +0 -1
  528. codex/static_root/assets/relation-chips-kqofGdNg.js.br +0 -0
  529. codex/static_root/assets/relation-chips-kqofGdNg.js.gz +0 -0
  530. codex/static_root/assets/settings-drawer-C-hgtHJt.0eaf7e00ee9b.js.br +0 -0
  531. codex/static_root/assets/settings-drawer-C-hgtHJt.0eaf7e00ee9b.js.gz +0 -0
  532. codex/static_root/assets/settings-drawer-C-hgtHJt.js.br +0 -0
  533. codex/static_root/assets/settings-drawer-C-hgtHJt.js.gz +0 -0
  534. codex/static_root/assets/stats-tab-BAYTqQNg.5f715428c394.css.br +0 -0
  535. codex/static_root/assets/stats-tab-BAYTqQNg.5f715428c394.css.gz +0 -0
  536. codex/static_root/assets/stats-tab-BAYTqQNg.css.br +0 -0
  537. codex/static_root/assets/stats-tab-BAYTqQNg.css.gz +0 -0
  538. codex/static_root/assets/stats-tab-C7iJCFa5.f1039eba03c2.js.br +0 -0
  539. codex/static_root/assets/stats-tab-C7iJCFa5.f1039eba03c2.js.gz +0 -0
  540. codex/static_root/assets/stats-tab-C7iJCFa5.js.br +0 -0
  541. codex/static_root/assets/stats-tab-C7iJCFa5.js.gz +0 -0
  542. codex/static_root/assets/task-tab--cXi48kg.5dfd6890a1c2.css +0 -1
  543. codex/static_root/assets/task-tab--cXi48kg.5dfd6890a1c2.css.gz +0 -0
  544. codex/static_root/assets/task-tab--cXi48kg.css +0 -1
  545. codex/static_root/assets/task-tab--cXi48kg.css.gz +0 -0
  546. codex/static_root/assets/task-tab-Drfz5uaT.0b387dcd4f5a.js +0 -1
  547. codex/static_root/assets/task-tab-Drfz5uaT.0b387dcd4f5a.js.br +0 -0
  548. codex/static_root/assets/task-tab-Drfz5uaT.0b387dcd4f5a.js.gz +0 -0
  549. codex/static_root/assets/task-tab-Drfz5uaT.js +0 -1
  550. codex/static_root/assets/task-tab-Drfz5uaT.js.br +0 -0
  551. codex/static_root/assets/task-tab-Drfz5uaT.js.gz +0 -0
  552. codex/static_root/assets/transition-CQVFPpmZ.ba35e475243a.js.br +0 -0
  553. codex/static_root/assets/transition-CQVFPpmZ.ba35e475243a.js.gz +0 -0
  554. codex/static_root/assets/transition-CQVFPpmZ.js.br +0 -0
  555. codex/static_root/assets/transition-CQVFPpmZ.js.gz +0 -0
  556. codex/static_root/assets/unauthorized-BjhIc97q.728511c92cd0.css.br +0 -0
  557. codex/static_root/assets/unauthorized-BjhIc97q.728511c92cd0.css.gz +0 -0
  558. codex/static_root/assets/unauthorized-BjhIc97q.css.br +0 -0
  559. codex/static_root/assets/unauthorized-BjhIc97q.css.gz +0 -0
  560. codex/static_root/assets/unauthorized-Cfxq6rru.968d6e6e57bd.js +0 -1
  561. codex/static_root/assets/unauthorized-Cfxq6rru.968d6e6e57bd.js.br +0 -0
  562. codex/static_root/assets/unauthorized-Cfxq6rru.968d6e6e57bd.js.gz +0 -0
  563. codex/static_root/assets/unauthorized-Cfxq6rru.js +0 -1
  564. codex/static_root/assets/unauthorized-Cfxq6rru.js.br +0 -0
  565. codex/static_root/assets/unauthorized-Cfxq6rru.js.gz +0 -0
  566. codex/static_root/assets/user-tab-icKcK_Qd.c29142ed5212.js.br +0 -0
  567. codex/static_root/assets/user-tab-icKcK_Qd.c29142ed5212.js.gz +0 -0
  568. codex/static_root/assets/user-tab-icKcK_Qd.js.br +0 -0
  569. codex/static_root/assets/user-tab-icKcK_Qd.js.gz +0 -0
  570. codex/static_root/manifest.3eee2b4822b7.json.br +0 -0
  571. codex/static_root/manifest.3eee2b4822b7.json.gz +0 -0
  572. {codex-1.7.0a2.dist-info → codex-1.7.2.dist-info}/LICENSE +0 -0
  573. {codex-1.7.0a2.dist-info → codex-1.7.2.dist-info}/WHEEL +0 -0
  574. {codex-1.7.0a2.dist-info → codex-1.7.2.dist-info}/entry_points.txt +0 -0
Binary file
Binary file
@@ -1 +1 @@
1
- {"paths": {"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/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/fonts/glyphicons-halflings-regular.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/glyphicons-halflings-regular.woff": "rest_framework/fonts/glyphicons-halflings-regular.fa2772327f55.woff", "rest_framework/fonts/fontawesome-webfont.ttf": "rest_framework/fonts/fontawesome-webfont.dcb26c7239d8.ttf", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "rest_framework/fonts/fontawesome-webfont.svg": "rest_framework/fonts/fontawesome-webfont.83e37a11f9d7.svg", "rest_framework/fonts/glyphicons-halflings-regular.ttf": "rest_framework/fonts/glyphicons-halflings-regular.e18bbf611f2a.ttf", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "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/img/grid.png": "rest_framework/img/grid.a4b938cf382b.png", "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/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/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/bootstrap-theme.min.css.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "rest_framework/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "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/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/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "img/story-arc.svg": "img/story-arc.ca10014355ef.svg", "img/logo-maskable.svg": "img/logo-maskable.8f7de7f1c6a8.svg", "img/folder.svg": "img/folder.f28936a3701d.svg", "img/missing-cover-165.webp": "img/missing-cover-165.0743171f2148.webp", "img/missing-cover.svg": "img/missing-cover.ddb038cc2c56.svg", "img/publisher.svg": "img/publisher.82d378fcd601.svg", "img/logo-32.webp": "img/logo-32.5688944495bf.webp", "img/imprint.svg": "img/imprint.7c2adebb76d6.svg", "img/logo.svg": "img/logo.0f5344a028ca.svg", "img/volume.svg": "img/volume.814e4c79461a.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.c58d966aa64e.webp", "img/series.svg": "img/series.ec8a889b8f95.svg", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "assets/group-tab-Zl_C7M7Z.js": "assets/group-tab-Zl_C7M7Z.dbeed7f2d08f.js", "assets/main-BZ73p_WW.css": "assets/main-BZ73p_WW.d529e8b3f52a.css", "assets/VCombobox-DwwoR4yO.js": "assets/VCombobox-DwwoR4yO.e7a4db7ab7f0.js", "assets/main-H14uUxuN.js": "assets/main-H14uUxuN.cc1511f0f146.js", "assets/VSelect-DLu8bpcs.css": "assets/VSelect-DLu8bpcs.98bdcf35411c.css", "assets/transition-5LRFTPo5.css": "assets/transition-5LRFTPo5.3d726f9bbcb0.css", "assets/relation-chips-kqofGdNg.js": "assets/relation-chips-kqofGdNg.0c7a53962f2b.js", "assets/admin-menu-BHOUwxhf.js": "assets/admin-menu-BHOUwxhf.1ed26b58fb9f.js", "assets/task-tab-Drfz5uaT.js": "assets/task-tab-Drfz5uaT.0b387dcd4f5a.js", "assets/datetime-column-DeCthByU.css": "assets/datetime-column-DeCthByU.1f3bf499e063.css", "assets/unauthorized-BjhIc97q.css": "assets/unauthorized-BjhIc97q.728511c92cd0.css", "assets/VTextField-BnCEPZIq.css": "assets/VTextField-BnCEPZIq.b0c32b2c0b14.css", "assets/task-tab--cXi48kg.css": "assets/task-tab--cXi48kg.5dfd6890a1c2.css", "assets/settings-drawer-DKncO_vX.css": "assets/settings-drawer-DKncO_vX.0a2cd24cd904.css", "assets/library-tab-Wew8YOLv.css": "assets/library-tab-Wew8YOLv.0c1780a6b68e.css", "assets/admin-settings-button-progress-DUUQfVsZ.css": "assets/admin-settings-button-progress-DUUQfVsZ.2548c49a853e.css", "assets/admin-menu-B9bzD6hV.css": "assets/admin-menu-B9bzD6hV.c13b7df2ff57.css", "assets/flag-tab-CqWovuBu.css": "assets/flag-tab-CqWovuBu.4dfc6b251e85.css", "assets/http-error-YNrrsTPg.js": "assets/http-error-YNrrsTPg.73e9978dc0ce.js", "assets/browser-6T4uwUjJ.js": "assets/browser-6T4uwUjJ.7dd4a7f74df6.js", "assets/admin-settings-button-progress-DHIl0C8k.js": "assets/admin-settings-button-progress-DHIl0C8k.85a213c96423.js", "assets/index-CL_6g4tJ.css": "assets/index-CL_6g4tJ.523d7b3d350f.css", "assets/relation-chips-ByfWwuQc.css": "assets/relation-chips-ByfWwuQc.01269a188e01.css", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/VSelect-BTy7SKk0.js": "assets/VSelect-BTy7SKk0.dee138de5dd0.js", "assets/library-tab-CxKs8G-K.js": "assets/library-tab-CxKs8G-K.c6bfd6d53b17.js", "assets/confirm-dialog-B7w6z2rf.css": "assets/confirm-dialog-B7w6z2rf.472011c06253.css", "assets/group-tab-DkIN1Heu.css": "assets/group-tab-DkIN1Heu.948e907b1e6b.css", "assets/VDialog-DbN2FfmF.js": "assets/VDialog-DbN2FfmF.b2843f79d90f.js", "assets/settings-drawer-C-hgtHJt.js": "assets/settings-drawer-C-hgtHJt.0eaf7e00ee9b.js", "assets/pagination-toolbar-DGrxp2OD.css": "assets/pagination-toolbar-DGrxp2OD.f960a624f04f.css", "assets/stats-tab-BAYTqQNg.css": "assets/stats-tab-BAYTqQNg.5f715428c394.css", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/VCombobox-bwEYrXCg.css": "assets/VCombobox-bwEYrXCg.9f25a34994e2.css", "assets/VDialog-CSvrKKb2.css": "assets/VDialog-CSvrKKb2.fd4d50904b17.css", "assets/stats-tab-C7iJCFa5.js": "assets/stats-tab-C7iJCFa5.f1039eba03c2.js", "assets/change-password-dialog-BfiQBpUn.js": "assets/change-password-dialog-BfiQBpUn.48db4c906920.js", "assets/VSlideGroup-BtXPhMOT.css": "assets/VSlideGroup-BtXPhMOT.830f136ffd41.css", "assets/filter-CmOjoKbH.js": "assets/filter-CmOjoKbH.ea79c4727d92.js", "assets/VWindowItem-DHTDdYfK.js": "assets/VWindowItem-DHTDdYfK.f6bf6b893442.js", "assets/transition-CQVFPpmZ.js": "assets/transition-CQVFPpmZ.ba35e475243a.js", "assets/VTable-Y5Sc3hJd.css": "assets/VTable-Y5Sc3hJd.c36f0a6a30cf.css", "assets/VExpansionPanels-6G1AUajL.css": "assets/VExpansionPanels-6G1AUajL.5b17872981df.css", "assets/VRadioGroup-C7Zu_Eup.js": "assets/VRadioGroup-C7Zu_Eup.b42735892aec.js", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/index-j5K-C_JC.js": "assets/index-j5K-C_JC.65c2dc5af141.js", "assets/admin-CIWyRJnH.js": "assets/admin-CIWyRJnH.dde0ee029f08.js", "assets/VSelectionControl-CiViEYoC.css": "assets/VSelectionControl-CiViEYoC.c77bb19a4a06.css", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/pagination-toolbar-BgoV4zqc.js": "assets/pagination-toolbar-BgoV4zqc.ab5fa1be17a3.js", "assets/flag-tab-1PeNvDA9.js": "assets/flag-tab-1PeNvDA9.2fc60db57915.js", "assets/user-tab-icKcK_Qd.js": "assets/user-tab-icKcK_Qd.c29142ed5212.js", "assets/unauthorized-Cfxq6rru.js": "assets/unauthorized-Cfxq6rru.968d6e6e57bd.js", "assets/http-error-DKulXuTl.css": "assets/http-error-DKulXuTl.95e42988d5d5.css", "assets/VCheckboxBtn-DnBH3a96.js": "assets/VCheckboxBtn-DnBH3a96.876fda35b85a.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/VTable-R3X0iPjV.js": "assets/VTable-R3X0iPjV.ee07d9c2ca5f.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/VSelectionControl-B42mmzLA.js": "assets/VSelectionControl-B42mmzLA.bf64d259ddef.js", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/datetime-column-Dnxh9sRh.js": "assets/datetime-column-Dnxh9sRh.b6a92a6bcce9.js", "assets/VSlideGroup-BtfHoWCn.js": "assets/VSlideGroup-BtfHoWCn.33e2bd94e34a.js", "assets/change-password-dialog-DrIXdKUC.css": "assets/change-password-dialog-DrIXdKUC.217574b45b02.css", "assets/VTextField-D9pqgz_R.js": "assets/VTextField-D9pqgz_R.47beb9e7e547.js", "assets/reader-DORea4Al.js": "assets/reader-DORea4Al.d8e756bb0027.js", "assets/pdf-doc-BbuJd_VS.js": "assets/pdf-doc-BbuJd_VS.225d8590d020.js", "assets/admin-DJ7pIXDQ.css": "assets/admin-DJ7pIXDQ.e2a77af73ef2.css", "assets/pager-full-pdf-DcRg28qt.js": "assets/pager-full-pdf-DcRg28qt.ca9cdb9619ff.js", "assets/VExpansionPanels-CBPnoy7O.js": "assets/VExpansionPanels-CBPnoy7O.212f4cad7d78.js", "assets/confirm-dialog-Iyuhxfyi.js": "assets/confirm-dialog-Iyuhxfyi.cf28325e58b7.js", "assets/VCheckbox-CCOzQpCw.js": "assets/VCheckbox-CCOzQpCw.a65ad95bd21a.js", "assets/reader-OpKdTZ_B.css": "assets/reader-OpKdTZ_B.ebd1512b7014.css", "assets/pdf-doc-CG5-AZ2M.css": "assets/pdf-doc-CG5-AZ2M.b94aac7e3313.css", "assets/browser-Br5CorL4.css": "assets/browser-Br5CorL4.6e2a416309d5.css", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.3eee2b4822b7.json"}, "version": "1.1", "hash": "0bc634e03670"}
1
+ {"paths": {"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/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/fonts/glyphicons-halflings-regular.svg": "rest_framework/fonts/glyphicons-halflings-regular.08eda92397ae.svg", "rest_framework/fonts/glyphicons-halflings-regular.woff": "rest_framework/fonts/glyphicons-halflings-regular.fa2772327f55.woff", "rest_framework/fonts/fontawesome-webfont.ttf": "rest_framework/fonts/fontawesome-webfont.dcb26c7239d8.ttf", "rest_framework/fonts/glyphicons-halflings-regular.eot": "rest_framework/fonts/glyphicons-halflings-regular.f4769f9bdb74.eot", "rest_framework/fonts/fontawesome-webfont.svg": "rest_framework/fonts/fontawesome-webfont.83e37a11f9d7.svg", "rest_framework/fonts/glyphicons-halflings-regular.ttf": "rest_framework/fonts/glyphicons-halflings-regular.e18bbf611f2a.ttf", "rest_framework/fonts/fontawesome-webfont.eot": "rest_framework/fonts/fontawesome-webfont.8b27bc96115c.eot", "rest_framework/fonts/fontawesome-webfont.woff": "rest_framework/fonts/fontawesome-webfont.3293616ec0c6.woff", "rest_framework/fonts/glyphicons-halflings-regular.woff2": "rest_framework/fonts/glyphicons-halflings-regular.448c34a56d69.woff2", "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/img/grid.png": "rest_framework/img/grid.a4b938cf382b.png", "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/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/default.css": "rest_framework/css/default.789dfb5732d7.css", "rest_framework/css/bootstrap-theme.min.css.map": "rest_framework/css/bootstrap-theme.min.css.51806092cc05.map", "rest_framework/css/bootstrap.min.css.map": "rest_framework/css/bootstrap.min.css.cafbda9c0e9e.map", "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/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/js/coreapi-0.1.1.js": "rest_framework/js/coreapi-0.1.1.8851fb9336c9.js", "rest_framework/js/csrf.js": "rest_framework/js/csrf.455080a7b2ce.js", "rest_framework/js/jquery-3.7.1.min.js": "rest_framework/js/jquery-3.7.1.min.2c872dbe60f4.js", "rest_framework/js/bootstrap.min.js": "rest_framework/js/bootstrap.min.2f34b630ffe3.js", "img/story-arc.svg": "img/story-arc.ca10014355ef.svg", "img/logo-maskable.svg": "img/logo-maskable.8f7de7f1c6a8.svg", "img/folder.svg": "img/folder.f28936a3701d.svg", "img/missing-cover-165.webp": "img/missing-cover-165.0743171f2148.webp", "img/missing-cover.svg": "img/missing-cover.ddb038cc2c56.svg", "img/publisher.svg": "img/publisher.82d378fcd601.svg", "img/logo-32.webp": "img/logo-32.5688944495bf.webp", "img/imprint.svg": "img/imprint.7c2adebb76d6.svg", "img/logo.svg": "img/logo.0f5344a028ca.svg", "img/volume.svg": "img/volume.814e4c79461a.svg", "img/logo-maskable-180.webp": "img/logo-maskable-180.c58d966aa64e.webp", "img/series.svg": "img/series.ec8a889b8f95.svg", "pwa/offline.html": "pwa/offline.7bfaf9f94bf9.html", "assets/transition-DWVQ2EZ3.js": "assets/transition-DWVQ2EZ3.0bdfaa37b937.js", "assets/change-password-dialog-C_EOKOn9.css": "assets/change-password-dialog-C_EOKOn9.a30e68c6e303.css", "assets/VCheckbox-DLMzIII1.js": "assets/VCheckbox-DLMzIII1.1ff8fc2d9a21.js", "assets/admin-settings-button-progress-BAk-B1sR.js": "assets/admin-settings-button-progress-BAk-B1sR.cbf73c71330d.js", "assets/reader-2up6WEuE.js": "assets/reader-2up6WEuE.c56ad81d14c6.js", "assets/main-BZ73p_WW.css": "assets/main-BZ73p_WW.d529e8b3f52a.css", "assets/VTextField-X5yAw35c.js": "assets/VTextField-X5yAw35c.155e276dd747.js", "assets/VSelect-DLu8bpcs.css": "assets/VSelect-DLu8bpcs.98bdcf35411c.css", "assets/transition-5LRFTPo5.css": "assets/transition-5LRFTPo5.3d726f9bbcb0.css", "assets/VCheckboxBtn-BzoQl8XC.js": "assets/VCheckboxBtn-BzoQl8XC.094679a3624b.js", "assets/stats-tab-BlXGStge.css": "assets/stats-tab-BlXGStge.9fdb0106124d.css", "assets/datetime-column-DeCthByU.css": "assets/datetime-column-DeCthByU.1f3bf499e063.css", "assets/browser-CctlSJji.css": "assets/browser-CctlSJji.d42d796476d2.css", "assets/VCombobox-CBY8K5CP.js": "assets/VCombobox-CBY8K5CP.fcf2221a9edd.js", "assets/flag-tab-k2g6u_vi.js": "assets/flag-tab-k2g6u_vi.3e1da9318af9.js", "assets/settings-drawer-DKncO_vX.css": "assets/settings-drawer-DKncO_vX.0a2cd24cd904.css", "assets/VSelect-DqXJ23Pc.js": "assets/VSelect-DqXJ23Pc.a1360cbed050.js", "assets/admin-settings-button-progress-DUUQfVsZ.css": "assets/admin-settings-button-progress-DUUQfVsZ.2548c49a853e.css", "assets/admin-menu-B9bzD6hV.css": "assets/admin-menu-B9bzD6hV.c13b7df2ff57.css", "assets/flag-tab-CqWovuBu.css": "assets/flag-tab-CqWovuBu.4dfc6b251e85.css", "assets/stats-tab-bqSPLvTp.js": "assets/stats-tab-bqSPLvTp.05106cb03ef0.js", "assets/admin-BFvQwinN.js": "assets/admin-BFvQwinN.6cfff21f780a.js", "assets/index-CL_6g4tJ.css": "assets/index-CL_6g4tJ.523d7b3d350f.css", "assets/relation-chips-ByfWwuQc.css": "assets/relation-chips-ByfWwuQc.01269a188e01.css", "assets/pager-full-pdf-C1ZSyXfG.js": "assets/pager-full-pdf-C1ZSyXfG.f2e95b19621c.js", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/VDialog-DXQz0Ylp.css": "assets/VDialog-DXQz0Ylp.7b23d86dbd0d.css", "assets/user-tab-EsokzMCB.js": "assets/user-tab-EsokzMCB.b0acc46b56a3.js", "assets/VTable-Cbq-yJos.js": "assets/VTable-Cbq-yJos.c884706cac21.js", "assets/group-tab-DkIN1Heu.css": "assets/group-tab-DkIN1Heu.948e907b1e6b.css", "assets/VSelectionControl-CxhDNufT.js": "assets/VSelectionControl-CxhDNufT.dd7ca99567fc.js", "assets/library-tab-BpinbqAu.js": "assets/library-tab-BpinbqAu.53fa2625e727.js", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/group-tab-C6Ykf03Z.js": "assets/group-tab-C6Ykf03Z.ff0cc204013a.js", "assets/VCombobox-bwEYrXCg.css": "assets/VCombobox-bwEYrXCg.9f25a34994e2.css", "assets/unauthorized-CEGD20tR.js": "assets/unauthorized-CEGD20tR.064b0993a944.js", "assets/VSlideGroup-BtXPhMOT.css": "assets/VSlideGroup-BtXPhMOT.830f136ffd41.css", "assets/filter-ud5mPZpn.js": "assets/filter-ud5mPZpn.0f0a537959aa.js", "assets/datetime-column-D_F30OLW.js": "assets/datetime-column-D_F30OLW.09cdce0ef96e.js", "assets/VTextField-Crc3gdNh.css": "assets/VTextField-Crc3gdNh.39995ccf4d52.css", "assets/confirm-dialog-54rblwf7.css": "assets/confirm-dialog-54rblwf7.9b5915b112c0.css", "assets/VTable-Y5Sc3hJd.css": "assets/VTable-Y5Sc3hJd.c36f0a6a30cf.css", "assets/VExpansionPanels-6G1AUajL.css": "assets/VExpansionPanels-6G1AUajL.5b17872981df.css", "assets/VSlideGroup-DRbthp6q.js": "assets/VSlideGroup-DRbthp6q.7365c5542d47.js", "assets/task-tab-EGlhcKTH.css": "assets/task-tab-EGlhcKTH.478e74041f80.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/VSelectionControl-CiViEYoC.css": "assets/VSelectionControl-CiViEYoC.c77bb19a4a06.css", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/VWindowItem-CRqhVh-9.js": "assets/VWindowItem-CRqhVh-9.cd73d01e0591.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/VDialog-Db4tJYqR.js": "assets/VDialog-Db4tJYqR.e21a79a5030e.js", "assets/reader-Dd2KmdCN.css": "assets/reader-Dd2KmdCN.115d4bfe9280.css", "assets/change-password-dialog-DJtOQw7K.js": "assets/change-password-dialog-DJtOQw7K.be7fa5ec653d.js", "assets/library-tab-Cat0MAK5.css": "assets/library-tab-Cat0MAK5.5911f022188e.css", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/settings-drawer-yVoY-WCS.js": "assets/settings-drawer-yVoY-WCS.1240cc47a246.js", "assets/browser-DJnEeVHz.js": "assets/browser-DJnEeVHz.a78c47516b08.js", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/VExpansionPanels-DN4yGbOt.js": "assets/VExpansionPanels-DN4yGbOt.163e59e38865.js", "assets/index-ClGiHwWc.js": "assets/index-ClGiHwWc.0717bacf5135.js", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/http-error-Ctcws1xe.css": "assets/http-error-Ctcws1xe.cfd378a792d2.css", "assets/admin-menu-Jfmp_Yd8.js": "assets/admin-menu-Jfmp_Yd8.39fa7a18b3b4.js", "assets/confirm-dialog-CME4gKSZ.js": "assets/confirm-dialog-CME4gKSZ.1606233e784c.js", "assets/pdf-doc-b-GyNR6z.js": "assets/pdf-doc-b-GyNR6z.c9d18f0d36ed.js", "assets/unauthorized-DyojW2ic.css": "assets/unauthorized-DyojW2ic.feefa7628a23.css", "assets/http-error-DQBHK8v5.js": "assets/http-error-DQBHK8v5.aea50b1327fd.js", "assets/admin-DJ7pIXDQ.css": "assets/admin-DJ7pIXDQ.e2a77af73ef2.css", "assets/pagination-toolbar-Cx_9nh6D.css": "assets/pagination-toolbar-Cx_9nh6D.546121fa7a0d.css", "assets/VRadioGroup-D2-PWEfs.js": "assets/VRadioGroup-D2-PWEfs.ce7644863c25.js", "assets/pagination-toolbar-Diad0EdD.js": "assets/pagination-toolbar-Diad0EdD.140911bf86af.js", "assets/relation-chips-piYv1IcD.js": "assets/relation-chips-piYv1IcD.f8a2ae79de89.js", "assets/main-BVKrDunc.js": "assets/main-BVKrDunc.1c6f8cdc3afb.js", "assets/task-tab-DWPKaGPT.js": "assets/task-tab-DWPKaGPT.da4df28dde5c.js", "assets/pdf-doc-CG5-AZ2M.css": "assets/pdf-doc-CG5-AZ2M.b94aac7e3313.css", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.4a38de3db1c5.json"}, "version": "1.1", "hash": "3d42fa5855cb"}
codex/urls/api/browser.py CHANGED
@@ -8,6 +8,7 @@ from codex.views.bookmark import BookmarkView
8
8
  from codex.views.browser.browser import BrowserView
9
9
  from codex.views.browser.choices import BrowserChoicesAvailableView, BrowserChoicesView
10
10
  from codex.views.browser.cover import CoverView
11
+ from codex.views.browser.download import GroupDownloadView
11
12
  from codex.views.browser.metadata.metadata import MetadataView
12
13
  from codex.views.browser.settings import BrowserSettingsView
13
14
 
@@ -55,4 +56,12 @@ urlpatterns = [
55
56
  cache_control(max_age=COVER_MAX_AGE, public=True)(CoverView.as_view()),
56
57
  name="cover",
57
58
  ),
59
+ #
60
+ #
61
+ # Download
62
+ path(
63
+ "<int_list:pks>/download/<str:filename>",
64
+ GroupDownloadView.as_view(),
65
+ name="download",
66
+ ),
58
67
  ]
codex/urls/api/reader.py CHANGED
@@ -11,10 +11,6 @@ from codex.views.reader.settings import ReaderSettingsView
11
11
 
12
12
  app_name = "issue"
13
13
  urlpatterns = [
14
- #
15
- #
16
- # Comic
17
- path("<int:pk>/download/<str:filename>", DownloadView.as_view(), name="download"),
18
14
  #
19
15
  #
20
16
  # Reader
@@ -25,4 +21,12 @@ urlpatterns = [
25
21
  name="page",
26
22
  ),
27
23
  path("settings", ReaderSettingsView.as_view(), name="settings"),
24
+ #
25
+ #
26
+ # Download
27
+ path(
28
+ "<int:pk>/download/<str:filename>",
29
+ DownloadView.as_view(),
30
+ name="download",
31
+ ),
28
32
  ]
codex/util.py CHANGED
@@ -1,5 +1,7 @@
1
1
  """Utility functions."""
2
2
 
3
+ from collections.abc import Mapping
4
+
3
5
 
4
6
  def max_none(*args):
5
7
  """None aware math.max."""
@@ -10,3 +12,12 @@ def max_none(*args):
10
12
  elif arg is not None:
11
13
  max_arg = max(max_arg, arg)
12
14
  return max_arg
15
+
16
+
17
+ def mapping_to_dict(data):
18
+ """Convert nested Mapping objects to dicts."""
19
+ if isinstance(data, Mapping):
20
+ return {key: mapping_to_dict(value) for key, value in data.items()}
21
+ if isinstance(data, list | tuple | frozenset | set):
22
+ return [mapping_to_dict(item) for item in data]
23
+ return data
@@ -73,8 +73,7 @@ _TASK_MAP = MappingProxyType(
73
73
  "db_vacuum": JanitorVacuumTask(),
74
74
  "db_backup": JanitorBackupTask(),
75
75
  "db_foreign_key_check": JanitorForeignKeyCheck(),
76
- "db_integrity_check_quick": JanitorIntegrityCheck(),
77
- "db_integrity_check_long": JanitorIntegrityCheck(True),
76
+ "db_integrity_check": JanitorIntegrityCheck(),
78
77
  "db_fts_integrity_check": JanitorFTSIntegrityCheck(),
79
78
  "db_fts_rebuild": JanitorFTSRebuildTask(),
80
79
  "watchdog_sync": WatchdogSyncTask(),
codex/views/bookmark.py CHANGED
@@ -66,5 +66,5 @@ class BookmarkView(AuthFilterGenericAPIView, BookmarkBaseView, BookmarkUpdate):
66
66
  pks = self.kwargs.get("pks")
67
67
  comic_filter = {rel: pks}
68
68
 
69
- self.update_bookmarks(auth_filter, comic_filter, updates)
69
+ self.update_bookmarks(auth_filter, comic_filter, updates, LOG)
70
70
  return Response()
@@ -3,6 +3,7 @@
3
3
  from types import MappingProxyType
4
4
 
5
5
  from django.db.models import (
6
+ F,
6
7
  Value,
7
8
  )
8
9
  from django.db.models.aggregates import Count
@@ -48,6 +49,16 @@ class BrowserAnnotateCardView(BrowserAnnotateBookmarkView):
48
49
  value = "c" if qs.model is Comic else self.model_group # type: ignore
49
50
  return qs.annotate(group=Value(value, CharField(max_length=1)))
50
51
 
52
+ def _annotate_file_name(self, qs):
53
+ """Annotate the file name for folder view."""
54
+ if qs.model is not Comic:
55
+ return qs
56
+ if self.order_key == "filename":
57
+ file_name = F("filename")
58
+ else:
59
+ file_name = self.get_filename_func(qs.model)
60
+ return qs.annotate(file_name=file_name)
61
+
51
62
  def annotate_card_aggregates(self, qs):
52
63
  """Annotate aggregates that appear the browser card."""
53
64
  if qs.model is Comic:
@@ -55,6 +66,7 @@ class BrowserAnnotateCardView(BrowserAnnotateBookmarkView):
55
66
  qs = self.annotate_order_value(qs)
56
67
  qs = self._annotate_group(qs)
57
68
  qs = self.annotate_group_names(qs)
69
+ qs = self._annotate_file_name(qs)
58
70
  qs = self._annotate_child_count(qs)
59
71
  qs = self.annotate_bookmarks(qs)
60
72
  qs = self.annotate_progress(qs)
@@ -123,6 +123,17 @@ class BrowserAnnotateOrderView(BrowserOrderByView, SharedAnnotationsMixin):
123
123
  self._comic_sort_names = tuple(sort_name_annotations.keys())
124
124
  return qs
125
125
 
126
+ def get_filename_func(self, model):
127
+ """Get the filename creation function."""
128
+ prefix = "" if model == Comic else self.rel_prefix
129
+ path_rel = prefix + "path"
130
+
131
+ return Right(
132
+ path_rel,
133
+ StrIndex(Reverse(F(path_rel)), Value(sep)) - 1, # type: ignore
134
+ output_field=CharField(),
135
+ )
136
+
126
137
  def _alias_filename(self, qs):
127
138
  """Calculate filename from path in the db."""
128
139
  if self.order_key != "filename":
@@ -130,15 +141,8 @@ class BrowserAnnotateOrderView(BrowserOrderByView, SharedAnnotationsMixin):
130
141
  if qs.model is Folder:
131
142
  filename = F("name")
132
143
  else:
133
- prefix = "" if qs.model == Comic else self.rel_prefix
134
- path_rel = prefix + "path"
135
- filename = self.order_agg_func(
136
- Right(
137
- path_rel,
138
- StrIndex(Reverse(F(path_rel)), Value(sep)) - 1, # type: ignore
139
- output_field=CharField(),
140
- )
141
- )
144
+ filename_func = self.get_filename_func(qs.model)
145
+ filename = self.order_agg_func(filename_func)
142
146
  return qs.alias(filename=filename)
143
147
 
144
148
  def _alias_story_arc_number(self, qs):
@@ -0,0 +1,64 @@
1
+ """Download a group of comics in a zipfile."""
2
+
3
+ from django.http import HttpResponseBadRequest
4
+ from django.http.response import FileResponse, Http404
5
+ from drf_spectacular.types import OpenApiTypes
6
+ from drf_spectacular.utils import extend_schema
7
+ from zipstream import ZipStream
8
+
9
+ from codex.logger.logging import get_logger
10
+ from codex.views.browser.filters.filter import BrowserFilterView
11
+
12
+ LOG = get_logger()
13
+
14
+
15
+ class GroupDownloadView(BrowserFilterView):
16
+ """Return a group of comic archives as a streaming zipfile."""
17
+
18
+ content_type = "application/zip"
19
+ AS_ATTACHMENT = True
20
+ TARGET = "download"
21
+
22
+ def get_object(self):
23
+ """Get comic paths for a browse group."""
24
+ group = self.kwargs.get("group")
25
+ pks = self.kwargs.get("pks")
26
+ if not self.model:
27
+ reason = f"Could not find model for group {group}"
28
+ return HttpResponseBadRequest(reason)
29
+
30
+ try:
31
+ qs = self.get_filtered_queryset(self.model, group=group, pks=pks)
32
+ path_rel = self.rel_prefix + "path"
33
+ paths = qs.values_list(path_rel, flat=True)
34
+ except Exception as exc:
35
+ LOG.warning(f"Error with download query for {group}:{pks} {exc}")
36
+ raise
37
+
38
+ if not paths:
39
+ reason = f"Comics from {group}:{pks} not not found."
40
+ raise Http404(reason)
41
+
42
+ return sorted(set(paths))
43
+
44
+ @extend_schema(responses={(200, content_type): OpenApiTypes.BINARY})
45
+ def get(self, *_args, **kwargs):
46
+ """Stream a zip archive of many comics."""
47
+ paths = self.get_object()
48
+
49
+ zs = ZipStream(sized=True)
50
+ for path in paths:
51
+ zs.add_path(path)
52
+ download_file = zs
53
+
54
+ filename = kwargs.get("filename")
55
+ if not filename:
56
+ pks = self.kwargs.get("pks")
57
+ filename = f"{self.model.__name__} {pks} Comics.zip" # type: ignore
58
+
59
+ return FileResponse(
60
+ download_file,
61
+ as_attachment=self.AS_ATTACHMENT,
62
+ content_type=self.content_type,
63
+ filename=filename,
64
+ )
@@ -27,6 +27,8 @@ class GroupFilterView(BrowserParamsView):
27
27
  elif target in _PK_REL_TARGETS or page_mtime:
28
28
  # metadata, mtime, browser.page_mtime
29
29
  rel = "pk"
30
+ elif target == "download":
31
+ rel = "comic__folders" if group == "f" else "pk"
30
32
  else:
31
33
  # browser.group, opds
32
34
  rel = GROUP_RELATION[group]
@@ -1,14 +1,16 @@
1
1
  """Browser Settings and URL Validation."""
2
2
 
3
+ from collections.abc import Mapping
3
4
  from copy import deepcopy
4
5
  from types import MappingProxyType
5
6
 
6
7
  from rest_framework.exceptions import NotFound
7
8
 
8
- from codex.choices import DEFAULT_BROWSER_ROUTE, mapping_to_dict
9
+ from codex.choices import DEFAULT_BROWSER_ROUTE
9
10
  from codex.exceptions import SeeOtherRedirectError
10
11
  from codex.logger.logging import get_logger
11
12
  from codex.models.groups import BrowserGroupModel
13
+ from codex.util import mapping_to_dict
12
14
  from codex.views.browser.filters.search.parse import SearchFilterView
13
15
  from codex.views.const import (
14
16
  COMIC_GROUP,
@@ -67,12 +69,14 @@ class BrowserValidateView(SearchFilterView):
67
69
  self._rel_prefix = self.get_rel_prefix(self.model)
68
70
  return self._rel_prefix
69
71
 
70
- def raise_redirect(self, reason, route_mask=None, settings_mask=None):
72
+ def raise_redirect(
73
+ self, reason, route_mask=None, settings_mask: Mapping | None = None
74
+ ):
71
75
  """Redirect the client to a valid group url."""
72
76
  route = mapping_to_dict(self.DEFAULT_ROUTE)
73
77
  if route_mask:
74
78
  route["params"].update(route_mask) # type: ignore
75
- settings = deepcopy(dict(self.params))
79
+ settings: dict = deepcopy(mapping_to_dict(self.params)) # type: ignore
76
80
  if settings_mask:
77
81
  settings.update(settings_mask)
78
82
  detail = {"route": route, "settings": settings, "reason": reason}
codex/views/download.py CHANGED
@@ -6,7 +6,7 @@ from django.http import FileResponse, Http404
6
6
  from drf_spectacular.types import OpenApiTypes
7
7
  from drf_spectacular.utils import extend_schema
8
8
 
9
- from codex.models import Comic
9
+ from codex.models.comic import Comic
10
10
  from codex.views.auth import AuthFilterAPIView
11
11
 
12
12
 
@@ -15,7 +15,7 @@ class DownloadView(AuthFilterAPIView):
15
15
 
16
16
  content_type = "application/vnd.comicbook+zip"
17
17
 
18
- _AS_ATTACHMENT = True
18
+ AS_ATTACHMENT = True
19
19
 
20
20
  @extend_schema(responses={(200, content_type): OpenApiTypes.BINARY})
21
21
  def get(self, *_args, **kwargs):
@@ -45,13 +45,13 @@ class DownloadView(AuthFilterAPIView):
45
45
  filename = comic.get_filename()
46
46
  return FileResponse(
47
47
  comic_file,
48
- as_attachment=self._AS_ATTACHMENT,
48
+ as_attachment=self.AS_ATTACHMENT,
49
49
  content_type=content_type,
50
50
  filename=filename,
51
51
  )
52
52
 
53
53
 
54
54
  class FileView(DownloadView):
55
- """View a comic in the browser."""
55
+ """View a single comic in the browser."""
56
56
 
57
- _AS_ATTACHMENT = False
57
+ AS_ATTACHMENT = False
@@ -69,21 +69,26 @@ class ReaderPageView(BookmarkBaseView):
69
69
 
70
70
  def _get_page_image(self):
71
71
  """Get the image data and content type."""
72
+ # Get comic - Distinct is important
72
73
  group_acl_filter = self.get_group_acl_filter(Comic, self.request.user)
74
+ qs = Comic.objects.filter(group_acl_filter).only("path", "file_type").distinct()
73
75
  pk = self.kwargs.get("pk")
74
- comic = Comic.objects.filter(group_acl_filter).only("path").get(pk=pk)
76
+ comic = qs.get(pk=pk)
77
+
78
+ # page_image
75
79
  page = self.kwargs.get("page")
76
80
  to_pixmap = self.request.GET.get("pixmap", "").lower() not in FALSY
77
- if comic.file_type == FileType.PDF.value and not to_pixmap:
78
- content_type = _PDF_MIME_TYPE
79
- else:
80
- content_type = self.content_type
81
-
82
81
  with Comicbox(comic.path) as cb:
83
82
  page_image = cb.get_page_by_index(page, to_pixmap=to_pixmap)
84
83
  if not page_image:
85
84
  page_image = b""
86
85
 
86
+ # content type
87
+ if comic.file_type == FileType.PDF.value and not to_pixmap:
88
+ content_type = _PDF_MIME_TYPE
89
+ else:
90
+ content_type = self.content_type
91
+
87
92
  return page_image, content_type
88
93
 
89
94
  @extend_schema(
@@ -3,12 +3,12 @@
3
3
  from types import MappingProxyType
4
4
  from typing import Any
5
5
 
6
- from codex.choices import mapping_to_dict
7
6
  from codex.logger.logging import get_logger
8
7
  from codex.models import Comic
9
8
  from codex.serializers.reader import (
10
9
  ReaderViewInputSerializer,
11
10
  )
11
+ from codex.util import mapping_to_dict
12
12
  from codex.views.const import FOLDER_GROUP, GROUP_RELATION, STORY_ARC_GROUP
13
13
  from codex.views.session import SessionView
14
14
  from codex.views.util import reparse_json_query_params
codex/views/session.py CHANGED
@@ -4,8 +4,9 @@ from abc import ABC
4
4
  from copy import deepcopy
5
5
  from types import MappingProxyType
6
6
 
7
- from codex.choices import BROWSER_DEFAULTS, READER_DEFAULTS, mapping_to_dict
7
+ from codex.choices import BROWSER_DEFAULTS, READER_DEFAULTS
8
8
  from codex.logger.logging import get_logger
9
+ from codex.util import mapping_to_dict
9
10
  from codex.views.auth import AuthFilterGenericAPIView
10
11
  from codex.views.util import pop_name
11
12
 
codex/views/timezone.py CHANGED
@@ -4,7 +4,6 @@ from drf_spectacular.utils import extend_schema
4
4
  from rest_framework.response import Response
5
5
 
6
6
  from codex.logger.logging import get_logger
7
- from codex.models import UserActive
8
7
  from codex.serializers.auth import TimezoneSerializer
9
8
  from codex.serializers.mixins import OKSerializer
10
9
  from codex.views.auth import AuthGenericAPIView
@@ -26,12 +25,6 @@ class TimezoneView(AuthGenericAPIView):
26
25
  session["django_timezone"] = django_timezone
27
26
  session.save()
28
27
 
29
- def _update_user_active(self):
30
- """Update user activity."""
31
- user = self.request.user
32
- if user and user.is_authenticated:
33
- UserActive.objects.update_or_create(user=user)
34
-
35
28
  @extend_schema(request=input_serializer_class)
36
29
  def put(self, *args, **kwargs):
37
30
  """Get the user info for the current user."""
@@ -39,16 +32,11 @@ class TimezoneView(AuthGenericAPIView):
39
32
  serializer = self.input_serializer_class(data=data)
40
33
  serializer.is_valid(raise_exception=True)
41
34
  try:
42
- self._save_timezone(serializer.validated_data.get("timezone")) # type: ignore
35
+ timezone = serializer.validated_data.get("timezone") # type: ignore
36
+ self._save_timezone(timezone)
43
37
  except Exception as exc:
44
38
  reason = f"update user timezone {exc}"
45
39
  LOG.warning(reason)
46
40
 
47
- try:
48
- self._update_user_active()
49
- except Exception as exc:
50
- reason = f"update user activity {exc}"
51
- LOG.warning(reason)
52
-
53
41
  serializer = self.get_serializer()
54
42
  return Response(serializer.data)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codex
3
- Version: 1.7.0a2
3
+ Version: 1.7.2
4
4
  Summary: A comic archive web server.
5
5
  Home-page: https://github.com/ajslater/codex
6
6
  License: GPL-3.0-only
@@ -23,13 +23,13 @@ Classifier: Programming Language :: Python :: 3.12
23
23
  Classifier: Programming Language :: Python :: 3 :: Only
24
24
  Classifier: Topic :: Internet :: WWW/HTTP
25
25
  Classifier: Topic :: Multimedia :: Graphics :: Viewers
26
- Requires-Dist: Pillow (>=10.0.0,<11.0.0)
26
+ Requires-Dist: Pillow (>=11.0.0,<12.0.0)
27
27
  Requires-Dist: aioprocessing (>=2.0.1,<3.0.0)
28
28
  Requires-Dist: ansicolors (>=1.1,<2.0)
29
29
  Requires-Dist: bidict (>=0.23.1,<0.24.0)
30
30
  Requires-Dist: case-converter (>=1.1.0,<2.0.0)
31
31
  Requires-Dist: channels (>=4.0.0,<5.0.0)
32
- Requires-Dist: comicbox[pdf] (>=1.2.0,<2.0.0)
32
+ Requires-Dist: comicbox[pdf] (>=1.2.1,<2.0.0)
33
33
  Requires-Dist: dateparser (>=1.2.0,<2.0.0)
34
34
  Requires-Dist: django (>=5.1.0,<6.0.0)
35
35
  Requires-Dist: django-cachalot (>=2.6.3,<3.0.0)
@@ -52,6 +52,7 @@ Requires-Dist: versio (>=0.5.0,<0.6.0)
52
52
  Requires-Dist: watchdog (>=5.0.2,<6.0.0)
53
53
  Requires-Dist: websocket_client (>=1.2,<2.0)
54
54
  Requires-Dist: whitenoise[brotli] (>=6.0,<7.0)
55
+ Requires-Dist: zipstream-ng (>=1.8.0,<2.0.0)
55
56
  Project-URL: Documentation, https://github.com/ajslater/codex
56
57
  Project-URL: Docker Image, https://hub.docker.com/r/ajslater/codex
57
58
  Project-URL: News, https://github.com/ajslater/codex/blob/main/NEWS.md
@@ -338,10 +339,7 @@ index, a Django cache and comic book cover thumbnails.
338
339
  when codex starts.
339
340
  - `CODEX_FIX_FOREIGN_KEYS=1` will check for and try to repair illegal foreign
340
341
  keys on startup.
341
- - `CODEX_INTEGRITY_CHECK=1` will perform a quick full database integrity check
342
- on startup.
343
- - `CODEX_INTEGRITY_CHECK=full` will perform a more thorough database integrity
344
- check on startup.
342
+ - `CODEX_INTEGRITY_CHECK=1` will perform database integrity check on startup.
345
343
  - `CODEX_FTS_INTEGRITY_CHECK=1` will perform an integrity check on the full text
346
344
  search index.
347
345
  - `CODEX_FTS_REBUILD=1` will rebuild the full text search index.