codex 1.4.1__py3-none-any.whl → 1.4.3__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 (237) hide show
  1. codex/applications/websocket.py +1 -1
  2. codex/librarian/importer/aggregate_metadata.py +38 -25
  3. codex/librarian/importer/clean_metadata.py +26 -13
  4. codex/librarian/importer/create_fks.py +1 -1
  5. codex/librarian/librariand.py +7 -4
  6. codex/librarian/watchdog/db_snapshot.py +1 -1
  7. codex/librarian/watchdog/event_batcherd.py +14 -11
  8. codex/librarian/watchdog/events.py +1 -1
  9. codex/logger/loggerd.py +14 -11
  10. codex/migrations/0001_init.py +3 -2
  11. codex/migrations/0002_auto_20200826_0622.py +4 -2
  12. codex/migrations/0003_auto_20200831_2033.py +4 -2
  13. codex/migrations/0004_failedimport.py +4 -2
  14. codex/migrations/0005_auto_20200918_0146.py +4 -2
  15. codex/migrations/0006_update_default_names_and_remove_duplicate_comics.py +12 -7
  16. codex/migrations/0007_auto_20211210_1710.py +3 -2
  17. codex/migrations/0008_alter_comic_created_at_alter_comic_format_and_more.py +4 -2
  18. codex/migrations/0009_alter_comic_parent_folder.py +4 -2
  19. codex/migrations/0010_haystack.py +4 -2
  20. codex/migrations/0011_library_groups_and_metadata_changes.py +3 -2
  21. codex/migrations/0012_rename_description_comic_comments.py +4 -2
  22. codex/migrations/0013_int_issue_count_longer_charfields.py +3 -3
  23. codex/migrations/0014_pdf_issue_suffix_remove_cover_image_sort_name.py +3 -2
  24. codex/migrations/0015_link_comics_to_top_level_folders.py +5 -2
  25. codex/migrations/0016_remove_comic_cover_path_librarianstatus.py +3 -3
  26. codex/migrations/0017_alter_timestamp_options_alter_adminflag_name_and_more.py +3 -3
  27. codex/migrations/0018_rename_userbookmark_bookmark.py +3 -2
  28. codex/migrations/0019_delete_queuejob.py +3 -2
  29. codex/migrations/0020_remove_search_tables.py +3 -2
  30. codex/migrations/0021_bookmark_fit_to_choices_read_in_reverse.py +3 -2
  31. codex/migrations/0022_bookmark_vertical_useractive_null_statuses.py +3 -2
  32. codex/migrations/0023_rename_credit_creator_and_more.py +3 -2
  33. codex/migrations/0024_comic_gtin_comic_story_arc_number.py +4 -2
  34. codex/migrations/0025_add_story_arc_number.py +4 -2
  35. codex/models.py +3 -4
  36. codex/search/backend.py +34 -31
  37. codex/serializers/auth.py +2 -1
  38. codex/serializers/choices.py +1 -0
  39. codex/static_root/assets/admin-b2b56cd6.f68d07d2bf93.js +41 -0
  40. codex/static_root/assets/admin-b2b56cd6.f68d07d2bf93.js.br +0 -0
  41. codex/static_root/assets/admin-b2b56cd6.f68d07d2bf93.js.gz +0 -0
  42. codex/static_root/assets/admin-b2b56cd6.js +41 -0
  43. codex/static_root/assets/admin-b2b56cd6.js.br +0 -0
  44. codex/static_root/assets/admin-b2b56cd6.js.gz +0 -0
  45. codex/static_root/assets/{admin-drawer-panel-522f1e6c.089d70878270.js → admin-drawer-panel-efc525ec.ddab36a24e08.js} +1 -1
  46. codex/static_root/assets/admin-drawer-panel-efc525ec.ddab36a24e08.js.br +0 -0
  47. codex/static_root/assets/admin-drawer-panel-efc525ec.ddab36a24e08.js.gz +0 -0
  48. codex/static_root/assets/{admin-drawer-panel-522f1e6c.js → admin-drawer-panel-efc525ec.js} +1 -1
  49. codex/static_root/assets/admin-drawer-panel-efc525ec.js.br +0 -0
  50. codex/static_root/assets/admin-drawer-panel-efc525ec.js.gz +0 -0
  51. codex/static_root/assets/admin-f2bb1dc8.css +1 -0
  52. codex/static_root/assets/admin-f2bb1dc8.css.br +0 -0
  53. codex/static_root/assets/admin-f2bb1dc8.css.gz +0 -0
  54. codex/static_root/assets/admin-f2bb1dc8.ecec18791c01.css +1 -0
  55. codex/static_root/assets/admin-f2bb1dc8.ecec18791c01.css.br +0 -0
  56. codex/static_root/assets/admin-f2bb1dc8.ecec18791c01.css.gz +0 -0
  57. codex/static_root/assets/{browser-7f7d7134.0fe3749b0f2f.css → browser-198df919.css} +1 -1
  58. codex/static_root/assets/browser-198df919.css.br +0 -0
  59. codex/static_root/assets/browser-198df919.css.gz +0 -0
  60. codex/static_root/assets/{browser-7f7d7134.css → browser-198df919.f06301531790.css} +1 -1
  61. codex/static_root/assets/browser-198df919.f06301531790.css.br +0 -0
  62. codex/static_root/assets/browser-198df919.f06301531790.css.gz +0 -0
  63. codex/static_root/assets/browser-ca158ba5.980d652eb174.js +1 -0
  64. codex/static_root/assets/browser-ca158ba5.980d652eb174.js.br +0 -0
  65. codex/static_root/assets/browser-ca158ba5.980d652eb174.js.gz +0 -0
  66. codex/static_root/assets/browser-ca158ba5.js +1 -0
  67. codex/static_root/assets/browser-ca158ba5.js.br +0 -0
  68. codex/static_root/assets/browser-ca158ba5.js.gz +0 -0
  69. codex/static_root/assets/{http-error-5e17b794.77ceeb2d4641.js → http-error-d31fd3bd.6ab9acf65973.js} +1 -1
  70. codex/static_root/assets/http-error-d31fd3bd.6ab9acf65973.js.br +0 -0
  71. codex/static_root/assets/http-error-d31fd3bd.6ab9acf65973.js.gz +0 -0
  72. codex/static_root/assets/{http-error-5e17b794.js → http-error-d31fd3bd.js} +1 -1
  73. codex/static_root/assets/http-error-d31fd3bd.js.br +0 -0
  74. codex/static_root/assets/http-error-d31fd3bd.js.gz +0 -0
  75. codex/static_root/assets/{main-0898f4bb.181e0145c642.css → main-c11eb0f1.776522baac3b.css} +1 -1
  76. codex/static_root/assets/main-c11eb0f1.776522baac3b.css.br +0 -0
  77. codex/static_root/assets/{main-0898f4bb.181e0145c642.css.gz → main-c11eb0f1.776522baac3b.css.gz} +0 -0
  78. codex/static_root/assets/{main-0898f4bb.css → main-c11eb0f1.css} +1 -1
  79. codex/static_root/assets/main-c11eb0f1.css.br +0 -0
  80. codex/static_root/assets/{main-0898f4bb.css.gz → main-c11eb0f1.css.gz} +0 -0
  81. codex/static_root/assets/main-c5736dea.a4790dbdb569.js +1 -0
  82. codex/static_root/assets/main-c5736dea.a4790dbdb569.js.br +0 -0
  83. codex/static_root/assets/main-c5736dea.a4790dbdb569.js.gz +0 -0
  84. codex/static_root/assets/main-c5736dea.js +1 -0
  85. codex/static_root/assets/main-c5736dea.js.br +0 -0
  86. codex/static_root/assets/main-c5736dea.js.gz +0 -0
  87. codex/static_root/assets/metadata-dialog-83c74d48.b5cccc13c737.css +1 -0
  88. codex/static_root/assets/metadata-dialog-83c74d48.b5cccc13c737.css.br +0 -0
  89. codex/static_root/assets/metadata-dialog-83c74d48.b5cccc13c737.css.gz +0 -0
  90. codex/static_root/assets/metadata-dialog-83c74d48.css +1 -0
  91. codex/static_root/assets/metadata-dialog-83c74d48.css.br +0 -0
  92. codex/static_root/assets/metadata-dialog-83c74d48.css.gz +0 -0
  93. codex/static_root/assets/metadata-dialog-8c0a11ff.b281b7635db5.js +1 -0
  94. codex/static_root/assets/metadata-dialog-8c0a11ff.b281b7635db5.js.br +0 -0
  95. codex/static_root/assets/metadata-dialog-8c0a11ff.b281b7635db5.js.gz +0 -0
  96. codex/static_root/assets/metadata-dialog-8c0a11ff.js +1 -0
  97. codex/static_root/assets/metadata-dialog-8c0a11ff.js.br +0 -0
  98. codex/static_root/assets/metadata-dialog-8c0a11ff.js.gz +0 -0
  99. codex/static_root/assets/{page-pdf-157ba97e.613d7c2beb77.js → page-pdf-ed976750.730244f14d16.js} +1 -1
  100. codex/static_root/assets/page-pdf-ed976750.730244f14d16.js.br +0 -0
  101. codex/static_root/assets/page-pdf-ed976750.730244f14d16.js.gz +0 -0
  102. codex/static_root/assets/{page-pdf-157ba97e.js → page-pdf-ed976750.js} +1 -1
  103. codex/static_root/assets/page-pdf-ed976750.js.br +0 -0
  104. codex/static_root/assets/page-pdf-ed976750.js.gz +0 -0
  105. codex/static_root/assets/reader-5540ffcb.8ea3c63a3154.css +1 -0
  106. codex/static_root/assets/reader-5540ffcb.8ea3c63a3154.css.br +0 -0
  107. codex/static_root/assets/reader-5540ffcb.8ea3c63a3154.css.gz +0 -0
  108. codex/static_root/assets/reader-5540ffcb.css +1 -0
  109. codex/static_root/assets/reader-5540ffcb.css.br +0 -0
  110. codex/static_root/assets/reader-5540ffcb.css.gz +0 -0
  111. codex/static_root/assets/reader-c562377d.7f78718f4c63.js +1 -0
  112. codex/static_root/assets/reader-c562377d.7f78718f4c63.js.br +0 -0
  113. codex/static_root/assets/reader-c562377d.7f78718f4c63.js.gz +0 -0
  114. codex/static_root/assets/reader-c562377d.js +1 -0
  115. codex/static_root/assets/reader-c562377d.js.br +0 -0
  116. codex/static_root/assets/reader-c562377d.js.gz +0 -0
  117. codex/static_root/{manifest.d2f93a519ada.json → manifest.55457ccaa01c.json} +32 -32
  118. codex/static_root/manifest.55457ccaa01c.json.br +0 -0
  119. codex/static_root/manifest.55457ccaa01c.json.gz +0 -0
  120. codex/static_root/manifest.json +32 -32
  121. codex/static_root/manifest.json.br +0 -0
  122. codex/static_root/manifest.json.gz +0 -0
  123. codex/static_root/pwa/{offline.37a4206d79f0.html → offline.7bfaf9f94bf9.html} +1 -1
  124. codex/static_root/pwa/offline.7bfaf9f94bf9.html.br +0 -0
  125. codex/static_root/pwa/offline.7bfaf9f94bf9.html.gz +0 -0
  126. codex/static_root/pwa/offline.html +1 -1
  127. codex/static_root/pwa/offline.html.br +0 -0
  128. codex/static_root/pwa/offline.html.gz +0 -0
  129. codex/static_root/staticfiles.json +1 -1
  130. codex/threads.py +1 -1
  131. codex/views/admin/api_key.py +3 -1
  132. codex/views/admin/flag.py +3 -1
  133. codex/views/admin/group.py +3 -1
  134. codex/views/admin/library.py +5 -4
  135. codex/views/admin/stats.py +10 -6
  136. codex/views/admin/tasks.py +35 -30
  137. codex/views/admin/user.py +4 -2
  138. codex/views/bookmark.py +6 -4
  139. codex/views/browser/base.py +30 -28
  140. codex/views/browser/browser.py +78 -80
  141. codex/views/browser/browser_annotations.py +15 -10
  142. codex/views/browser/browser_order_by.py +21 -16
  143. codex/views/browser/choices.py +37 -22
  144. codex/views/browser/filters/search.py +19 -16
  145. codex/views/browser/metadata.py +50 -41
  146. codex/views/cover.py +3 -1
  147. codex/views/download.py +4 -2
  148. codex/views/frontend.py +3 -2
  149. codex/views/mixins.py +13 -9
  150. codex/views/opds/authentication_v1.py +45 -41
  151. codex/views/opds/const.py +20 -13
  152. codex/views/opds/v1/entry/data.py +2 -1
  153. codex/views/opds/v1/facets.py +2 -1
  154. codex/views/opds/v1/feed.py +11 -4
  155. codex/views/opds/v1/links.py +8 -6
  156. codex/views/opds/v1/opensearch_v1.py +1 -1
  157. codex/views/opds/v2/feed.py +2 -1
  158. codex/views/opds/v2/publications.py +15 -12
  159. codex/views/reader/page.py +1 -1
  160. codex/views/session.py +50 -43
  161. codex/views/template.py +2 -2
  162. codex/websockets/listener.py +10 -7
  163. {codex-1.4.1.dist-info → codex-1.4.3.dist-info}/METADATA +24 -28
  164. {codex-1.4.1.dist-info → codex-1.4.3.dist-info}/RECORD +167 -167
  165. {codex-1.4.1.dist-info → codex-1.4.3.dist-info}/WHEEL +1 -1
  166. codex/static_root/assets/admin-12749881.ef0f50bac290.js +0 -41
  167. codex/static_root/assets/admin-12749881.ef0f50bac290.js.br +0 -0
  168. codex/static_root/assets/admin-12749881.ef0f50bac290.js.gz +0 -0
  169. codex/static_root/assets/admin-12749881.js +0 -41
  170. codex/static_root/assets/admin-12749881.js.br +0 -0
  171. codex/static_root/assets/admin-12749881.js.gz +0 -0
  172. codex/static_root/assets/admin-beda768d.a614eee46307.css +0 -1
  173. codex/static_root/assets/admin-beda768d.a614eee46307.css.br +0 -0
  174. codex/static_root/assets/admin-beda768d.a614eee46307.css.gz +0 -0
  175. codex/static_root/assets/admin-beda768d.css +0 -1
  176. codex/static_root/assets/admin-beda768d.css.br +0 -0
  177. codex/static_root/assets/admin-beda768d.css.gz +0 -0
  178. codex/static_root/assets/admin-drawer-panel-522f1e6c.089d70878270.js.br +0 -0
  179. codex/static_root/assets/admin-drawer-panel-522f1e6c.089d70878270.js.gz +0 -0
  180. codex/static_root/assets/admin-drawer-panel-522f1e6c.js.br +0 -0
  181. codex/static_root/assets/admin-drawer-panel-522f1e6c.js.gz +0 -0
  182. codex/static_root/assets/browser-7f7d7134.0fe3749b0f2f.css.br +0 -0
  183. codex/static_root/assets/browser-7f7d7134.0fe3749b0f2f.css.gz +0 -0
  184. codex/static_root/assets/browser-7f7d7134.css.br +0 -0
  185. codex/static_root/assets/browser-7f7d7134.css.gz +0 -0
  186. codex/static_root/assets/browser-af622672.d51aca96d64d.js +0 -1
  187. codex/static_root/assets/browser-af622672.d51aca96d64d.js.br +0 -0
  188. codex/static_root/assets/browser-af622672.d51aca96d64d.js.gz +0 -0
  189. codex/static_root/assets/browser-af622672.js +0 -1
  190. codex/static_root/assets/browser-af622672.js.br +0 -0
  191. codex/static_root/assets/browser-af622672.js.gz +0 -0
  192. codex/static_root/assets/http-error-5e17b794.77ceeb2d4641.js.br +0 -0
  193. codex/static_root/assets/http-error-5e17b794.77ceeb2d4641.js.gz +0 -0
  194. codex/static_root/assets/http-error-5e17b794.js.br +0 -0
  195. codex/static_root/assets/http-error-5e17b794.js.gz +0 -0
  196. codex/static_root/assets/main-0898f4bb.181e0145c642.css.br +0 -0
  197. codex/static_root/assets/main-0898f4bb.css.br +0 -0
  198. codex/static_root/assets/main-9e76a4c3.6844a407d14c.js +0 -1
  199. codex/static_root/assets/main-9e76a4c3.6844a407d14c.js.br +0 -0
  200. codex/static_root/assets/main-9e76a4c3.6844a407d14c.js.gz +0 -0
  201. codex/static_root/assets/main-9e76a4c3.js +0 -1
  202. codex/static_root/assets/main-9e76a4c3.js.br +0 -0
  203. codex/static_root/assets/main-9e76a4c3.js.gz +0 -0
  204. codex/static_root/assets/metadata-dialog-62c29ce0.8418785c0453.js +0 -1
  205. codex/static_root/assets/metadata-dialog-62c29ce0.8418785c0453.js.br +0 -0
  206. codex/static_root/assets/metadata-dialog-62c29ce0.8418785c0453.js.gz +0 -0
  207. codex/static_root/assets/metadata-dialog-62c29ce0.js +0 -1
  208. codex/static_root/assets/metadata-dialog-62c29ce0.js.br +0 -0
  209. codex/static_root/assets/metadata-dialog-62c29ce0.js.gz +0 -0
  210. codex/static_root/assets/metadata-dialog-cb306ffd.cc304996d7bb.css +0 -1
  211. codex/static_root/assets/metadata-dialog-cb306ffd.cc304996d7bb.css.br +0 -0
  212. codex/static_root/assets/metadata-dialog-cb306ffd.cc304996d7bb.css.gz +0 -0
  213. codex/static_root/assets/metadata-dialog-cb306ffd.css +0 -1
  214. codex/static_root/assets/metadata-dialog-cb306ffd.css.br +0 -0
  215. codex/static_root/assets/metadata-dialog-cb306ffd.css.gz +0 -0
  216. codex/static_root/assets/page-pdf-157ba97e.613d7c2beb77.js.br +0 -0
  217. codex/static_root/assets/page-pdf-157ba97e.613d7c2beb77.js.gz +0 -0
  218. codex/static_root/assets/page-pdf-157ba97e.js.br +0 -0
  219. codex/static_root/assets/page-pdf-157ba97e.js.gz +0 -0
  220. codex/static_root/assets/reader-36266549.0b2cf1291f27.js +0 -1
  221. codex/static_root/assets/reader-36266549.0b2cf1291f27.js.br +0 -0
  222. codex/static_root/assets/reader-36266549.0b2cf1291f27.js.gz +0 -0
  223. codex/static_root/assets/reader-36266549.js +0 -1
  224. codex/static_root/assets/reader-36266549.js.br +0 -0
  225. codex/static_root/assets/reader-36266549.js.gz +0 -0
  226. codex/static_root/assets/reader-7f004141.506eecc6954b.css +0 -1
  227. codex/static_root/assets/reader-7f004141.506eecc6954b.css.br +0 -0
  228. codex/static_root/assets/reader-7f004141.506eecc6954b.css.gz +0 -0
  229. codex/static_root/assets/reader-7f004141.css +0 -1
  230. codex/static_root/assets/reader-7f004141.css.br +0 -0
  231. codex/static_root/assets/reader-7f004141.css.gz +0 -0
  232. codex/static_root/manifest.d2f93a519ada.json.br +0 -0
  233. codex/static_root/manifest.d2f93a519ada.json.gz +0 -0
  234. codex/static_root/pwa/offline.37a4206d79f0.html.br +0 -0
  235. codex/static_root/pwa/offline.37a4206d79f0.html.gz +0 -0
  236. {codex-1.4.1.dist-info → codex-1.4.3.dist-info}/LICENSE +0 -0
  237. {codex-1.4.1.dist-info → codex-1.4.3.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,6 @@
1
1
  """Generated by Django 4.0.4 on 2022-04-26 03:09."""
2
2
  from pathlib import Path
3
+ from typing import ClassVar
3
4
 
4
5
  from django.db import migrations, models
5
6
 
@@ -72,11 +73,11 @@ def add_library_folders(apps, _schema_editor):
72
73
  class Migration(migrations.Migration):
73
74
  """Remove cover_image, sort_name. add issue_suffix & file_format."""
74
75
 
75
- dependencies = [
76
+ dependencies: ClassVar[list] = [
76
77
  ("codex", "0013_int_issue_count_longer_charfields"),
77
78
  ]
78
79
 
79
- operations = [
80
+ operations: ClassVar[list] = [
80
81
  migrations.AlterField( # Fixes django 4.1 bug removing fields
81
82
  model_name="comic",
82
83
  name="sort_name",
@@ -1,5 +1,6 @@
1
1
  """Fix no parent folder comics."""
2
2
  from pathlib import Path
3
+ from typing import ClassVar
3
4
 
4
5
  from django.db import migrations
5
6
 
@@ -32,8 +33,10 @@ def fix_no_parent_folder_comics(apps, _schema_editor):
32
33
  class Migration(migrations.Migration):
33
34
  """Fix top level comics."""
34
35
 
35
- dependencies = [("codex", "0014_pdf_issue_suffix_remove_cover_image_sort_name")]
36
+ dependencies: ClassVar[list] = [
37
+ ("codex", "0014_pdf_issue_suffix_remove_cover_image_sort_name")
38
+ ]
36
39
 
37
- operations = [
40
+ operations: ClassVar[list] = [
38
41
  migrations.RunPython(fix_no_parent_folder_comics),
39
42
  ]
@@ -1,8 +1,8 @@
1
1
  """Generated by Django 4.0.6 on 2022-07-21 07:11."""
2
-
3
2
  import os
4
3
  import shutil
5
4
  from pathlib import Path
5
+ from typing import ClassVar
6
6
 
7
7
  from django.db import migrations, models
8
8
 
@@ -42,11 +42,11 @@ def remove_old_caches(_apps, _schema_editor):
42
42
  class Migration(migrations.Migration):
43
43
  """v0.11.0 migrations."""
44
44
 
45
- dependencies = [
45
+ dependencies: ClassVar[list] = [
46
46
  ("codex", "0015_link_comics_to_top_level_folders"),
47
47
  ]
48
48
 
49
- operations = [
49
+ operations: ClassVar[list] = [
50
50
  migrations.RemoveField(
51
51
  model_name="library",
52
52
  name="schema_version",
@@ -1,8 +1,8 @@
1
1
  """Generated by Django 4.1 on 2022-08-13 19:52."""
2
-
3
2
  import os
4
3
  import shutil
5
4
  from pathlib import Path
5
+ from typing import ClassVar
6
6
 
7
7
  from django.db import migrations, models
8
8
 
@@ -26,11 +26,11 @@ def remove_null_librarian_statuses(apps, _schema_editor):
26
26
  class Migration(migrations.Migration):
27
27
  """Choices and max_length changes, mostly."""
28
28
 
29
- dependencies = [
29
+ dependencies: ClassVar[list] = [
30
30
  ("codex", "0016_remove_comic_cover_path_librarianstatus"),
31
31
  ]
32
32
 
33
- operations = [
33
+ operations: ClassVar[list] = [
34
34
  migrations.RunPython(clear_covers),
35
35
  migrations.RunPython(remove_null_librarian_statuses),
36
36
  migrations.AlterModelOptions(
@@ -1,4 +1,5 @@
1
1
  """Generated by Django 4.1 on 2022-08-24 01:49."""
2
+ from typing import ClassVar
2
3
 
3
4
  from django.conf import settings
4
5
  from django.db import migrations, models
@@ -7,13 +8,13 @@ from django.db import migrations, models
7
8
  class Migration(migrations.Migration):
8
9
  """Rename Bookmark table & use '' for CharField nulls."""
9
10
 
10
- dependencies = [
11
+ dependencies: ClassVar[list] = [
11
12
  ("sessions", "0001_initial"),
12
13
  migrations.swappable_dependency(settings.AUTH_USER_MODEL),
13
14
  ("codex", "0017_alter_timestamp_options_alter_adminflag_name_and_more"),
14
15
  ]
15
16
 
16
- operations = [
17
+ operations: ClassVar[list] = [
17
18
  migrations.RenameField(
18
19
  model_name="UserBookmark", old_name="bookmark", new_name="page"
19
20
  ),
@@ -1,4 +1,5 @@
1
1
  """Generated by Django 4.1.4 on 2022-12-07 20:25."""
2
+ from typing import ClassVar
2
3
 
3
4
  from django.db import migrations
4
5
 
@@ -6,11 +7,11 @@ from django.db import migrations
6
7
  class Migration(migrations.Migration):
7
8
  """Delete fake model used in Django Admin."""
8
9
 
9
- dependencies = [
10
+ dependencies: ClassVar[list] = [
10
11
  ("codex", "0018_rename_userbookmark_bookmark"),
11
12
  ]
12
13
 
13
- operations = [
14
+ operations: ClassVar[list] = [
14
15
  migrations.DeleteModel(
15
16
  name="QueueJob",
16
17
  ),
@@ -1,4 +1,5 @@
1
1
  """Generated by Django 4.1.5 on 2023-01-11 08:12."""
2
+ from typing import ClassVar
2
3
 
3
4
  from django.db import migrations
4
5
 
@@ -12,11 +13,11 @@ def rename_search_timestamp(apps, _schema_editor):
12
13
  class Migration(migrations.Migration):
13
14
  """Run migrations."""
14
15
 
15
- dependencies = [
16
+ dependencies: ClassVar[list] = [
16
17
  ("codex", "0019_delete_queuejob"),
17
18
  ]
18
19
 
19
- operations = [
20
+ operations: ClassVar[list] = [
20
21
  migrations.RunPython(rename_search_timestamp),
21
22
  migrations.AlterUniqueTogether(
22
23
  name="searchresult",
@@ -1,4 +1,5 @@
1
1
  """Generated by Django 4.1.7 on 2023-02-26 21:49."""
2
+ from typing import ClassVar
2
3
 
3
4
  from django.db import migrations, models
4
5
 
@@ -13,11 +14,11 @@ def ensure_fit_to_has_valid_choices(apps, _schema_editor):
13
14
  class Migration(migrations.Migration):
14
15
  """Add bookmark choices to database."""
15
16
 
16
- dependencies = [
17
+ dependencies: ClassVar[list] = [
17
18
  ("codex", "0020_remove_search_tables"),
18
19
  ]
19
20
 
20
- operations = [
21
+ operations: ClassVar[list] = [
21
22
  migrations.RunPython(ensure_fit_to_has_valid_choices),
22
23
  migrations.AlterField(
23
24
  model_name="bookmark",
@@ -1,4 +1,5 @@
1
1
  """Generated by Django 4.1.7 on 2023-03-10 07:34."""
2
+ from typing import ClassVar
2
3
 
3
4
  import django.db.models.deletion
4
5
  from django.conf import settings
@@ -8,12 +9,12 @@ from django.db import migrations, models
8
9
  class Migration(migrations.Migration):
9
10
  """Migrate."""
10
11
 
11
- dependencies = [
12
+ dependencies: ClassVar[list] = [
12
13
  migrations.swappable_dependency(settings.AUTH_USER_MODEL),
13
14
  ("codex", "0021_bookmark_fit_to_choices_read_in_reverse"),
14
15
  ]
15
16
 
16
- operations = [
17
+ operations: ClassVar[list] = [
17
18
  migrations.AlterField(
18
19
  model_name="librarianstatus",
19
20
  name="complete",
@@ -1,5 +1,6 @@
1
1
  """Generated by Django 4.1.7 on 2023-03-26 20:32."""
2
2
  from pathlib import Path
3
+ from typing import ClassVar
3
4
 
4
5
  from django.db import connection, migrations, models
5
6
 
@@ -97,11 +98,11 @@ def prepare_timestamps(apps, _schema_editor):
97
98
  class Migration(migrations.Migration):
98
99
  """Prepare data and then migrate schema."""
99
100
 
100
- dependencies = [
101
+ dependencies: ClassVar[list] = [
101
102
  ("codex", "0022_bookmark_vertical_useractive_null_statuses"),
102
103
  ]
103
104
 
104
- operations = [
105
+ operations: ClassVar[list] = [
105
106
  # PREPARE
106
107
  migrations.RunPython(prepare_librarianstatus),
107
108
  migrations.RunPython(prepare_adminflags),
@@ -1,16 +1,18 @@
1
1
  """Generated by Django 4.2.1 on 2023-05-10 22:44."""
2
2
 
3
+ from typing import ClassVar
4
+
3
5
  from django.db import migrations, models
4
6
 
5
7
 
6
8
  class Migration(migrations.Migration):
7
9
  """Add fields."""
8
10
 
9
- dependencies = [
11
+ dependencies: ClassVar[list] = [
10
12
  ("codex", "0023_rename_credit_creator_and_more"),
11
13
  ]
12
14
 
13
- operations = [
15
+ operations: ClassVar[list] = [
14
16
  migrations.AddField(
15
17
  model_name="comic",
16
18
  name="gtin",
@@ -1,4 +1,6 @@
1
1
  """Generated by Django 4.2.1 on 2023-05-17 19:22."""
2
+ from typing import ClassVar
3
+
2
4
  import django.db.models.deletion
3
5
  from django.db import migrations, models
4
6
 
@@ -32,11 +34,11 @@ def _create_story_arc_numbers(apps, _schema_editor):
32
34
  class Migration(migrations.Migration):
33
35
  """Run Migrations."""
34
36
 
35
- dependencies = [
37
+ dependencies: ClassVar[list] = [
36
38
  ("codex", "0024_comic_gtin_comic_story_arc_number"),
37
39
  ]
38
40
 
39
- operations = [
41
+ operations: ClassVar[list] = [
40
42
  migrations.CreateModel(
41
43
  name="StoryArcNumber",
42
44
  fields=[
codex/models.py CHANGED
@@ -266,14 +266,14 @@ class WatchedPath(BrowserGroupModel):
266
266
  on_delete=CASCADE,
267
267
  null=True,
268
268
  )
269
- ZERO_STAT = [0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0]
269
+ ZERO_STAT = (0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0)
270
270
 
271
271
  def set_stat(self):
272
272
  """Set select stat params from the filesystem."""
273
273
  st_record = Path(self.path).stat()
274
274
  # Converting os.stat directly to a list or tuple saves
275
275
  # mtime as an int and causes problems.
276
- st = self.ZERO_STAT.copy()
276
+ st = list(self.ZERO_STAT)
277
277
  st[0] = st_record.st_mode
278
278
  st[1] = st_record.st_ino
279
279
  # st[2] = st_record.st_dev is ignored by diff
@@ -475,8 +475,7 @@ class Comic(WatchedPath):
475
475
  names.append(obj.name)
476
476
 
477
477
  title = " ".join(filter(None, names)).strip(" .")
478
- title = cls._RE_COMBINE_WHITESPACE.sub(" ", title).strip()
479
- return title
478
+ return cls._RE_COMBINE_WHITESPACE.sub(" ", title).strip()
480
479
 
481
480
  @classmethod
482
481
  def get_filename(cls, obj):
codex/search/backend.py CHANGED
@@ -2,6 +2,7 @@
2
2
  from math import ceil
3
3
  from multiprocessing import cpu_count
4
4
  from pathlib import Path
5
+ from types import MappingProxyType
5
6
 
6
7
  from django.utils.timezone import now
7
8
  from haystack.backends.whoosh_backend import (
@@ -97,34 +98,36 @@ TEXT_ANALYZER = (
97
98
  class CodexSearchBackend(WhooshSearchBackend, WorkerBaseMixin):
98
99
  """Custom Whoosh Backend."""
99
100
 
100
- FIELDMAP = {
101
- "characters": ["category", "character"],
102
- "created_at": ["created"],
103
- "creators": [
104
- "author",
105
- "authors",
106
- "contributor",
107
- "contributors",
108
- "creator",
109
- "creator",
110
- "creators",
111
- ],
112
- "community_rating": gen_multipart_field_aliases("community_rating"),
113
- "critical_rating": gen_multipart_field_aliases("critical_rating"),
114
- "genres": ["genre"],
115
- "file_type": ["type"],
116
- "locations": ["location"],
117
- "name": ["title"],
118
- "original_format": ["format"],
119
- "page_count": ["pages"],
120
- "read_ltr": ["ltr"],
121
- "series_groups": gen_multipart_field_aliases("series_groups"),
122
- "scan_info": ["scan"],
123
- "story_arcs": gen_multipart_field_aliases("story_arcs"),
124
- "tags": ["tag"],
125
- "teams": ["team"],
126
- "updated_at": ["updated"],
127
- }
101
+ FIELDMAP = MappingProxyType(
102
+ {
103
+ "characters": ["category", "character"],
104
+ "created_at": ["created"],
105
+ "creators": [
106
+ "author",
107
+ "authors",
108
+ "contributor",
109
+ "contributors",
110
+ "creator",
111
+ "creator",
112
+ "creators",
113
+ ],
114
+ "community_rating": gen_multipart_field_aliases("community_rating"),
115
+ "critical_rating": gen_multipart_field_aliases("critical_rating"),
116
+ "genres": ["genre"],
117
+ "file_type": ["type"],
118
+ "locations": ["location"],
119
+ "name": ["title"],
120
+ "original_format": ["format"],
121
+ "page_count": ["pages"],
122
+ "read_ltr": ["ltr"],
123
+ "series_groups": gen_multipart_field_aliases("series_groups"),
124
+ "scan_info": ["scan"],
125
+ "story_arcs": gen_multipart_field_aliases("story_arcs"),
126
+ "tags": ["tag"],
127
+ "teams": ["team"],
128
+ "updated_at": ["updated"],
129
+ }
130
+ )
128
131
  RESERVED_CHARACTERS = ()
129
132
  RESERVED_WORDS = ()
130
133
  FIELD_ALIAS_PLUGIN = FieldAliasPlugin(FIELDMAP)
@@ -146,8 +149,8 @@ class CodexSearchBackend(WhooshSearchBackend, WorkerBaseMixin):
146
149
  )
147
150
  WRITER_PERIOD = 0 # No period timer.
148
151
  WRITER_LIMIT = 1000
149
- COMMITARGS_MERGE_SMALL = {"merge": True}
150
- COMMITARGS_NO_MERGE = {"merge": False}
152
+ COMMITARGS_MERGE_SMALL = MappingProxyType({"merge": True})
153
+ COMMITARGS_NO_MERGE = MappingProxyType({"merge": False})
151
154
  _SELECT_RELATED_FIELDS = ("publisher", "imprint", "series", "volume")
152
155
  _PREFETCH_RELATED_FIELDS = (
153
156
  "characters",
@@ -480,5 +483,5 @@ class CodexSearchBackend(WhooshSearchBackend, WorkerBaseMixin):
480
483
  """Merge small segments of the index."""
481
484
  if not self.setup_complete:
482
485
  self.setup(False)
483
- writer = self.get_writer({"merge": True})
486
+ writer = self.get_writer(MappingProxyType({"merge": True}))
484
487
  writer.close()
codex/serializers/auth.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Codex Auth Serializers."""
2
+ from types import MappingProxyType
2
3
 
3
4
  from django.contrib.auth.models import User
4
5
  from rest_framework.fields import BooleanField, CharField
@@ -60,7 +61,7 @@ class UserCreateSerializer(ModelSerializer, TimezoneSerializer):
60
61
 
61
62
  model = User
62
63
  fields = ("username", "password", "timezone")
63
- extra_kwargs = {"password": {"write_only": True}}
64
+ extra_kwargs = MappingProxyType({"password": {"write_only": True}})
64
65
 
65
66
 
66
67
  class UserLoginSerializer(UserCreateSerializer):
@@ -98,6 +98,7 @@ def _build_show_defaults(settings_group_list):
98
98
  for choice in settings_group_list:
99
99
  key = choice["value"]
100
100
  show[key] = choice.get("default", False)
101
+ # Returning a mapping proxy makes deepcopy into dict harder
101
102
  return show
102
103
 
103
104