codex 1.6.0a11__py3-none-any.whl → 1.6.0rc0__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 (395) hide show
  1. codex/librarian/covers/create.py +21 -16
  2. codex/serializers/browser/choices.py +21 -54
  3. codex/serializers/browser/filters.py +30 -36
  4. codex/serializers/browser/mixins.py +2 -2
  5. codex/serializers/fields.py +32 -65
  6. codex/serializers/opds/v2.py +4 -6
  7. codex/static_root/assets/{VCheckbox-BwDyxhU7.831b00df198a.js → VCheckbox-BK0IPHyB.c85e2f87e16a.js} +1 -1
  8. codex/static_root/assets/VCheckbox-BK0IPHyB.c85e2f87e16a.js.br +0 -0
  9. codex/static_root/assets/VCheckbox-BK0IPHyB.c85e2f87e16a.js.gz +0 -0
  10. codex/static_root/assets/{VCheckbox-BwDyxhU7.js → VCheckbox-BK0IPHyB.js} +1 -1
  11. codex/static_root/assets/VCheckbox-BK0IPHyB.js.br +0 -0
  12. codex/static_root/assets/VCheckbox-BK0IPHyB.js.gz +0 -0
  13. codex/static_root/assets/{VCheckboxBtn-DVq5lDK4.5e6464c8d80a.js → VCheckboxBtn-DbVzgq3g.c2e2e2b16db0.js} +1 -1
  14. codex/static_root/assets/VCheckboxBtn-DbVzgq3g.c2e2e2b16db0.js.br +0 -0
  15. codex/static_root/assets/VCheckboxBtn-DbVzgq3g.c2e2e2b16db0.js.gz +0 -0
  16. codex/static_root/assets/{VCheckboxBtn-DVq5lDK4.js → VCheckboxBtn-DbVzgq3g.js} +1 -1
  17. codex/static_root/assets/VCheckboxBtn-DbVzgq3g.js.br +0 -0
  18. codex/static_root/assets/VCheckboxBtn-DbVzgq3g.js.gz +0 -0
  19. codex/static_root/assets/{VCombobox-BASCOy0n.7801caa5e192.js → VCombobox-DRNxfPeq.db51c60468b3.js} +1 -1
  20. codex/static_root/assets/VCombobox-DRNxfPeq.db51c60468b3.js.br +0 -0
  21. codex/static_root/assets/VCombobox-DRNxfPeq.db51c60468b3.js.gz +0 -0
  22. codex/static_root/assets/{VCombobox-BASCOy0n.js → VCombobox-DRNxfPeq.js} +1 -1
  23. codex/static_root/assets/VCombobox-DRNxfPeq.js.br +0 -0
  24. codex/static_root/assets/VCombobox-DRNxfPeq.js.gz +0 -0
  25. codex/static_root/assets/{VDialog-DnbL_v_u.0bd289bda8e6.js → VDialog-xrkpB5lc.7d3fa671e281.js} +1 -1
  26. codex/static_root/assets/VDialog-xrkpB5lc.7d3fa671e281.js.br +0 -0
  27. codex/static_root/assets/VDialog-xrkpB5lc.7d3fa671e281.js.gz +0 -0
  28. codex/static_root/assets/{VDialog-DnbL_v_u.js → VDialog-xrkpB5lc.js} +1 -1
  29. codex/static_root/assets/VDialog-xrkpB5lc.js.br +0 -0
  30. codex/static_root/assets/VDialog-xrkpB5lc.js.gz +0 -0
  31. codex/static_root/assets/{VExpansionPanels-B8nz8lN5.56e5adec4f62.js → VExpansionPanels-dtwXHEmN.b8444e54d145.js} +1 -1
  32. codex/static_root/assets/VExpansionPanels-dtwXHEmN.b8444e54d145.js.br +0 -0
  33. codex/static_root/assets/VExpansionPanels-dtwXHEmN.b8444e54d145.js.gz +0 -0
  34. codex/static_root/assets/{VExpansionPanels-B8nz8lN5.js → VExpansionPanels-dtwXHEmN.js} +1 -1
  35. codex/static_root/assets/VExpansionPanels-dtwXHEmN.js.br +0 -0
  36. codex/static_root/assets/VExpansionPanels-dtwXHEmN.js.gz +0 -0
  37. codex/static_root/assets/{VRadioGroup-BgwJ_b94.55f84f3429b9.js → VRadioGroup-DUhU0d2J.62d19103a0cc.js} +1 -1
  38. codex/static_root/assets/VRadioGroup-DUhU0d2J.62d19103a0cc.js.br +0 -0
  39. codex/static_root/assets/VRadioGroup-DUhU0d2J.62d19103a0cc.js.gz +0 -0
  40. codex/static_root/assets/{VRadioGroup-BgwJ_b94.js → VRadioGroup-DUhU0d2J.js} +1 -1
  41. codex/static_root/assets/VRadioGroup-DUhU0d2J.js.br +0 -0
  42. codex/static_root/assets/VRadioGroup-DUhU0d2J.js.gz +0 -0
  43. codex/static_root/assets/{VSelect-BoKpXxwe.a88f065dfe3b.js → VSelect-C768JtGg.a9c65d26248e.js} +1 -1
  44. codex/static_root/assets/VSelect-C768JtGg.a9c65d26248e.js.br +0 -0
  45. codex/static_root/assets/VSelect-C768JtGg.a9c65d26248e.js.gz +0 -0
  46. codex/static_root/assets/{VSelect-BoKpXxwe.js → VSelect-C768JtGg.js} +1 -1
  47. codex/static_root/assets/VSelect-C768JtGg.js.br +0 -0
  48. codex/static_root/assets/VSelect-C768JtGg.js.gz +0 -0
  49. codex/static_root/assets/{VSelectionControl-BXJGg8No.js → VSelectionControl-DocEa9g1.52f73fdce6d1.js} +1 -1
  50. codex/static_root/assets/VSelectionControl-DocEa9g1.52f73fdce6d1.js.br +0 -0
  51. codex/static_root/assets/VSelectionControl-DocEa9g1.52f73fdce6d1.js.gz +0 -0
  52. codex/static_root/assets/{VSelectionControl-BXJGg8No.0cb36d941d2a.js → VSelectionControl-DocEa9g1.js} +1 -1
  53. codex/static_root/assets/VSelectionControl-DocEa9g1.js.br +0 -0
  54. codex/static_root/assets/VSelectionControl-DocEa9g1.js.gz +0 -0
  55. codex/static_root/assets/{VSlideGroup-C2TL5E34.775adeb5a973.js → VSlideGroup-w7zv3wT_.647c2d1d6877.js} +1 -1
  56. codex/static_root/assets/VSlideGroup-w7zv3wT_.647c2d1d6877.js.br +0 -0
  57. codex/static_root/assets/VSlideGroup-w7zv3wT_.647c2d1d6877.js.gz +0 -0
  58. codex/static_root/assets/{VSlideGroup-C2TL5E34.js → VSlideGroup-w7zv3wT_.js} +1 -1
  59. codex/static_root/assets/VSlideGroup-w7zv3wT_.js.br +0 -0
  60. codex/static_root/assets/VSlideGroup-w7zv3wT_.js.gz +0 -0
  61. codex/static_root/assets/{VTable-C0FptljX.e4840b635c6e.js → VTable-Bm3ZZq7k.126b28481416.js} +1 -1
  62. codex/static_root/assets/VTable-Bm3ZZq7k.126b28481416.js.br +0 -0
  63. codex/static_root/assets/VTable-Bm3ZZq7k.126b28481416.js.gz +0 -0
  64. codex/static_root/assets/{VTable-C0FptljX.js → VTable-Bm3ZZq7k.js} +1 -1
  65. codex/static_root/assets/VTable-Bm3ZZq7k.js.br +0 -0
  66. codex/static_root/assets/VTable-Bm3ZZq7k.js.gz +0 -0
  67. codex/static_root/assets/{VTextField-Aw8nKhY6.428732ac22d7.js → VTextField-DuOs5usq.b1fe3e9e431d.js} +1 -1
  68. codex/static_root/assets/VTextField-DuOs5usq.b1fe3e9e431d.js.br +0 -0
  69. codex/static_root/assets/VTextField-DuOs5usq.b1fe3e9e431d.js.gz +0 -0
  70. codex/static_root/assets/{VTextField-Aw8nKhY6.js → VTextField-DuOs5usq.js} +1 -1
  71. codex/static_root/assets/VTextField-DuOs5usq.js.br +0 -0
  72. codex/static_root/assets/VTextField-DuOs5usq.js.gz +0 -0
  73. codex/static_root/assets/{VWindowItem-D9j_u9MX.828acf3dee55.js → VWindowItem-C3SaotR1.05f0f97e8897.js} +1 -1
  74. codex/static_root/assets/VWindowItem-C3SaotR1.05f0f97e8897.js.br +0 -0
  75. codex/static_root/assets/VWindowItem-C3SaotR1.05f0f97e8897.js.gz +0 -0
  76. codex/static_root/assets/{VWindowItem-D9j_u9MX.js → VWindowItem-C3SaotR1.js} +1 -1
  77. codex/static_root/assets/VWindowItem-C3SaotR1.js.br +0 -0
  78. codex/static_root/assets/VWindowItem-C3SaotR1.js.gz +0 -0
  79. codex/static_root/assets/admin-37fN97_d.076ef24ac3c3.js +1 -0
  80. codex/static_root/assets/admin-37fN97_d.076ef24ac3c3.js.br +0 -0
  81. codex/static_root/assets/admin-37fN97_d.076ef24ac3c3.js.gz +0 -0
  82. codex/static_root/assets/admin-37fN97_d.js +1 -0
  83. codex/static_root/assets/admin-37fN97_d.js.br +0 -0
  84. codex/static_root/assets/admin-37fN97_d.js.gz +0 -0
  85. codex/static_root/assets/{admin-drawer-panel-Dmn4wEY3.af7e8490f0e3.js → admin-drawer-panel-CFthvbMb.11b1e9f05875.js} +2 -2
  86. codex/static_root/assets/admin-drawer-panel-CFthvbMb.11b1e9f05875.js.br +0 -0
  87. codex/static_root/assets/admin-drawer-panel-CFthvbMb.11b1e9f05875.js.gz +0 -0
  88. codex/static_root/assets/{admin-drawer-panel-Dmn4wEY3.js → admin-drawer-panel-CFthvbMb.js} +2 -2
  89. codex/static_root/assets/admin-drawer-panel-CFthvbMb.js.br +0 -0
  90. codex/static_root/assets/admin-drawer-panel-CFthvbMb.js.gz +0 -0
  91. codex/static_root/assets/browser-BlycPHgZ.5842145b0e63.css +1 -0
  92. codex/static_root/assets/browser-BlycPHgZ.5842145b0e63.css.br +0 -0
  93. codex/static_root/assets/browser-BlycPHgZ.5842145b0e63.css.gz +0 -0
  94. codex/static_root/assets/browser-BlycPHgZ.css +1 -0
  95. codex/static_root/assets/browser-BlycPHgZ.css.br +0 -0
  96. codex/static_root/assets/browser-BlycPHgZ.css.gz +0 -0
  97. codex/static_root/assets/browser-CA_2XCnV.fb1d5c95e960.js +1 -0
  98. codex/static_root/assets/browser-CA_2XCnV.fb1d5c95e960.js.br +0 -0
  99. codex/static_root/assets/browser-CA_2XCnV.fb1d5c95e960.js.gz +0 -0
  100. codex/static_root/assets/browser-CA_2XCnV.js +1 -0
  101. codex/static_root/assets/browser-CA_2XCnV.js.br +0 -0
  102. codex/static_root/assets/browser-CA_2XCnV.js.gz +0 -0
  103. codex/static_root/assets/{change-password-dialog-Cc1e755p.b29d200537bf.js → change-password-dialog-CdCjAlM3.39002922098f.js} +1 -1
  104. codex/static_root/assets/change-password-dialog-CdCjAlM3.39002922098f.js.br +0 -0
  105. codex/static_root/assets/change-password-dialog-CdCjAlM3.39002922098f.js.gz +0 -0
  106. codex/static_root/assets/{change-password-dialog-Cc1e755p.js → change-password-dialog-CdCjAlM3.js} +1 -1
  107. codex/static_root/assets/change-password-dialog-CdCjAlM3.js.br +0 -0
  108. codex/static_root/assets/change-password-dialog-CdCjAlM3.js.gz +0 -0
  109. codex/static_root/assets/{confirm-dialog-Cyr7HAAz.8ab1d8b6241a.js → confirm-dialog-C-TnajF6.839491684c0e.js} +1 -1
  110. codex/static_root/assets/confirm-dialog-C-TnajF6.839491684c0e.js.br +0 -0
  111. codex/static_root/assets/confirm-dialog-C-TnajF6.839491684c0e.js.gz +0 -0
  112. codex/static_root/assets/{confirm-dialog-Cyr7HAAz.js → confirm-dialog-C-TnajF6.js} +1 -1
  113. codex/static_root/assets/confirm-dialog-C-TnajF6.js.br +0 -0
  114. codex/static_root/assets/confirm-dialog-C-TnajF6.js.gz +0 -0
  115. codex/static_root/assets/{datetime-column-Cqi99Ze-.49d0ce340183.js → datetime-column-DwrIUx_h.f913e4e33aab.js} +1 -1
  116. codex/static_root/assets/datetime-column-DwrIUx_h.f913e4e33aab.js.br +0 -0
  117. codex/static_root/assets/datetime-column-DwrIUx_h.f913e4e33aab.js.gz +0 -0
  118. codex/static_root/assets/{datetime-column-Cqi99Ze-.js → datetime-column-DwrIUx_h.js} +1 -1
  119. codex/static_root/assets/datetime-column-DwrIUx_h.js.br +0 -0
  120. codex/static_root/assets/datetime-column-DwrIUx_h.js.gz +0 -0
  121. codex/static_root/assets/{filter-CuocBoS2.885d1b8d44cc.js → filter-Tm2kUX1m.efab6f87b66b.js} +1 -1
  122. codex/static_root/assets/filter-Tm2kUX1m.efab6f87b66b.js.br +0 -0
  123. codex/static_root/assets/filter-Tm2kUX1m.efab6f87b66b.js.gz +0 -0
  124. codex/static_root/assets/{filter-CuocBoS2.js → filter-Tm2kUX1m.js} +1 -1
  125. codex/static_root/assets/filter-Tm2kUX1m.js.br +0 -0
  126. codex/static_root/assets/filter-Tm2kUX1m.js.gz +0 -0
  127. codex/static_root/assets/{flag-tab-B5dRCBAt.e858f7ec9f55.js → flag-tab-CEyOjZFp.628af77cb04b.js} +1 -1
  128. codex/static_root/assets/flag-tab-CEyOjZFp.628af77cb04b.js.br +0 -0
  129. codex/static_root/assets/flag-tab-CEyOjZFp.628af77cb04b.js.gz +0 -0
  130. codex/static_root/assets/{flag-tab-B5dRCBAt.js → flag-tab-CEyOjZFp.js} +1 -1
  131. codex/static_root/assets/flag-tab-CEyOjZFp.js.br +0 -0
  132. codex/static_root/assets/flag-tab-CEyOjZFp.js.gz +0 -0
  133. codex/static_root/assets/{group-tab-_nT2o04v.c06032b254dc.js → group-tab-CBqhy8zy.75497868a808.js} +1 -1
  134. codex/static_root/assets/group-tab-CBqhy8zy.75497868a808.js.br +0 -0
  135. codex/static_root/assets/group-tab-CBqhy8zy.75497868a808.js.gz +0 -0
  136. codex/static_root/assets/{group-tab-_nT2o04v.js → group-tab-CBqhy8zy.js} +1 -1
  137. codex/static_root/assets/group-tab-CBqhy8zy.js.br +0 -0
  138. codex/static_root/assets/group-tab-CBqhy8zy.js.gz +0 -0
  139. codex/static_root/assets/{http-error-CXo9qLiW.d5a337f399c9.js → http-error-MPj9N9no.5efe701ebf21.js} +1 -1
  140. codex/static_root/assets/http-error-MPj9N9no.5efe701ebf21.js.br +0 -0
  141. codex/static_root/assets/http-error-MPj9N9no.5efe701ebf21.js.gz +0 -0
  142. codex/static_root/assets/{http-error-CXo9qLiW.js → http-error-MPj9N9no.js} +1 -1
  143. codex/static_root/assets/http-error-MPj9N9no.js.br +0 -0
  144. codex/static_root/assets/http-error-MPj9N9no.js.gz +0 -0
  145. codex/static_root/assets/{library-tab-lz5QMD4i.2f04b226ebe8.js → library-tab-5azEcqzs.47a08c31a787.js} +1 -1
  146. codex/static_root/assets/library-tab-5azEcqzs.47a08c31a787.js.br +0 -0
  147. codex/static_root/assets/library-tab-5azEcqzs.47a08c31a787.js.gz +0 -0
  148. codex/static_root/assets/{library-tab-lz5QMD4i.js → library-tab-5azEcqzs.js} +1 -1
  149. codex/static_root/assets/library-tab-5azEcqzs.js.br +0 -0
  150. codex/static_root/assets/library-tab-5azEcqzs.js.gz +0 -0
  151. codex/static_root/assets/main-BsvrAp4n.67f45fa0cbae.js +32 -0
  152. codex/static_root/assets/main-BsvrAp4n.67f45fa0cbae.js.br +0 -0
  153. codex/static_root/assets/main-BsvrAp4n.67f45fa0cbae.js.gz +0 -0
  154. codex/static_root/assets/main-BsvrAp4n.js +32 -0
  155. codex/static_root/assets/main-BsvrAp4n.js.br +0 -0
  156. codex/static_root/assets/main-BsvrAp4n.js.gz +0 -0
  157. codex/static_root/assets/pagination-toolbar-BLUoVz2y.50051431acf1.css +1 -0
  158. codex/static_root/assets/pagination-toolbar-BLUoVz2y.50051431acf1.css.br +0 -0
  159. codex/static_root/assets/pagination-toolbar-BLUoVz2y.50051431acf1.css.gz +0 -0
  160. codex/static_root/assets/pagination-toolbar-BLUoVz2y.css +1 -0
  161. codex/static_root/assets/pagination-toolbar-BLUoVz2y.css.br +0 -0
  162. codex/static_root/assets/pagination-toolbar-BLUoVz2y.css.gz +0 -0
  163. codex/static_root/assets/pagination-toolbar-CfSLqHFH.202c4c4edba3.js +1 -0
  164. codex/static_root/assets/pagination-toolbar-CfSLqHFH.202c4c4edba3.js.br +0 -0
  165. codex/static_root/assets/pagination-toolbar-CfSLqHFH.202c4c4edba3.js.gz +0 -0
  166. codex/static_root/assets/pagination-toolbar-CfSLqHFH.js +1 -0
  167. codex/static_root/assets/pagination-toolbar-CfSLqHFH.js.br +0 -0
  168. codex/static_root/assets/pagination-toolbar-CfSLqHFH.js.gz +0 -0
  169. codex/static_root/assets/{pdf-doc-BpZdmj2g.93e86d9c7927.js → pdf-doc-Dd9MUnaN.750b8c2b1614.js} +1 -1
  170. codex/static_root/assets/pdf-doc-Dd9MUnaN.750b8c2b1614.js.br +0 -0
  171. codex/static_root/assets/pdf-doc-Dd9MUnaN.750b8c2b1614.js.gz +0 -0
  172. codex/static_root/assets/{pdf-doc-BpZdmj2g.js → pdf-doc-Dd9MUnaN.js} +1 -1
  173. codex/static_root/assets/pdf-doc-Dd9MUnaN.js.br +0 -0
  174. codex/static_root/assets/pdf-doc-Dd9MUnaN.js.gz +0 -0
  175. codex/static_root/assets/{reader-CRJUR2qj.js → reader-CFLp5Avy.c10d0e7bdc6a.js} +2 -2
  176. codex/static_root/assets/reader-CFLp5Avy.c10d0e7bdc6a.js.br +0 -0
  177. codex/static_root/assets/reader-CFLp5Avy.c10d0e7bdc6a.js.gz +0 -0
  178. codex/static_root/assets/{reader-CRJUR2qj.55d626f0f9fa.js → reader-CFLp5Avy.js} +2 -2
  179. codex/static_root/assets/reader-CFLp5Avy.js.br +0 -0
  180. codex/static_root/assets/reader-CFLp5Avy.js.gz +0 -0
  181. codex/static_root/assets/{relation-chips-NgDnInw_.3b5ba16f68f0.js → relation-chips-CFQRvVd2.16c214e5a077.js} +1 -1
  182. codex/static_root/assets/relation-chips-CFQRvVd2.16c214e5a077.js.br +0 -0
  183. codex/static_root/assets/relation-chips-CFQRvVd2.16c214e5a077.js.gz +0 -0
  184. codex/static_root/assets/{relation-chips-NgDnInw_.js → relation-chips-CFQRvVd2.js} +1 -1
  185. codex/static_root/assets/relation-chips-CFQRvVd2.js.br +0 -0
  186. codex/static_root/assets/relation-chips-CFQRvVd2.js.gz +0 -0
  187. codex/static_root/assets/{settings-drawer-BaQT27kc.js → settings-drawer-DATmeafe.aed03d89d68e.js} +2 -2
  188. codex/static_root/assets/settings-drawer-DATmeafe.aed03d89d68e.js.br +0 -0
  189. codex/static_root/assets/settings-drawer-DATmeafe.aed03d89d68e.js.gz +0 -0
  190. codex/static_root/assets/{settings-drawer-BaQT27kc.e43fc1527b66.js → settings-drawer-DATmeafe.js} +2 -2
  191. codex/static_root/assets/settings-drawer-DATmeafe.js.br +0 -0
  192. codex/static_root/assets/settings-drawer-DATmeafe.js.gz +0 -0
  193. codex/static_root/assets/{stats-tab-DoHb54IU.30d7deea7b9f.js → stats-tab-BaWY3sVM.0007ad091e4a.js} +1 -1
  194. codex/static_root/assets/stats-tab-BaWY3sVM.0007ad091e4a.js.br +0 -0
  195. codex/static_root/assets/stats-tab-BaWY3sVM.0007ad091e4a.js.gz +0 -0
  196. codex/static_root/assets/{stats-tab-DoHb54IU.js → stats-tab-BaWY3sVM.js} +1 -1
  197. codex/static_root/assets/stats-tab-BaWY3sVM.js.br +0 -0
  198. codex/static_root/assets/stats-tab-BaWY3sVM.js.gz +0 -0
  199. codex/static_root/assets/{task-tab-B88ucu1U.4f240e3d82c4.js → task-tab-DVu0qD_G.5eb9fd4258f1.js} +1 -1
  200. codex/static_root/assets/task-tab-DVu0qD_G.5eb9fd4258f1.js.br +0 -0
  201. codex/static_root/assets/task-tab-DVu0qD_G.5eb9fd4258f1.js.gz +0 -0
  202. codex/static_root/assets/{task-tab-B88ucu1U.js → task-tab-DVu0qD_G.js} +1 -1
  203. codex/static_root/assets/task-tab-DVu0qD_G.js.br +0 -0
  204. codex/static_root/assets/task-tab-DVu0qD_G.js.gz +0 -0
  205. codex/static_root/assets/to-case-nvRvwQgU.a5952b24fca1.js +1 -0
  206. codex/static_root/assets/to-case-nvRvwQgU.a5952b24fca1.js.br +0 -0
  207. codex/static_root/assets/to-case-nvRvwQgU.js +1 -0
  208. codex/static_root/assets/to-case-nvRvwQgU.js.br +0 -0
  209. codex/static_root/assets/{unauthorized-AnKtlgGy.62ee74d4373c.js → unauthorized-xWMjiI8M.490ac34d8d4a.js} +1 -1
  210. codex/static_root/assets/unauthorized-xWMjiI8M.490ac34d8d4a.js.br +0 -0
  211. codex/static_root/assets/unauthorized-xWMjiI8M.490ac34d8d4a.js.gz +0 -0
  212. codex/static_root/assets/{unauthorized-AnKtlgGy.js → unauthorized-xWMjiI8M.js} +1 -1
  213. codex/static_root/assets/unauthorized-xWMjiI8M.js.br +0 -0
  214. codex/static_root/assets/unauthorized-xWMjiI8M.js.gz +0 -0
  215. codex/static_root/assets/{user-tab-BxtZ2u7W.161cc8f0dcce.js → user-tab-BhdZJ6QU.c2709e6649b1.js} +1 -1
  216. codex/static_root/assets/user-tab-BhdZJ6QU.c2709e6649b1.js.br +0 -0
  217. codex/static_root/assets/user-tab-BhdZJ6QU.c2709e6649b1.js.gz +0 -0
  218. codex/static_root/assets/{user-tab-BxtZ2u7W.js → user-tab-BhdZJ6QU.js} +1 -1
  219. codex/static_root/assets/user-tab-BhdZJ6QU.js.br +0 -0
  220. codex/static_root/assets/user-tab-BhdZJ6QU.js.gz +0 -0
  221. codex/static_root/{manifest.3851c028b0cb.json → manifest.94f4daf2f37d.json} +222 -222
  222. codex/static_root/manifest.94f4daf2f37d.json.br +0 -0
  223. codex/static_root/manifest.94f4daf2f37d.json.gz +0 -0
  224. codex/static_root/manifest.json +222 -222
  225. codex/static_root/manifest.json.br +0 -0
  226. codex/static_root/manifest.json.gz +0 -0
  227. codex/static_root/staticfiles.json +1 -1
  228. codex/views/browser/cover.py +15 -18
  229. codex/views/browser/filters/group.py +4 -3
  230. codex/views/browser/metadata.py +5 -5
  231. codex/views/reader/page.py +13 -2
  232. codex/views/util.py +13 -0
  233. {codex-1.6.0a11.dist-info → codex-1.6.0rc0.dist-info}/METADATA +2 -1
  234. {codex-1.6.0a11.dist-info → codex-1.6.0rc0.dist-info}/RECORD +237 -237
  235. codex/static_root/assets/VCheckbox-BwDyxhU7.831b00df198a.js.br +0 -0
  236. codex/static_root/assets/VCheckbox-BwDyxhU7.831b00df198a.js.gz +0 -0
  237. codex/static_root/assets/VCheckbox-BwDyxhU7.js.br +0 -0
  238. codex/static_root/assets/VCheckbox-BwDyxhU7.js.gz +0 -0
  239. codex/static_root/assets/VCheckboxBtn-DVq5lDK4.5e6464c8d80a.js.br +0 -0
  240. codex/static_root/assets/VCheckboxBtn-DVq5lDK4.5e6464c8d80a.js.gz +0 -0
  241. codex/static_root/assets/VCheckboxBtn-DVq5lDK4.js.br +0 -0
  242. codex/static_root/assets/VCheckboxBtn-DVq5lDK4.js.gz +0 -0
  243. codex/static_root/assets/VCombobox-BASCOy0n.7801caa5e192.js.br +0 -0
  244. codex/static_root/assets/VCombobox-BASCOy0n.7801caa5e192.js.gz +0 -0
  245. codex/static_root/assets/VCombobox-BASCOy0n.js.br +0 -0
  246. codex/static_root/assets/VCombobox-BASCOy0n.js.gz +0 -0
  247. codex/static_root/assets/VDialog-DnbL_v_u.0bd289bda8e6.js.br +0 -0
  248. codex/static_root/assets/VDialog-DnbL_v_u.0bd289bda8e6.js.gz +0 -0
  249. codex/static_root/assets/VDialog-DnbL_v_u.js.br +0 -0
  250. codex/static_root/assets/VDialog-DnbL_v_u.js.gz +0 -0
  251. codex/static_root/assets/VExpansionPanels-B8nz8lN5.56e5adec4f62.js.br +0 -0
  252. codex/static_root/assets/VExpansionPanels-B8nz8lN5.56e5adec4f62.js.gz +0 -0
  253. codex/static_root/assets/VExpansionPanels-B8nz8lN5.js.br +0 -0
  254. codex/static_root/assets/VExpansionPanels-B8nz8lN5.js.gz +0 -0
  255. codex/static_root/assets/VRadioGroup-BgwJ_b94.55f84f3429b9.js.br +0 -0
  256. codex/static_root/assets/VRadioGroup-BgwJ_b94.55f84f3429b9.js.gz +0 -0
  257. codex/static_root/assets/VRadioGroup-BgwJ_b94.js.br +0 -0
  258. codex/static_root/assets/VRadioGroup-BgwJ_b94.js.gz +0 -0
  259. codex/static_root/assets/VSelect-BoKpXxwe.a88f065dfe3b.js.br +0 -0
  260. codex/static_root/assets/VSelect-BoKpXxwe.a88f065dfe3b.js.gz +0 -0
  261. codex/static_root/assets/VSelect-BoKpXxwe.js.br +0 -0
  262. codex/static_root/assets/VSelect-BoKpXxwe.js.gz +0 -0
  263. codex/static_root/assets/VSelectionControl-BXJGg8No.0cb36d941d2a.js.br +0 -0
  264. codex/static_root/assets/VSelectionControl-BXJGg8No.0cb36d941d2a.js.gz +0 -0
  265. codex/static_root/assets/VSelectionControl-BXJGg8No.js.br +0 -0
  266. codex/static_root/assets/VSelectionControl-BXJGg8No.js.gz +0 -0
  267. codex/static_root/assets/VSlideGroup-C2TL5E34.775adeb5a973.js.br +0 -0
  268. codex/static_root/assets/VSlideGroup-C2TL5E34.775adeb5a973.js.gz +0 -0
  269. codex/static_root/assets/VSlideGroup-C2TL5E34.js.br +0 -0
  270. codex/static_root/assets/VSlideGroup-C2TL5E34.js.gz +0 -0
  271. codex/static_root/assets/VTable-C0FptljX.e4840b635c6e.js.br +0 -0
  272. codex/static_root/assets/VTable-C0FptljX.e4840b635c6e.js.gz +0 -0
  273. codex/static_root/assets/VTable-C0FptljX.js.br +0 -0
  274. codex/static_root/assets/VTable-C0FptljX.js.gz +0 -0
  275. codex/static_root/assets/VTextField-Aw8nKhY6.428732ac22d7.js.br +0 -0
  276. codex/static_root/assets/VTextField-Aw8nKhY6.428732ac22d7.js.gz +0 -0
  277. codex/static_root/assets/VTextField-Aw8nKhY6.js.br +0 -0
  278. codex/static_root/assets/VTextField-Aw8nKhY6.js.gz +0 -0
  279. codex/static_root/assets/VWindowItem-D9j_u9MX.828acf3dee55.js.br +0 -0
  280. codex/static_root/assets/VWindowItem-D9j_u9MX.828acf3dee55.js.gz +0 -0
  281. codex/static_root/assets/VWindowItem-D9j_u9MX.js.br +0 -0
  282. codex/static_root/assets/VWindowItem-D9j_u9MX.js.gz +0 -0
  283. codex/static_root/assets/admin-drawer-panel-Dmn4wEY3.af7e8490f0e3.js.br +0 -0
  284. codex/static_root/assets/admin-drawer-panel-Dmn4wEY3.af7e8490f0e3.js.gz +0 -0
  285. codex/static_root/assets/admin-drawer-panel-Dmn4wEY3.js.br +0 -0
  286. codex/static_root/assets/admin-drawer-panel-Dmn4wEY3.js.gz +0 -0
  287. codex/static_root/assets/admin-jf7zR2p_.4741813376d2.js +0 -1
  288. codex/static_root/assets/admin-jf7zR2p_.4741813376d2.js.br +0 -0
  289. codex/static_root/assets/admin-jf7zR2p_.4741813376d2.js.gz +0 -0
  290. codex/static_root/assets/admin-jf7zR2p_.js +0 -1
  291. codex/static_root/assets/admin-jf7zR2p_.js.br +0 -0
  292. codex/static_root/assets/admin-jf7zR2p_.js.gz +0 -0
  293. codex/static_root/assets/browser-BKZuypzF.86e5333bd7d6.js +0 -1
  294. codex/static_root/assets/browser-BKZuypzF.86e5333bd7d6.js.br +0 -0
  295. codex/static_root/assets/browser-BKZuypzF.86e5333bd7d6.js.gz +0 -0
  296. codex/static_root/assets/browser-BKZuypzF.js +0 -1
  297. codex/static_root/assets/browser-BKZuypzF.js.br +0 -0
  298. codex/static_root/assets/browser-BKZuypzF.js.gz +0 -0
  299. codex/static_root/assets/browser-D7xci5SY.css +0 -1
  300. codex/static_root/assets/browser-D7xci5SY.css.br +0 -0
  301. codex/static_root/assets/browser-D7xci5SY.css.gz +0 -0
  302. codex/static_root/assets/browser-D7xci5SY.fa305e14005c.css +0 -1
  303. codex/static_root/assets/browser-D7xci5SY.fa305e14005c.css.br +0 -0
  304. codex/static_root/assets/browser-D7xci5SY.fa305e14005c.css.gz +0 -0
  305. codex/static_root/assets/change-password-dialog-Cc1e755p.b29d200537bf.js.br +0 -0
  306. codex/static_root/assets/change-password-dialog-Cc1e755p.b29d200537bf.js.gz +0 -0
  307. codex/static_root/assets/change-password-dialog-Cc1e755p.js.br +0 -0
  308. codex/static_root/assets/change-password-dialog-Cc1e755p.js.gz +0 -0
  309. codex/static_root/assets/confirm-dialog-Cyr7HAAz.8ab1d8b6241a.js.br +0 -0
  310. codex/static_root/assets/confirm-dialog-Cyr7HAAz.8ab1d8b6241a.js.gz +0 -0
  311. codex/static_root/assets/confirm-dialog-Cyr7HAAz.js.br +0 -0
  312. codex/static_root/assets/confirm-dialog-Cyr7HAAz.js.gz +0 -0
  313. codex/static_root/assets/datetime-column-Cqi99Ze-.49d0ce340183.js.br +0 -0
  314. codex/static_root/assets/datetime-column-Cqi99Ze-.49d0ce340183.js.gz +0 -0
  315. codex/static_root/assets/datetime-column-Cqi99Ze-.js.br +0 -0
  316. codex/static_root/assets/datetime-column-Cqi99Ze-.js.gz +0 -0
  317. codex/static_root/assets/filter-CuocBoS2.885d1b8d44cc.js.br +0 -0
  318. codex/static_root/assets/filter-CuocBoS2.885d1b8d44cc.js.gz +0 -0
  319. codex/static_root/assets/filter-CuocBoS2.js.br +0 -0
  320. codex/static_root/assets/filter-CuocBoS2.js.gz +0 -0
  321. codex/static_root/assets/flag-tab-B5dRCBAt.e858f7ec9f55.js.br +0 -0
  322. codex/static_root/assets/flag-tab-B5dRCBAt.e858f7ec9f55.js.gz +0 -0
  323. codex/static_root/assets/flag-tab-B5dRCBAt.js.br +0 -0
  324. codex/static_root/assets/flag-tab-B5dRCBAt.js.gz +0 -0
  325. codex/static_root/assets/group-tab-_nT2o04v.c06032b254dc.js.br +0 -0
  326. codex/static_root/assets/group-tab-_nT2o04v.c06032b254dc.js.gz +0 -0
  327. codex/static_root/assets/group-tab-_nT2o04v.js.br +0 -0
  328. codex/static_root/assets/group-tab-_nT2o04v.js.gz +0 -0
  329. codex/static_root/assets/http-error-CXo9qLiW.d5a337f399c9.js.br +0 -0
  330. codex/static_root/assets/http-error-CXo9qLiW.d5a337f399c9.js.gz +0 -0
  331. codex/static_root/assets/http-error-CXo9qLiW.js.br +0 -0
  332. codex/static_root/assets/http-error-CXo9qLiW.js.gz +0 -0
  333. codex/static_root/assets/library-tab-lz5QMD4i.2f04b226ebe8.js.br +0 -0
  334. codex/static_root/assets/library-tab-lz5QMD4i.2f04b226ebe8.js.gz +0 -0
  335. codex/static_root/assets/library-tab-lz5QMD4i.js.br +0 -0
  336. codex/static_root/assets/library-tab-lz5QMD4i.js.gz +0 -0
  337. codex/static_root/assets/main-17i0EBCp.7093c3f755f1.js +0 -32
  338. codex/static_root/assets/main-17i0EBCp.7093c3f755f1.js.br +0 -0
  339. codex/static_root/assets/main-17i0EBCp.7093c3f755f1.js.gz +0 -0
  340. codex/static_root/assets/main-17i0EBCp.js +0 -32
  341. codex/static_root/assets/main-17i0EBCp.js.br +0 -0
  342. codex/static_root/assets/main-17i0EBCp.js.gz +0 -0
  343. codex/static_root/assets/pagination-toolbar-BBvsIXTd.ad891da6617a.js +0 -1
  344. codex/static_root/assets/pagination-toolbar-BBvsIXTd.ad891da6617a.js.br +0 -0
  345. codex/static_root/assets/pagination-toolbar-BBvsIXTd.ad891da6617a.js.gz +0 -0
  346. codex/static_root/assets/pagination-toolbar-BBvsIXTd.js +0 -1
  347. codex/static_root/assets/pagination-toolbar-BBvsIXTd.js.br +0 -0
  348. codex/static_root/assets/pagination-toolbar-BBvsIXTd.js.gz +0 -0
  349. codex/static_root/assets/pagination-toolbar-B_zL7BQQ.css +0 -1
  350. codex/static_root/assets/pagination-toolbar-B_zL7BQQ.css.br +0 -0
  351. codex/static_root/assets/pagination-toolbar-B_zL7BQQ.css.gz +0 -0
  352. codex/static_root/assets/pagination-toolbar-B_zL7BQQ.d1311bd41edc.css +0 -1
  353. codex/static_root/assets/pagination-toolbar-B_zL7BQQ.d1311bd41edc.css.br +0 -0
  354. codex/static_root/assets/pagination-toolbar-B_zL7BQQ.d1311bd41edc.css.gz +0 -0
  355. codex/static_root/assets/pdf-doc-BpZdmj2g.93e86d9c7927.js.br +0 -0
  356. codex/static_root/assets/pdf-doc-BpZdmj2g.93e86d9c7927.js.gz +0 -0
  357. codex/static_root/assets/pdf-doc-BpZdmj2g.js.br +0 -0
  358. codex/static_root/assets/pdf-doc-BpZdmj2g.js.gz +0 -0
  359. codex/static_root/assets/reader-CRJUR2qj.55d626f0f9fa.js.br +0 -0
  360. codex/static_root/assets/reader-CRJUR2qj.55d626f0f9fa.js.gz +0 -0
  361. codex/static_root/assets/reader-CRJUR2qj.js.br +0 -0
  362. codex/static_root/assets/reader-CRJUR2qj.js.gz +0 -0
  363. codex/static_root/assets/relation-chips-NgDnInw_.3b5ba16f68f0.js.br +0 -0
  364. codex/static_root/assets/relation-chips-NgDnInw_.3b5ba16f68f0.js.gz +0 -0
  365. codex/static_root/assets/relation-chips-NgDnInw_.js.br +0 -0
  366. codex/static_root/assets/relation-chips-NgDnInw_.js.gz +0 -0
  367. codex/static_root/assets/settings-drawer-BaQT27kc.e43fc1527b66.js.br +0 -0
  368. codex/static_root/assets/settings-drawer-BaQT27kc.e43fc1527b66.js.gz +0 -0
  369. codex/static_root/assets/settings-drawer-BaQT27kc.js.br +0 -0
  370. codex/static_root/assets/settings-drawer-BaQT27kc.js.gz +0 -0
  371. codex/static_root/assets/stats-tab-DoHb54IU.30d7deea7b9f.js.br +0 -0
  372. codex/static_root/assets/stats-tab-DoHb54IU.30d7deea7b9f.js.gz +0 -0
  373. codex/static_root/assets/stats-tab-DoHb54IU.js.br +0 -0
  374. codex/static_root/assets/stats-tab-DoHb54IU.js.gz +0 -0
  375. codex/static_root/assets/task-tab-B88ucu1U.4f240e3d82c4.js.br +0 -0
  376. codex/static_root/assets/task-tab-B88ucu1U.4f240e3d82c4.js.gz +0 -0
  377. codex/static_root/assets/task-tab-B88ucu1U.js.br +0 -0
  378. codex/static_root/assets/task-tab-B88ucu1U.js.gz +0 -0
  379. codex/static_root/assets/to-case-B7MjLIw-.08fc8412de69.js +0 -1
  380. codex/static_root/assets/to-case-B7MjLIw-.08fc8412de69.js.br +0 -0
  381. codex/static_root/assets/to-case-B7MjLIw-.js +0 -1
  382. codex/static_root/assets/to-case-B7MjLIw-.js.br +0 -0
  383. codex/static_root/assets/unauthorized-AnKtlgGy.62ee74d4373c.js.br +0 -0
  384. codex/static_root/assets/unauthorized-AnKtlgGy.62ee74d4373c.js.gz +0 -0
  385. codex/static_root/assets/unauthorized-AnKtlgGy.js.br +0 -0
  386. codex/static_root/assets/unauthorized-AnKtlgGy.js.gz +0 -0
  387. codex/static_root/assets/user-tab-BxtZ2u7W.161cc8f0dcce.js.br +0 -0
  388. codex/static_root/assets/user-tab-BxtZ2u7W.161cc8f0dcce.js.gz +0 -0
  389. codex/static_root/assets/user-tab-BxtZ2u7W.js.br +0 -0
  390. codex/static_root/assets/user-tab-BxtZ2u7W.js.gz +0 -0
  391. codex/static_root/manifest.3851c028b0cb.json.br +0 -0
  392. codex/static_root/manifest.3851c028b0cb.json.gz +0 -0
  393. {codex-1.6.0a11.dist-info → codex-1.6.0rc0.dist-info}/LICENSE +0 -0
  394. {codex-1.6.0a11.dist-info → codex-1.6.0rc0.dist-info}/WHEEL +0 -0
  395. {codex-1.6.0a11.dist-info → codex-1.6.0rc0.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.2f6b0359e1ef.json", "js/choices-admin.json": "js/choices-admin.3521e2a863df.json", "assets/relation-chips-Bsc-gUxE.css": "assets/relation-chips-Bsc-gUxE.98e65384c3c9.css", "assets/pagination-toolbar-BBvsIXTd.js": "assets/pagination-toolbar-BBvsIXTd.ad891da6617a.js", "assets/group-tab-CBKuS3Iv.css": "assets/group-tab-CBKuS3Iv.7e4746634782.css", "assets/http-error-DKulXuTl.css": "assets/http-error-DKulXuTl.95e42988d5d5.css", "assets/group-tab-_nT2o04v.js": "assets/group-tab-_nT2o04v.c06032b254dc.js", "assets/VSelect-ARDhJiQK.css": "assets/VSelect-ARDhJiQK.372c098fb475.css", "assets/flag-tab-BNwbLfrN.css": "assets/flag-tab-BNwbLfrN.b755a99fff7e.css", "assets/library-tab-lz5QMD4i.js": "assets/library-tab-lz5QMD4i.2f04b226ebe8.js", "assets/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/datetime-column-Cqi99Ze-.js": "assets/datetime-column-Cqi99Ze-.49d0ce340183.js", "assets/VExpansionPanels-B8nz8lN5.js": "assets/VExpansionPanels-B8nz8lN5.56e5adec4f62.js", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/VSlideGroup-C2TL5E34.js": "assets/VSlideGroup-C2TL5E34.775adeb5a973.js", "assets/materialdesignicons-webfont-PXm3-2wK.woff": "assets/materialdesignicons-webfont-PXm3-2wK.026b7ac9c43c.woff", "assets/unauthorized-AnKtlgGy.js": "assets/unauthorized-AnKtlgGy.62ee74d4373c.js", "assets/VSlideGroup-Dk_1upHt.css": "assets/VSlideGroup-Dk_1upHt.2c836070ec75.css", "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/stats-tab-DoHb54IU.js": "assets/stats-tab-DoHb54IU.30d7deea7b9f.js", "assets/VCombobox-BASCOy0n.js": "assets/VCombobox-BASCOy0n.7801caa5e192.js", "assets/http-error-CXo9qLiW.js": "assets/http-error-CXo9qLiW.d5a337f399c9.js", "assets/VCheckboxBtn-DVq5lDK4.js": "assets/VCheckboxBtn-DVq5lDK4.5e6464c8d80a.js", "assets/VDialog-lQ13FnRR.css": "assets/VDialog-lQ13FnRR.1c801ad756b2.css", "assets/relation-chips-NgDnInw_.js": "assets/relation-chips-NgDnInw_.3b5ba16f68f0.js", "assets/main-Ztp855PW.css": "assets/main-Ztp855PW.d46d718fac45.css", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/task-tab-B88ucu1U.js": "assets/task-tab-B88ucu1U.4f240e3d82c4.js", "assets/browser-BKZuypzF.js": "assets/browser-BKZuypzF.86e5333bd7d6.js", "assets/change-password-dialog-0u6IJA87.css": "assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/VTextField-Aw8nKhY6.js": "assets/VTextField-Aw8nKhY6.428732ac22d7.js", "assets/VWindowItem-D9j_u9MX.js": "assets/VWindowItem-D9j_u9MX.828acf3dee55.js", "assets/VCheckbox-BwDyxhU7.js": "assets/VCheckbox-BwDyxhU7.831b00df198a.js", "assets/settings-drawer-BaQT27kc.js": "assets/settings-drawer-BaQT27kc.e43fc1527b66.js", "assets/library-tab-BN0SfPcH.css": "assets/library-tab-BN0SfPcH.913e236f625e.css", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/user-tab-BxtZ2u7W.js": "assets/user-tab-BxtZ2u7W.161cc8f0dcce.js", "assets/admin-jf7zR2p_.js": "assets/admin-jf7zR2p_.4741813376d2.js", "assets/change-password-dialog-Cc1e755p.js": "assets/change-password-dialog-Cc1e755p.b29d200537bf.js", "assets/VSelect-BoKpXxwe.js": "assets/VSelect-BoKpXxwe.a88f065dfe3b.js", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/pdf-doc-BpZdmj2g.js": "assets/pdf-doc-BpZdmj2g.93e86d9c7927.js", "assets/VRadioGroup-BgwJ_b94.js": "assets/VRadioGroup-BgwJ_b94.55f84f3429b9.js", "assets/admin-drawer-panel-Dmn4wEY3.js": "assets/admin-drawer-panel-Dmn4wEY3.af7e8490f0e3.js", "assets/flag-tab-B5dRCBAt.js": "assets/flag-tab-B5dRCBAt.e858f7ec9f55.js", "assets/browser-D7xci5SY.css": "assets/browser-D7xci5SY.fa305e14005c.css", "assets/main-17i0EBCp.js": "assets/main-17i0EBCp.7093c3f755f1.js", "assets/admin-B8Bp2Uih.css": "assets/admin-B8Bp2Uih.82c98714bcf1.css", "assets/reader-CRJUR2qj.js": "assets/reader-CRJUR2qj.55d626f0f9fa.js", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/stats-tab-B4yKuY0c.css": "assets/stats-tab-B4yKuY0c.a5728396494b.css", "assets/reader-CqXFa_gE.css": "assets/reader-CqXFa_gE.78267e9de0c2.css", "assets/confirm-dialog-Cyr7HAAz.js": "assets/confirm-dialog-Cyr7HAAz.8ab1d8b6241a.js", "assets/to-case-B7MjLIw-.js": "assets/to-case-B7MjLIw-.08fc8412de69.js", "assets/datetime-column-DeCthByU.css": "assets/datetime-column-DeCthByU.1f3bf499e063.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "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/VTable-C0FptljX.js": "assets/VTable-C0FptljX.e4840b635c6e.js", "assets/VTextField-BssVoDhB.css": "assets/VTextField-BssVoDhB.4cc388b4aa3c.css", "assets/pagination-toolbar-B_zL7BQQ.css": "assets/pagination-toolbar-B_zL7BQQ.d1311bd41edc.css", "assets/VDialog-DnbL_v_u.js": "assets/VDialog-DnbL_v_u.0bd289bda8e6.js", "assets/materialdesignicons-webfont-Dp5v-WZN.woff2": "assets/materialdesignicons-webfont-Dp5v-WZN.1d7bcee1b302.woff2", "assets/filter-CuocBoS2.js": "assets/filter-CuocBoS2.885d1b8d44cc.js", "assets/VSelectionControl-BXJGg8No.js": "assets/VSelectionControl-BXJGg8No.0cb36d941d2a.js", "robots.txt": "robots.b6216d61c03e.txt", "manifest.json": "manifest.3851c028b0cb.json"}, "version": "1.1", "hash": "5a212e3ae156"}
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.2f6b0359e1ef.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/pdf-doc-Dd9MUnaN.js": "assets/pdf-doc-Dd9MUnaN.750b8c2b1614.js", "assets/VCheckboxBtn-DbVzgq3g.js": "assets/VCheckboxBtn-DbVzgq3g.c2e2e2b16db0.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/VSelectionControl-BFq--28I.css": "assets/VSelectionControl-BFq--28I.9687c77461fc.css", "assets/pdf-doc-CMzaSV_K.css": "assets/pdf-doc-CMzaSV_K.8cd4b3e65f9a.css", "assets/browser-CA_2XCnV.js": "assets/browser-CA_2XCnV.fb1d5c95e960.js", "assets/VSelectionControl-DocEa9g1.js": "assets/VSelectionControl-DocEa9g1.52f73fdce6d1.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/change-password-dialog-CdCjAlM3.js": "assets/change-password-dialog-CdCjAlM3.39002922098f.js", "assets/http-error-MPj9N9no.js": "assets/http-error-MPj9N9no.5efe701ebf21.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/relation-chips-CFQRvVd2.js": "assets/relation-chips-CFQRvVd2.16c214e5a077.js", "assets/flag-tab-CEyOjZFp.js": "assets/flag-tab-CEyOjZFp.628af77cb04b.js", "assets/VDialog-lQ13FnRR.css": "assets/VDialog-lQ13FnRR.1c801ad756b2.css", "assets/main-Ztp855PW.css": "assets/main-Ztp855PW.d46d718fac45.css", "assets/VCombobox-DRNxfPeq.js": "assets/VCombobox-DRNxfPeq.db51c60468b3.js", "assets/datetime-column-DwrIUx_h.js": "assets/datetime-column-DwrIUx_h.f913e4e33aab.js", "assets/VRadioGroup-i2qP9Wu9.css": "assets/VRadioGroup-i2qP9Wu9.8e3741381961.css", "assets/group-tab-CBqhy8zy.js": "assets/group-tab-CBqhy8zy.75497868a808.js", "assets/VSelect-C768JtGg.js": "assets/VSelect-C768JtGg.a9c65d26248e.js", "assets/change-password-dialog-0u6IJA87.css": "assets/change-password-dialog-0u6IJA87.5f9a9aa573b7.css", "assets/VTable-Bm3ZZq7k.js": "assets/VTable-Bm3ZZq7k.126b28481416.js", "assets/VTextField-DuOs5usq.js": "assets/VTextField-DuOs5usq.b1fe3e9e431d.js", "assets/copy-to-clipboard-DoUvDJVx.js": "assets/copy-to-clipboard-DoUvDJVx.bec27f144aca.js", "assets/VExpansionPanels-dtwXHEmN.js": "assets/VExpansionPanels-dtwXHEmN.b8444e54d145.js", "assets/VSlideGroup-w7zv3wT_.js": "assets/VSlideGroup-w7zv3wT_.647c2d1d6877.js", "assets/VWindowItem-ByIod57Y.css": "assets/VWindowItem-ByIod57Y.f7fb19752bf3.css", "assets/pagination-toolbar-CfSLqHFH.js": "assets/pagination-toolbar-CfSLqHFH.202c4c4edba3.js", "assets/settings-drawer-DATmeafe.js": "assets/settings-drawer-DATmeafe.aed03d89d68e.js", "assets/admin-37fN97_d.js": "assets/admin-37fN97_d.076ef24ac3c3.js", "assets/user-tab-BhdZJ6QU.js": "assets/user-tab-BhdZJ6QU.c2709e6649b1.js", "assets/main-BsvrAp4n.js": "assets/main-BsvrAp4n.67f45fa0cbae.js", "assets/task-tab-DVu0qD_G.js": "assets/task-tab-DVu0qD_G.5eb9fd4258f1.js", "assets/reader-CFLp5Avy.js": "assets/reader-CFLp5Avy.c10d0e7bdc6a.js", "assets/browser-BlycPHgZ.css": "assets/browser-BlycPHgZ.5842145b0e63.css", "assets/library-tab-BN0SfPcH.css": "assets/library-tab-BN0SfPcH.913e236f625e.css", "assets/confirm-dialog-BmhedLCx.css": "assets/confirm-dialog-BmhedLCx.7c2103d319d4.css", "assets/VCheckbox-BK0IPHyB.js": "assets/VCheckbox-BK0IPHyB.c85e2f87e16a.js", "assets/materialdesignicons-webfont-B7mPwVP_.ttf": "assets/materialdesignicons-webfont-B7mPwVP_.6e435534bd35.ttf", "assets/library-tab-5azEcqzs.js": "assets/library-tab-5azEcqzs.47a08c31a787.js", "assets/VCombobox-BksEr4D_.css": "assets/VCombobox-BksEr4D_.73429bb75f42.css", "assets/confirm-dialog-C-TnajF6.js": "assets/confirm-dialog-C-TnajF6.839491684c0e.js", "assets/filter-Tm2kUX1m.js": "assets/filter-Tm2kUX1m.efab6f87b66b.js", "assets/admin-B8Bp2Uih.css": "assets/admin-B8Bp2Uih.82c98714bcf1.css", "assets/stats-tab-BaWY3sVM.js": "assets/stats-tab-BaWY3sVM.0007ad091e4a.js", "assets/task-tab-1XiWn9xP.css": "assets/task-tab-1XiWn9xP.06cb8e1b794d.css", "assets/stats-tab-B4yKuY0c.css": "assets/stats-tab-B4yKuY0c.a5728396494b.css", "assets/reader-CqXFa_gE.css": "assets/reader-CqXFa_gE.78267e9de0c2.css", "assets/VRadioGroup-DUhU0d2J.js": "assets/VRadioGroup-DUhU0d2J.62d19103a0cc.js", "assets/admin-drawer-panel-CFthvbMb.js": "assets/admin-drawer-panel-CFthvbMb.11b1e9f05875.js", "assets/to-case-nvRvwQgU.js": "assets/to-case-nvRvwQgU.a5952b24fca1.js", "assets/datetime-column-DeCthByU.css": "assets/datetime-column-DeCthByU.1f3bf499e063.css", "assets/materialdesignicons-webfont-CSr8KVlo.eot": "assets/materialdesignicons-webfont-CSr8KVlo.8ced95a05e3c.eot", "assets/unauthorized-xWMjiI8M.js": "assets/unauthorized-xWMjiI8M.490ac34d8d4a.js", "assets/VDialog-xrkpB5lc.js": "assets/VDialog-xrkpB5lc.7d3fa671e281.js", "assets/VExpansionPanels-DsEXVcCv.css": "assets/VExpansionPanels-DsEXVcCv.20b475255e66.css", "assets/pagination-toolbar-BLUoVz2y.css": "assets/pagination-toolbar-BLUoVz2y.50051431acf1.css", "assets/unauthorized-CibJYD8o.css": "assets/unauthorized-CibJYD8o.4c2de98c2b53.css", "assets/VCheckbox-CMKdyl0R.css": "assets/VCheckbox-CMKdyl0R.016ed8d222c4.css", "assets/VWindowItem-C3SaotR1.js": "assets/VWindowItem-C3SaotR1.05f0f97e8897.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.94f4daf2f37d.json"}, "version": "1.1", "hash": "570d3a013d8f"}
@@ -1,7 +1,7 @@
1
1
  """Comic cover thumbnail view."""
2
2
 
3
3
  from django.db.models.query import Q
4
- from django.http import HttpResponse
4
+ from django.http.response import StreamingHttpResponse
5
5
  from drf_spectacular.types import OpenApiTypes
6
6
  from drf_spectacular.utils import extend_schema
7
7
  from rest_framework.renderers import BaseRenderer
@@ -21,6 +21,7 @@ from codex.views.const import (
21
21
  MISSING_COVER_NAME_MAP,
22
22
  STATIC_IMG_PATH,
23
23
  )
24
+ from codex.views.util import chunker
24
25
 
25
26
  LOG = get_logger(__name__)
26
27
 
@@ -51,21 +52,19 @@ class CoverView(BrowserAnnotationsView):
51
52
 
52
53
  def get_group_filter(self, group=None, pks=None, page_mtime=False):
53
54
  """Get group filter for First Cover View."""
54
- if self.params.get("dynamic_covers"):
55
+ if self.params.get("dynamic_covers") or self.model == Volume:
55
56
  return super().get_group_filter(group=group, pks=pks, page_mtime=page_mtime)
56
57
 
57
58
  # First cover group filter relies on sort names to look outside the browser supplied pks
58
59
  # For multi_groups not in the browser query.
59
60
  pks = self.kwargs["pks"]
60
- name_rel = "name" if self.model == Volume else "sort_name"
61
61
  qs = self.model.objects.filter(pk__in=pks) # type: ignore
62
- sort_names = qs.values_list(name_rel, flat=True).distinct()
62
+ sort_names = qs.values_list("sort_name", flat=True).distinct()
63
63
  model_rel = GROUP_RELATION[self.model_group]
64
- group_filter = {f"{model_rel}__{name_rel}__in": sort_names}
64
+ group_filter = {f"{model_rel}__sort_name__in": sort_names}
65
65
 
66
- parent = self.params["parent"]
67
- parent_pks = parent.get("pks", ())
68
- if parent_pks:
66
+ parent = self.params.get("parent", {})
67
+ if parent_pks := parent.get("pks"):
69
68
  parent_rel = GROUP_RELATION[parent["group"]]
70
69
  group_filter[f"{parent_rel}__pk__in"] = parent_pks
71
70
  return Q(**group_filter)
@@ -133,24 +132,21 @@ class CoverView(BrowserAnnotationsView):
133
132
  return cover_path, content_type
134
133
 
135
134
  def _get_cover_data(self, pk, custom):
136
- thumb_image_data = None
135
+ thumb_buffer = None
137
136
  content_type = "image/webp"
138
137
 
139
138
  cover_path = CoverPathMixin.get_cover_path(pk, custom)
140
139
  if not cover_path.exists():
141
- thumb_image_data = CoverCreateMixin.create_cover_from_path(
140
+ thumb_buffer = CoverCreateMixin.create_cover_from_path(
142
141
  pk, cover_path, LOG, LIBRARIAN_QUEUE, custom
143
142
  )
144
- if not thumb_image_data:
143
+ if not thumb_buffer:
145
144
  cover_path, content_type = self._get_missing_cover_path()
146
145
  elif cover_path.stat().st_size == 0:
147
146
  cover_path, content_type = self._get_missing_cover_path()
148
147
 
149
- if not thumb_image_data:
150
- # if not thumb_image_data:
151
- with cover_path.open("rb") as f:
152
- thumb_image_data = f.read()
153
- return thumb_image_data, content_type
148
+ cover_file = thumb_buffer if thumb_buffer else cover_path.open("rb")
149
+ return cover_file, content_type
154
150
 
155
151
  @extend_schema(
156
152
  parameters=[BrowserAnnotationsView.input_serializer_class],
@@ -161,7 +157,8 @@ class CoverView(BrowserAnnotationsView):
161
157
  try:
162
158
  self.init_request()
163
159
  pk, custom = self._get_cover_pk()
164
- thumb_image_data, content_type = self._get_cover_data(pk, custom)
165
- return HttpResponse(thumb_image_data, content_type=content_type)
160
+ cover_file, content_type = self._get_cover_data(pk, custom)
161
+
162
+ return StreamingHttpResponse(chunker(cover_file), content_type=content_type)
166
163
  except Exception:
167
164
  LOG.exception("get")
@@ -19,12 +19,13 @@ class GroupFilterView(SessionView):
19
19
  """Get the relation from the model to the pks."""
20
20
  # XXX these TARGET refs might be better as subclass get rel methods.
21
21
  target: str = self.TARGET # type: ignore
22
- if target in ("metadata", "mtime") or page_mtime:
22
+ if target in ("cover", "choices"):
23
+ rel = FILTER_ONLY_GROUP_RELATION[group]
24
+ elif target in ("metadata", "mtime") or page_mtime:
23
25
  # metadata, mtime, browser.page_mtime
24
26
  rel = "pk"
25
- elif target in ("choices", "cover"):
26
- rel = FILTER_ONLY_GROUP_RELATION[group]
27
27
  else:
28
+ # browser.group, opds
28
29
  rel = GROUP_RELATION[group]
29
30
 
30
31
  rel += "__in"
@@ -14,6 +14,7 @@ from codex.logger.logging import get_logger
14
14
  from codex.models import AdminFlag, Comic
15
15
  from codex.models.functions import JsonGroupArray
16
16
  from codex.serializers.browser.metadata import PREFETCH_PREFIX, MetadataSerializer
17
+ from codex.serializers.browser.settings import BrowserFilterChoicesInputSerilalizer
17
18
  from codex.views.browser.annotations import BrowserAnnotationsView
18
19
  from codex.views.const import METADATA_GROUP_RELATION
19
20
 
@@ -62,6 +63,7 @@ class MetadataView(BrowserAnnotationsView):
62
63
  """Comic metadata."""
63
64
 
64
65
  serializer_class = MetadataSerializer
66
+ input_serializer_class = BrowserFilterChoicesInputSerilalizer
65
67
  TARGET = "metadata"
66
68
  ADMIN_FLAG_VALUE_KEY_MAP = MappingProxyType(
67
69
  {
@@ -177,8 +179,7 @@ class MetadataView(BrowserAnnotationsView):
177
179
 
178
180
  qs = model.objects.filter(**group_filter)
179
181
  qs = qs.only("name").distinct()
180
- group_by = self.get_group_by(model)
181
- qs = qs.group_by(group_by)
182
+ qs = qs.group_by("name")
182
183
  qs = qs.annotate(ids=JsonGroupArray("id", distinct=True))
183
184
  qs = qs.values("ids", "name")
184
185
  groups[field_name] = qs
@@ -238,8 +239,7 @@ class MetadataView(BrowserAnnotationsView):
238
239
  if self.model and not self.is_model_comic:
239
240
  # move the name of the group to the correct field
240
241
  field = self.model.__name__.lower() + "_list"
241
- group_obj = {"pk": obj.pk, "name": obj.name}
242
- group_list = [group_obj]
242
+ group_list = self.model.objects.filter(pk__in=obj.ids).values("name")
243
243
  setattr(obj, field, group_list)
244
244
  obj.name = None
245
245
 
@@ -322,7 +322,7 @@ class MetadataView(BrowserAnnotationsView):
322
322
  m2m_intersections = self._query_m2m_intersections(filtered_qs)
323
323
  return self._copy_annotations_into_comic_fields(obj, groups, m2m_intersections) # type: ignore
324
324
 
325
- @extend_schema(parameters=[BrowserAnnotationsView.input_serializer_class])
325
+ @extend_schema(parameters=[input_serializer_class])
326
326
  def get(self, *_args, **_kwargs):
327
327
  """Get metadata for a filtered browse group."""
328
328
  # Init
@@ -1,7 +1,9 @@
1
1
  """Views for reading comic books."""
2
2
 
3
+ from io import BytesIO
4
+
3
5
  from comicbox.box import Comicbox
4
- from django.http import HttpResponse
6
+ from django.http.response import StreamingHttpResponse
5
7
  from drf_spectacular.types import OpenApiTypes
6
8
  from drf_spectacular.utils import OpenApiParameter, extend_schema
7
9
  from rest_framework.exceptions import NotFound
@@ -11,9 +13,13 @@ from codex.logger.logging import get_logger
11
13
  from codex.models import Comic
12
14
  from codex.views.bookmark import BookmarkBaseView
13
15
  from codex.views.const import FALSY
16
+ from codex.views.util import chunker
14
17
 
15
18
  LOG = get_logger(__name__)
16
19
  _PDF_MIME_TYPE = "application/pdf"
20
+ # Most pages seem to be 2.5 Mb
21
+ # largest pages I've seen were 9 Mb
22
+ _PAGE_CHUNK_SIZE = (1024**2) * 3 # 3 Mb
17
23
 
18
24
 
19
25
  class IgnoreClientContentNegotiation(BaseContentNegotiation):
@@ -66,8 +72,12 @@ class ReaderPageView(BookmarkBaseView):
66
72
  content_type = _PDF_MIME_TYPE
67
73
  else:
68
74
  content_type = self.content_type
75
+
69
76
  with Comicbox(comic.path) as cb:
70
77
  page_image = cb.get_page_by_index(page, to_pixmap=to_pixmap)
78
+ if not page_image:
79
+ page_image = b""
80
+
71
81
  return page_image, content_type
72
82
 
73
83
  @extend_schema(
@@ -98,4 +108,5 @@ class ReaderPageView(BookmarkBaseView):
98
108
  LOG.warning(exc)
99
109
  raise NotFound(detail="comic page not found") from exc
100
110
  else:
101
- return HttpResponse(page_image, content_type=content_type)
111
+ page_chunker = chunker(BytesIO(page_image), _PAGE_CHUNK_SIZE)
112
+ return StreamingHttpResponse(page_chunker, content_type=content_type)
codex/views/util.py CHANGED
@@ -10,6 +10,9 @@ from urllib.parse import unquote_plus
10
10
  from djangorestframework_camel_case.settings import api_settings
11
11
  from djangorestframework_camel_case.util import underscoreize
12
12
 
13
+ # Maximum cover size is around 24 Kb
14
+ DEFAULT_CHUNK_SIZE = 64 * 1024 # 64 Kb
15
+
13
16
 
14
17
  @dataclass()
15
18
  class Route(dict):
@@ -62,3 +65,13 @@ def pop_name(kwargs: Mapping):
62
65
  kwargs = dict(kwargs)
63
66
  kwargs.pop("name", None)
64
67
  return kwargs
68
+
69
+
70
+ async def chunker(open_file, chunk_size=DEFAULT_CHUNK_SIZE):
71
+ """Asynchronous iterator for serving files."""
72
+ while True:
73
+ chunk = open_file.read(chunk_size)
74
+ if not chunk:
75
+ open_file.close()
76
+ break
77
+ yield chunk
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codex
3
- Version: 1.6.0a11
3
+ Version: 1.6.0rc0
4
4
  Summary: A comic archive web server.
5
5
  Home-page: https://github.com/ajslater/codex
6
6
  License: GPL-3.0-only
@@ -75,6 +75,7 @@ border-radius: 128px;
75
75
  - Filter and sort on all comic metadata and unread status per user.
76
76
  - Browse a tree of publishers, imprints, series, volumes, or your own folder
77
77
  hierarchy.
78
+ - Add custom covers to Folders, Publishers, Imprints, Series, and Story Arcs.
78
79
  - Read comics in a variety of aspect ratios and directions that fit your screen.
79
80
  - Per user bookmarking. Per browser bookmarks even before you make an account.
80
81
  - Watches the filesystem and automatically imports new or changed comics.