django-nativemojo 0.1.15__py3-none-any.whl → 0.1.16__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.
Files changed (221) hide show
  1. {django_nativemojo-0.1.15.dist-info → django_nativemojo-0.1.16.dist-info}/METADATA +3 -1
  2. django_nativemojo-0.1.16.dist-info/RECORD +302 -0
  3. mojo/__init__.py +1 -1
  4. mojo/apps/account/management/commands/serializer_admin.py +121 -1
  5. mojo/apps/account/migrations/0006_add_device_tracking_models.py +72 -0
  6. mojo/apps/account/migrations/0007_delete_userdevicelocation.py +16 -0
  7. mojo/apps/account/migrations/0008_userdevicelocation.py +33 -0
  8. mojo/apps/account/migrations/0009_geolocatedip_subnet.py +18 -0
  9. mojo/apps/account/migrations/0010_group_avatar.py +20 -0
  10. mojo/apps/account/migrations/0011_user_org_registereddevice_pushconfig_and_more.py +118 -0
  11. mojo/apps/account/migrations/0012_remove_pushconfig_apns_key_file_and_more.py +21 -0
  12. mojo/apps/account/migrations/0013_pushconfig_test_mode_alter_pushconfig_apns_enabled_and_more.py +28 -0
  13. mojo/apps/account/migrations/0014_notificationdelivery_data_payload_and_more.py +48 -0
  14. mojo/apps/account/models/__init__.py +2 -0
  15. mojo/apps/account/models/device.py +281 -0
  16. mojo/apps/account/models/group.py +294 -8
  17. mojo/apps/account/models/member.py +14 -1
  18. mojo/apps/account/models/push/__init__.py +4 -0
  19. mojo/apps/account/models/push/config.py +112 -0
  20. mojo/apps/account/models/push/delivery.py +93 -0
  21. mojo/apps/account/models/push/device.py +66 -0
  22. mojo/apps/account/models/push/template.py +99 -0
  23. mojo/apps/account/models/user.py +190 -17
  24. mojo/apps/account/rest/__init__.py +2 -0
  25. mojo/apps/account/rest/device.py +39 -0
  26. mojo/apps/account/rest/group.py +8 -0
  27. mojo/apps/account/rest/push.py +187 -0
  28. mojo/apps/account/rest/user.py +95 -5
  29. mojo/apps/account/services/__init__.py +1 -0
  30. mojo/apps/account/services/push.py +363 -0
  31. mojo/apps/aws/migrations/0001_initial.py +206 -0
  32. mojo/apps/aws/migrations/0002_emaildomain_can_recv_emaildomain_can_send_and_more.py +28 -0
  33. mojo/apps/aws/migrations/0003_mailbox_is_domain_default_mailbox_is_system_default_and_more.py +31 -0
  34. mojo/apps/aws/migrations/0004_s3bucket.py +39 -0
  35. mojo/apps/aws/migrations/0005_alter_emaildomain_region_delete_s3bucket.py +21 -0
  36. mojo/apps/aws/models/__init__.py +19 -0
  37. mojo/apps/aws/models/email_attachment.py +99 -0
  38. mojo/apps/aws/models/email_domain.py +218 -0
  39. mojo/apps/aws/models/email_template.py +132 -0
  40. mojo/apps/aws/models/incoming_email.py +197 -0
  41. mojo/apps/aws/models/mailbox.py +288 -0
  42. mojo/apps/aws/models/sent_message.py +175 -0
  43. mojo/apps/aws/rest/__init__.py +6 -0
  44. mojo/apps/aws/rest/email.py +33 -0
  45. mojo/apps/aws/rest/email_ops.py +183 -0
  46. mojo/apps/aws/rest/messages.py +32 -0
  47. mojo/apps/aws/rest/send.py +101 -0
  48. mojo/apps/aws/rest/sns.py +403 -0
  49. mojo/apps/aws/rest/templates.py +19 -0
  50. mojo/apps/aws/services/__init__.py +32 -0
  51. mojo/apps/aws/services/email.py +390 -0
  52. mojo/apps/aws/services/email_ops.py +548 -0
  53. mojo/apps/docit/__init__.py +6 -0
  54. mojo/apps/docit/markdown_plugins/syntax_highlight.py +25 -0
  55. mojo/apps/docit/markdown_plugins/toc.py +12 -0
  56. mojo/apps/docit/migrations/0001_initial.py +113 -0
  57. mojo/apps/docit/migrations/0002_alter_book_modified_by_alter_page_modified_by.py +26 -0
  58. mojo/apps/docit/migrations/0003_alter_book_group.py +20 -0
  59. mojo/apps/docit/models/__init__.py +17 -0
  60. mojo/apps/docit/models/asset.py +231 -0
  61. mojo/apps/docit/models/book.py +227 -0
  62. mojo/apps/docit/models/page.py +319 -0
  63. mojo/apps/docit/models/page_revision.py +203 -0
  64. mojo/apps/docit/rest/__init__.py +10 -0
  65. mojo/apps/docit/rest/asset.py +17 -0
  66. mojo/apps/docit/rest/book.py +22 -0
  67. mojo/apps/docit/rest/page.py +22 -0
  68. mojo/apps/docit/rest/page_revision.py +17 -0
  69. mojo/apps/docit/services/__init__.py +11 -0
  70. mojo/apps/docit/services/docit.py +315 -0
  71. mojo/apps/docit/services/markdown.py +44 -0
  72. mojo/apps/fileman/backends/s3.py +209 -0
  73. mojo/apps/fileman/models/file.py +45 -9
  74. mojo/apps/fileman/models/manager.py +269 -3
  75. mojo/apps/incident/migrations/0007_event_uid.py +18 -0
  76. mojo/apps/incident/migrations/0008_ticket_ticketnote.py +55 -0
  77. mojo/apps/incident/migrations/0009_incident_status.py +18 -0
  78. mojo/apps/incident/migrations/0010_event_country_code.py +18 -0
  79. mojo/apps/incident/migrations/0011_incident_country_code.py +18 -0
  80. mojo/apps/incident/migrations/0012_alter_incident_status.py +18 -0
  81. mojo/apps/incident/models/__init__.py +1 -0
  82. mojo/apps/incident/models/event.py +35 -0
  83. mojo/apps/incident/models/incident.py +2 -0
  84. mojo/apps/incident/models/ticket.py +62 -0
  85. mojo/apps/incident/reporter.py +21 -3
  86. mojo/apps/incident/rest/__init__.py +1 -0
  87. mojo/apps/incident/rest/ticket.py +43 -0
  88. mojo/apps/jobs/__init__.py +489 -0
  89. mojo/apps/jobs/adapters.py +24 -0
  90. mojo/apps/jobs/cli.py +616 -0
  91. mojo/apps/jobs/daemon.py +370 -0
  92. mojo/apps/jobs/examples/sample_jobs.py +376 -0
  93. mojo/apps/jobs/examples/webhook_examples.py +203 -0
  94. mojo/apps/jobs/handlers/__init__.py +5 -0
  95. mojo/apps/jobs/handlers/webhook.py +317 -0
  96. mojo/apps/jobs/job_engine.py +734 -0
  97. mojo/apps/jobs/keys.py +203 -0
  98. mojo/apps/jobs/local_queue.py +363 -0
  99. mojo/apps/jobs/management/__init__.py +3 -0
  100. mojo/apps/jobs/management/commands/__init__.py +3 -0
  101. mojo/apps/jobs/manager.py +1327 -0
  102. mojo/apps/jobs/migrations/0001_initial.py +97 -0
  103. mojo/apps/jobs/migrations/0002_alter_job_max_retries_joblog.py +39 -0
  104. mojo/apps/jobs/models/__init__.py +6 -0
  105. mojo/apps/jobs/models/job.py +441 -0
  106. mojo/apps/jobs/rest/__init__.py +2 -0
  107. mojo/apps/jobs/rest/control.py +466 -0
  108. mojo/apps/jobs/rest/jobs.py +421 -0
  109. mojo/apps/jobs/scheduler.py +571 -0
  110. mojo/apps/jobs/services/__init__.py +6 -0
  111. mojo/apps/jobs/services/job_actions.py +465 -0
  112. mojo/apps/jobs/settings.py +209 -0
  113. mojo/apps/logit/models/log.py +3 -0
  114. mojo/apps/metrics/__init__.py +8 -1
  115. mojo/apps/metrics/redis_metrics.py +198 -0
  116. mojo/apps/metrics/rest/__init__.py +3 -0
  117. mojo/apps/metrics/rest/categories.py +266 -0
  118. mojo/apps/metrics/rest/helpers.py +48 -0
  119. mojo/apps/metrics/rest/permissions.py +99 -0
  120. mojo/apps/metrics/rest/values.py +277 -0
  121. mojo/apps/metrics/utils.py +17 -0
  122. mojo/decorators/http.py +40 -1
  123. mojo/helpers/aws/__init__.py +11 -7
  124. mojo/helpers/aws/inbound_email.py +309 -0
  125. mojo/helpers/aws/kms.py +413 -0
  126. mojo/helpers/aws/ses_domain.py +959 -0
  127. mojo/helpers/crypto/__init__.py +1 -1
  128. mojo/helpers/crypto/utils.py +15 -0
  129. mojo/helpers/location/__init__.py +2 -0
  130. mojo/helpers/location/countries.py +262 -0
  131. mojo/helpers/location/geolocation.py +196 -0
  132. mojo/helpers/logit.py +37 -0
  133. mojo/helpers/redis/__init__.py +2 -0
  134. mojo/helpers/redis/adapter.py +606 -0
  135. mojo/helpers/redis/client.py +48 -0
  136. mojo/helpers/redis/pool.py +225 -0
  137. mojo/helpers/request.py +8 -0
  138. mojo/helpers/response.py +8 -0
  139. mojo/middleware/auth.py +1 -1
  140. mojo/middleware/cors.py +40 -0
  141. mojo/middleware/logging.py +131 -12
  142. mojo/middleware/mojo.py +5 -0
  143. mojo/models/rest.py +271 -57
  144. mojo/models/secrets.py +86 -0
  145. mojo/serializers/__init__.py +16 -10
  146. mojo/serializers/core/__init__.py +90 -0
  147. mojo/serializers/core/cache/__init__.py +121 -0
  148. mojo/serializers/core/cache/backends.py +518 -0
  149. mojo/serializers/core/cache/base.py +102 -0
  150. mojo/serializers/core/cache/disabled.py +181 -0
  151. mojo/serializers/core/cache/memory.py +287 -0
  152. mojo/serializers/core/cache/redis.py +533 -0
  153. mojo/serializers/core/cache/utils.py +454 -0
  154. mojo/serializers/{manager.py → core/manager.py} +53 -4
  155. mojo/serializers/core/serializer.py +475 -0
  156. mojo/serializers/{advanced/formats → formats}/csv.py +116 -139
  157. mojo/serializers/suggested_improvements.md +388 -0
  158. testit/client.py +1 -1
  159. testit/helpers.py +14 -0
  160. testit/runner.py +23 -6
  161. django_nativemojo-0.1.15.dist-info/RECORD +0 -234
  162. mojo/apps/notify/README.md +0 -91
  163. mojo/apps/notify/README_NOTIFICATIONS.md +0 -566
  164. mojo/apps/notify/admin.py +0 -52
  165. mojo/apps/notify/handlers/example_handlers.py +0 -516
  166. mojo/apps/notify/handlers/ses/__init__.py +0 -25
  167. mojo/apps/notify/handlers/ses/complaint.py +0 -25
  168. mojo/apps/notify/handlers/ses/message.py +0 -86
  169. mojo/apps/notify/management/commands/__init__.py +0 -1
  170. mojo/apps/notify/management/commands/process_notifications.py +0 -370
  171. mojo/apps/notify/mod +0 -0
  172. mojo/apps/notify/models/__init__.py +0 -12
  173. mojo/apps/notify/models/account.py +0 -128
  174. mojo/apps/notify/models/attachment.py +0 -24
  175. mojo/apps/notify/models/bounce.py +0 -68
  176. mojo/apps/notify/models/complaint.py +0 -40
  177. mojo/apps/notify/models/inbox.py +0 -113
  178. mojo/apps/notify/models/inbox_message.py +0 -173
  179. mojo/apps/notify/models/outbox.py +0 -129
  180. mojo/apps/notify/models/outbox_message.py +0 -288
  181. mojo/apps/notify/models/template.py +0 -30
  182. mojo/apps/notify/providers/aws.py +0 -73
  183. mojo/apps/notify/rest/ses.py +0 -0
  184. mojo/apps/notify/utils/__init__.py +0 -2
  185. mojo/apps/notify/utils/notifications.py +0 -404
  186. mojo/apps/notify/utils/parsing.py +0 -202
  187. mojo/apps/notify/utils/render.py +0 -144
  188. mojo/apps/tasks/README.md +0 -118
  189. mojo/apps/tasks/__init__.py +0 -44
  190. mojo/apps/tasks/manager.py +0 -644
  191. mojo/apps/tasks/rest/__init__.py +0 -2
  192. mojo/apps/tasks/rest/hooks.py +0 -0
  193. mojo/apps/tasks/rest/tasks.py +0 -76
  194. mojo/apps/tasks/runner.py +0 -439
  195. mojo/apps/tasks/task.py +0 -99
  196. mojo/apps/tasks/tq_handlers.py +0 -132
  197. mojo/helpers/crypto/__pycache__/hash.cpython-310.pyc +0 -0
  198. mojo/helpers/crypto/__pycache__/sign.cpython-310.pyc +0 -0
  199. mojo/helpers/crypto/__pycache__/utils.cpython-310.pyc +0 -0
  200. mojo/helpers/redis.py +0 -10
  201. mojo/models/meta.py +0 -262
  202. mojo/serializers/advanced/README.md +0 -363
  203. mojo/serializers/advanced/__init__.py +0 -247
  204. mojo/serializers/advanced/formats/__init__.py +0 -28
  205. mojo/serializers/advanced/formats/excel.py +0 -516
  206. mojo/serializers/advanced/formats/json.py +0 -239
  207. mojo/serializers/advanced/formats/response.py +0 -485
  208. mojo/serializers/advanced/serializer.py +0 -568
  209. mojo/serializers/optimized.py +0 -618
  210. {django_nativemojo-0.1.15.dist-info → django_nativemojo-0.1.16.dist-info}/LICENSE +0 -0
  211. {django_nativemojo-0.1.15.dist-info → django_nativemojo-0.1.16.dist-info}/NOTICE +0 -0
  212. {django_nativemojo-0.1.15.dist-info → django_nativemojo-0.1.16.dist-info}/WHEEL +0 -0
  213. /mojo/apps/{notify → aws/migrations}/__init__.py +0 -0
  214. /mojo/apps/{notify/handlers → docit/markdown_plugins}/__init__.py +0 -0
  215. /mojo/apps/{notify/management → docit/migrations}/__init__.py +0 -0
  216. /mojo/apps/{notify/providers → jobs/examples}/__init__.py +0 -0
  217. /mojo/apps/{notify/rest → jobs/migrations}/__init__.py +0 -0
  218. /mojo/{serializers → rest}/openapi.py +0 -0
  219. /mojo/serializers/{settings_example.py → examples/settings.py} +0 -0
  220. /mojo/{apps/notify/handlers/ses/bounce.py → serializers/formats/__init__.py} +0 -0
  221. /mojo/serializers/{advanced/formats → formats}/localizers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-nativemojo
3
- Version: 0.1.15
3
+ Version: 0.1.16
4
4
  Summary: A REST framework for DJANGO with some extra apps that make it easy to provide a secure robust graph like RESIT API.
5
5
  License: MIT
6
6
  Author: MOJO Dev Team
@@ -17,7 +17,9 @@ Requires-Dist: django (>=4.2.18,<6.0.0)
17
17
  Requires-Dist: django-cors-headers (>=4.7.0,<5.0.0)
18
18
  Requires-Dist: faker (>=35.2.0,<36.0.0)
19
19
  Requires-Dist: gevent (>=25.5.1,<26.0.0)
20
+ Requires-Dist: mistune (>=3.0.2,<4.0.0)
20
21
  Requires-Dist: pycryptodome (>=3.21.0,<4.0.0)
22
+ Requires-Dist: pygments (>=2.18.0,<3.0.0)
21
23
  Requires-Dist: pyjwt (>=2.10.1,<3.0.0)
22
24
  Requires-Dist: pyobjict (>=2.0.2,<4.0.0)
23
25
  Requires-Dist: pytz (>=2025.1,<2026.0)
@@ -0,0 +1,302 @@
1
+ mojo/__init__.py,sha256=UJNo1FEKIT_Wmp0HszwgwG-eIHNED4q9frkrbtwGudI,71
2
+ mojo/apps/account/__init__.py,sha256=RwxmQqhA0Pub7VSpEHplzPYjfPBBzioocJeQ8pCNeZ4,46
3
+ mojo/apps/account/admin.py,sha256=sE4GxFX9-g-vvNWf22LOqlbQdKK47O9sKP-ohdBpmiE,3026
4
+ mojo/apps/account/apps.py,sha256=CCK2aJu19BpDq_uDI8DIqJFbRmfudzY9KZWahcbYLbE,539
5
+ mojo/apps/account/management/__init__.py,sha256=vSTSprFOr42paP838wrW23zVG44yA0koBfInXVwKQ0A,121
6
+ mojo/apps/account/management/commands/__init__.py,sha256=QsFr7gQcuPOvlg_VvSRnhQV-meDaqkCufBjucsLEaPI,199
7
+ mojo/apps/account/management/commands/serializer_admin.py,sha256=rAxayxJVrOPLQKsX2CzHOd2WgsCyC7hjXn1yNyIqZjM,24666
8
+ mojo/apps/account/migrations/0001_initial.py,sha256=qOwAHtdgyTI-ZGGOnC2ZUn-NSqlyp1z5c6uXvCZBbNE,4220
9
+ mojo/apps/account/migrations/0002_user_is_email_verified_user_is_phone_verified.py,sha256=tBGQ9p7ADhFGGTOXDBslXK5Q4igfpbjI3j1IXqq5064,549
10
+ mojo/apps/account/migrations/0003_group_mojo_secrets_user_mojo_secrets.py,sha256=il2zEdYBGgnUa1ybes3AGPx1RykenlnXr-1nIlhVawU,616
11
+ mojo/apps/account/migrations/0004_user_avatar.py,sha256=yUfyY7nOWIZrw2EfuGmrFbWMr40fW117dpFw3gVLXDI,589
12
+ mojo/apps/account/migrations/0005_group_last_activity.py,sha256=l68nR0UoewXAonqKdbbzB8k4BqHQPuZZj1MmAWZ8Ryc,413
13
+ mojo/apps/account/migrations/0006_add_device_tracking_models.py,sha256=_G6IC_9NS4Vmv_MLwdV1SuNuULxZopnpBT1LeYaFrrU,3944
14
+ mojo/apps/account/migrations/0007_delete_userdevicelocation.py,sha256=-bvKXfoCXsjdLLgTpOvpD788_5nsS6OIkWgpmBqfGQo,316
15
+ mojo/apps/account/migrations/0008_userdevicelocation.py,sha256=R6q2t6HySmIbkT2tk2LMs-O-zW-s0ebt4squ1fACBFU,1492
16
+ mojo/apps/account/migrations/0009_geolocatedip_subnet.py,sha256=K6b2mQsj71fgjM2e_5LcAZwfIHPWmAPm1VwIsdU5LOA,431
17
+ mojo/apps/account/migrations/0010_group_avatar.py,sha256=sq-bzkGR7IyODkpOIm09qCdWTkbX9rMNkNxM3tccaVQ,573
18
+ mojo/apps/account/migrations/0011_user_org_registereddevice_pushconfig_and_more.py,sha256=94XeRJqJs4xB1bt1r7cICP8kTNh_MorJ-RFVppvVRxg,7828
19
+ mojo/apps/account/migrations/0012_remove_pushconfig_apns_key_file_and_more.py,sha256=Jb8WSyLuDarF-7OJfDqp0gUQee4YG14CCDFNM0yhdfA,482
20
+ mojo/apps/account/migrations/0013_pushconfig_test_mode_alter_pushconfig_apns_enabled_and_more.py,sha256=0VfBEp4JpXTN0OIKiRcVby8jR60MB46tuyBL_dXTpI4,949
21
+ mojo/apps/account/migrations/0014_notificationdelivery_data_payload_and_more.py,sha256=TFRGWd1_pKetvIIx3jTkuy1YpM7x8ycTKBHDt-ZdjFQ,1783
22
+ mojo/apps/account/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ mojo/apps/account/models/__init__.py,sha256=TYLsLPqurKYNFqqZbOnQzukQLHWe0vznJmZpQ5ezdMw,236
24
+ mojo/apps/account/models/device.py,sha256=HOqErD5MgSPQ6VqlhwQTbzNCSljBiG757BMRLx96AKs,10419
25
+ mojo/apps/account/models/group.py,sha256=ZNHlG6nut72p2qG2wki5O9v31tx2wdiIG3ezWwFr7d8,13086
26
+ mojo/apps/account/models/member.py,sha256=7H78AgA1WAnqyggH0SolnyfUJHsvHVVyzdk0FMJX4mE,4097
27
+ mojo/apps/account/models/pkey.py,sha256=sSHixJTi7HwjJ-p3CB2UePGQLb0zV4UshS01xi8uykE,687
28
+ mojo/apps/account/models/push/__init__.py,sha256=7goek0WV4Jf5CaSriQKAR6YTnBwOS015AdzhD5J2U_E,154
29
+ mojo/apps/account/models/push/config.py,sha256=Re3A2_Mpw6LlSJcITDVvoJJV3cBNSFOqbnHdMPj2qvQ,4532
30
+ mojo/apps/account/models/push/delivery.py,sha256=gW_wipuifrJzGc41zOxrqn6Bafd6ddA3n9SBm0CxstM,3735
31
+ mojo/apps/account/models/push/device.py,sha256=8RVVK1K8LTR2W0_wZPHYxJir_aXnKO8zP-yREK_rHRU,2616
32
+ mojo/apps/account/models/push/template.py,sha256=VnQ0EPTdEF-YvKaPu1QADkp5Assv3OwoYEvgkiaJ--M,4073
33
+ mojo/apps/account/models/user.py,sha256=czyZfBJy213M7IvqCUU-C70vbPgmUCbVVfyM1nuBFRk,21507
34
+ mojo/apps/account/rest/__init__.py,sha256=AHerCTR2wqOQFeN5rUtbR-qN5tvLVer4MjixadJkc7g,97
35
+ mojo/apps/account/rest/device.py,sha256=qRyFR9HkQ8PqGbwR5ZEioky-v_sGy67Vbp-7Iy2oHDA,1248
36
+ mojo/apps/account/rest/group.py,sha256=Syi8hV8HozwzQS-_qNip0MQcBtxCn-W10i0o4kcb24M,1105
37
+ mojo/apps/account/rest/push.py,sha256=8JCf-JXFJpxMhHgAGvaVn2ZKauY80UlkCc5-qgdScz0,5832
38
+ mojo/apps/account/rest/user.py,sha256=jBAxuReJZMRNwjdDTx80HvpAOO8WET1ZXlS6JwsaG18,5550
39
+ mojo/apps/account/services/__init__.py,sha256=fdA9ScIbYS0DJPixwTPjKWhuh8FTC15nGFq7m7EOCNE,29
40
+ mojo/apps/account/services/push.py,sha256=WtRXJm9p3Ry9WhP39g5ebcuZ-o_CdL5kes_LNi6Osxw,14016
41
+ mojo/apps/account/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ mojo/apps/account/utils/jwtoken.py,sha256=7EMC08oDB9oeasv_7nishUNrE-QTls-Mv2n4yAa9euk,2714
43
+ mojo/apps/account/utils/passkeys.py,sha256=vUsXroe4SYcst4L7-eRWDR21l-yVYMOKa1-yWFNKfPo,2343
44
+ mojo/apps/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
+ mojo/apps/aws/migrations/0001_initial.py,sha256=6CbIyLTswAh9Wgbz6QmKZ7FevTwuiQM_c8-RVc67ZFA,14543
46
+ mojo/apps/aws/migrations/0002_emaildomain_can_recv_emaildomain_can_send_and_more.py,sha256=y5EORDmBgotDYCVdJif_pbCUDSSiQ0l6YoOqN7i6p2A,959
47
+ mojo/apps/aws/migrations/0003_mailbox_is_domain_default_mailbox_is_system_default_and_more.py,sha256=xbUZ-aPc3d5IFXpZNwcquns-GF2CrBRJmH0LHInPwgc,1106
48
+ mojo/apps/aws/migrations/0004_s3bucket.py,sha256=17eizmVX6WpYIO_zBivNdcY5f-myhqpFwRZW0QTaUFM,1986
49
+ mojo/apps/aws/migrations/0005_alter_emaildomain_region_delete_s3bucket.py,sha256=akgZsF9ah58Mo_tZNc1e-57KiKKrSTjbreKFJq0s7LY,514
50
+ mojo/apps/aws/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
+ mojo/apps/aws/models/__init__.py,sha256=ZfSWBSWt95ce5y6cI-kCk6SK7on-5w2fjJNuEu_Z92A,404
52
+ mojo/apps/aws/models/email_attachment.py,sha256=03yXgQo7Yuj54VBWKqnKdQ7AO3Y4MiSmLrxGbeThBok,2852
53
+ mojo/apps/aws/models/email_domain.py,sha256=CmULUky_RVacazy9bXxv1b_Iu8obPWG9Sx8xMrHa5xo,7116
54
+ mojo/apps/aws/models/email_template.py,sha256=9E1P3tHlYJWvBB3mGIpTfhdkEVU2WRxIvzrJSxM8l6s,4299
55
+ mojo/apps/aws/models/incoming_email.py,sha256=Nhkqp9dqAGAZyt6nS3xZf5oPdzEEvBerDNQx5COWYNc,5875
56
+ mojo/apps/aws/models/mailbox.py,sha256=5liCWEm8dYDyYCE-CDoP7wZHUERVSTEZ7qREw4Wf8cg,10334
57
+ mojo/apps/aws/models/sent_message.py,sha256=bsvPqrKZyu3qCgHbOg1uUh_Obu_8LYzldNttNXuE4Fg,5279
58
+ mojo/apps/aws/rest/__init__.py,sha256=3gdRhP4CJDy2s0H-w8XHgllb08E5Q_NFKIYH7AlSdXg,152
59
+ mojo/apps/aws/rest/email.py,sha256=BcHngkq7yv8TKdKzGpC-lmXVqbxPp3HtBuTPPVHl4TU,848
60
+ mojo/apps/aws/rest/email_ops.py,sha256=2M97QvwOgDomclbNVdH8dXpKclu1jAId5a3q1HFY2vA,6941
61
+ mojo/apps/aws/rest/messages.py,sha256=dY977YdCPOWTXw5hpIIfglGiQOw-VFJPy6-Uy41XBZw,965
62
+ mojo/apps/aws/rest/s3.py,sha256=jt9F3gd8aih0H-I6RKEBLLYHiw-D-aMWtWWY8lfYCfg,2541
63
+ mojo/apps/aws/rest/send.py,sha256=7ozIcec_hrD2V55enJ-nZmfj2Tg89RXhqmSVf0oMW_s,4356
64
+ mojo/apps/aws/rest/sns.py,sha256=W08uAks8DZ5mQQDd6Xtci5Kz4zDfta-rMpavPCVQUcs,15102
65
+ mojo/apps/aws/rest/templates.py,sha256=Y1IKZR9ZJje9xsrSa7SZd9Z6fui8UDoY4rkvzQexfIw,507
66
+ mojo/apps/aws/services/__init__.py,sha256=ua23H1vSBDSG3DJFQdFAxPTxmLUA2vzsNK80DsWiq6s,828
67
+ mojo/apps/aws/services/email.py,sha256=4bnMmzGtHACLZC58Wmeu93MDOdWXbKBTutpLXUGgxb8,14079
68
+ mojo/apps/aws/services/email_ops.py,sha256=J-OcZFZEPVLEl2MsVK1FQisY3IxAmQpnyp2BUozohqs,20175
69
+ mojo/apps/docit/__init__.py,sha256=3PRmMb-irOjt8OJQT3x48GNKWKoHcHRIdEqH3Zw-mzY,184
70
+ mojo/apps/docit/markdown_plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
+ mojo/apps/docit/markdown_plugins/syntax_highlight.py,sha256=fCsMqTR6f88ULBB3ARDqAXTq8Z2Hn8g7bBO1vzX_i24,846
72
+ mojo/apps/docit/markdown_plugins/toc.py,sha256=-AWsg5bPpsXt3-DVnEQxFcC6nBkWP0-Uz-9MOVJ7pIg,428
73
+ mojo/apps/docit/migrations/0001_initial.py,sha256=w01bIjMOPYcEy9PcE01jC33IScabx_O-R_1vn3_qF-U,8468
74
+ mojo/apps/docit/migrations/0002_alter_book_modified_by_alter_page_modified_by.py,sha256=kMkAEEZ8RdoPU-r8os39FhYEh6BpEqCODC3NzYpGBJY,990
75
+ mojo/apps/docit/migrations/0003_alter_book_group.py,sha256=w1KAh6vl1zMk44w0YIvmo-O-dNjKivJ0RhXAIISeqzo,659
76
+ mojo/apps/docit/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
+ mojo/apps/docit/models/__init__.py,sha256=9ogNhXUt8h_m0b2O-POHOxUfaO19Dn1PF4b5tRaMaDU,247
78
+ mojo/apps/docit/models/asset.py,sha256=BL73eWnZEKYQqAvL024DDA1YS9ExDC-_4X384WjCfBY,6712
79
+ mojo/apps/docit/models/book.py,sha256=wSVzCcML_KD88EdM-wrk21Pgcj2eABGBfL_p9p_74JU,7150
80
+ mojo/apps/docit/models/page.py,sha256=efewSf_FK_MygF7UTBLExqcqFHKsZnOt3O2rfXJJCaY,10241
81
+ mojo/apps/docit/models/page_revision.py,sha256=EEznVqiqRzvgB80MSQrTwa9vKOINgRFiDfaCJxRPl_c,6229
82
+ mojo/apps/docit/rest/__init__.py,sha256=vPtShwGXJvKNJ3wgIVFt20RA-oAb73TCytV16JF1Yd8,188
83
+ mojo/apps/docit/rest/asset.py,sha256=e5OvvzEUgdCIgXubr2WiKlTr2Nhiqzb1C77xwZ_X5bA,531
84
+ mojo/apps/docit/rest/book.py,sha256=tbHSqBS1bVEKoCVvnmV3SAdOr9gg0WqAzMLylhXST9I,585
85
+ mojo/apps/docit/rest/page.py,sha256=X8ddbUm5b5K2OtHUOT8ocvtiUwQmO_psxWho8C1_2xM,585
86
+ mojo/apps/docit/rest/page_revision.py,sha256=PLLaijjj6H-kGD8687OfnhmVID6EkOgdzxms2SajdmU,591
87
+ mojo/apps/docit/services/__init__.py,sha256=AMR1H_at7kboSw6sH755_ZMlwPGu6NQ2gmqsFDHB0AA,140
88
+ mojo/apps/docit/services/docit.py,sha256=6dV9CD_6kH8XTfFYbekCVrP-_Y3lQ7-wIXxDkeQSCgQ,11123
89
+ mojo/apps/docit/services/markdown.py,sha256=ma8i3TbMq9WlGLl0CoQp_-V_3N-6XRBcYJAviibESEA,1351
90
+ mojo/apps/fileman/README.md,sha256=vuld7Ek0kDO0WU3jgaZDmjj8pYxF674WkrPvW6X1Cfg,14106
91
+ mojo/apps/fileman/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
+ mojo/apps/fileman/apps.py,sha256=evFaBnGp90BZWgAe00fOYjdZ--5msi_vW8zjHgVct1Y,383
93
+ mojo/apps/fileman/backends/__init__.py,sha256=BQqbsGYQvfOPlXLio2XwNGsT5eLGIbrf01PZ8OceUx8,3292
94
+ mojo/apps/fileman/backends/base.py,sha256=3tvnt3GrnCWhKsLUh0sE8BQeTik7HmbVbZv5lKYw9_w,9411
95
+ mojo/apps/fileman/backends/filesystem.py,sha256=ykRCiV6aMxjjmDMOY9xfpupC1zcbPF04XBbs0ygmHWg,14949
96
+ mojo/apps/fileman/backends/s3.py,sha256=6N5ZsIsyoT7pr90241VTdNLzmBdXgcP8vJDUDHUM4XQ,26671
97
+ mojo/apps/fileman/examples/configurations.py,sha256=vDIMijAvF-iVrc8ZT1OzjDPKCJYsvxuvAuirXhB9FYU,13775
98
+ mojo/apps/fileman/examples/usage_example.py,sha256=ATkGuUUoNYb4xhEaWFul7Sj-gyKIa9XF5EmVUibSbMQ,22795
99
+ mojo/apps/fileman/management/__init__.py,sha256=HqDUzH9gSF7kUKGypm6LZ5cHxzYEc3I2_9fB3eI283s,36
100
+ mojo/apps/fileman/management/commands/__init__.py,sha256=XtylA46UPDJ5ZY48r5yyk7ZKpvfmnb8kYJjIRVFAMiM,45
101
+ mojo/apps/fileman/management/commands/cleanup_expired_uploads.py,sha256=818-r5w8sKPSOMa1iA7VjUSpYCnlKdjWtsv8cdHkfY8,8354
102
+ mojo/apps/fileman/migrations/0001_initial.py,sha256=M_JTKQK1sIHVA-jMjQzHyGVTp3GAOEUjJIHzT466KDg,7670
103
+ mojo/apps/fileman/migrations/0002_filemanager_parent_alter_filemanager_max_file_size.py,sha256=qGeGzANHIcUs_CAZBxdCrO6qxAAPSpMuh8TXiyzB6WQ,839
104
+ mojo/apps/fileman/migrations/0003_remove_file_fileman_fil_upload__c4bc35_idx_and_more.py,sha256=s6_Mk7ZgUc_sGIFlldY45KDY1O5fHo2HbMHfvd2r01c,600
105
+ mojo/apps/fileman/migrations/0004_remove_file_original_filename_and_more.py,sha256=zg7dedMO6a0a-FjtEBRVCgn5Pjrr1B5SDVBMoyw2w0c,1358
106
+ mojo/apps/fileman/migrations/0005_alter_file_upload_token.py,sha256=sDjN_Qb9CGqp-U4oDYzMClDtasWhQzTw-TQMdqHRjuU,480
107
+ mojo/apps/fileman/migrations/0006_file_download_url_filemanager_forever_urls.py,sha256=gzgtrYVKLJR71Xu8Wk83VK6dacgGdGCWvNq5eSU_vcc,703
108
+ mojo/apps/fileman/migrations/0007_remove_filemanager_forever_urls_and_more.py,sha256=dsZW-CZkgJcMp4XwF_dexzDB-JX_GNm4TDOuSFWC3e0,593
109
+ mojo/apps/fileman/migrations/0008_file_category.py,sha256=K_2hSPIxut-707_e6UxTu1yI2jA18NMtG6NE1uAd6pk,538
110
+ mojo/apps/fileman/migrations/0009_rename_file_path_file_storage_file_path.py,sha256=gs6-auHbek6OOFZ6am6SZH-BAWcSGFeISjJtNuOra7I,371
111
+ mojo/apps/fileman/migrations/0010_filerendition.py,sha256=bBXd4rN9nBOsYJ5d6uy2AasvETTU2XsHg5fay7teP-4,1939
112
+ mojo/apps/fileman/migrations/0011_alter_filerendition_original_file.py,sha256=MolIDgbswlzj6Sso2dRSgRrSxiYDF8R8V80UG0vfyZs,540
113
+ mojo/apps/fileman/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
114
+ mojo/apps/fileman/models/__init__.py,sha256=eINHGAhNCLK7Z4XeHT-iFH--0X3m23P2Py2zQgJHQbA,93
115
+ mojo/apps/fileman/models/file.py,sha256=tzeCJxEWpQ8aOgkIHecwuWSPlffm9WApCBWQMSDDGU0,15622
116
+ mojo/apps/fileman/models/manager.py,sha256=IaYvYtV9iHzZRg523X66u-iOU4fhdaAbclsFnfLb1Nw,22958
117
+ mojo/apps/fileman/models/rendition.py,sha256=j96Q-zv-dB-Shc_4AwE-ky1ZCovGjvX3KO0ACOBUlto,3198
118
+ mojo/apps/fileman/renderer/__init__.py,sha256=8LyugR_AXzq0bwScDLGWW8y7A_be0kIrs0L2AtVwgqc,3510
119
+ mojo/apps/fileman/renderer/audio.py,sha256=BUJefcyPMqqnpWD7nYATWVft4xaoKKpqbTx7GoZxI8M,15421
120
+ mojo/apps/fileman/renderer/base.py,sha256=Neh6G-v0IRey2xQvf8lFspIAAD9oK5LBvfuQqs7a0RQ,6538
121
+ mojo/apps/fileman/renderer/document.py,sha256=SScakrHT0TJJktEjpPkmX5eZfzzk2rgvD1VYJcwflLI,14836
122
+ mojo/apps/fileman/renderer/image.py,sha256=kDmtEu8UVhwUc1MsIf5Ty0OVLt3cC6tSL95xo6Vshfg,7883
123
+ mojo/apps/fileman/renderer/utils.py,sha256=dAOBih3uVMIkcGiiY2bjhGxWpgfM5_KUMG2Y4dlBTSw,8672
124
+ mojo/apps/fileman/renderer/video.py,sha256=Ml633nSDwgPx0BeKSQ5wAR4r642_BKPEA-_2dTboRDQ,10899
125
+ mojo/apps/fileman/rest/__init__.py,sha256=u4ZyCGVFOpp5OnXnHvl46rvsFUlHeXWNYNc0BBhKMK8,108
126
+ mojo/apps/fileman/rest/fileman.py,sha256=cQYKVm9Nzu5-Hf2tWbq8Gg_zad3RtIy2bE88NLgKlrs,346
127
+ mojo/apps/fileman/rest/upload.py,sha256=NZZnPytjQvG2OWVdNDN4t1a8mltZZNM51aiA0Yr51Ww,2579
128
+ mojo/apps/fileman/signals.py,sha256=Kj_vhUdOhAFNrl4VxD7RoAipbx9i8DiZJw_2L_g9Gfw,2849
129
+ mojo/apps/fileman/tasks.py,sha256=59RBxKGOTwMNYbfMIRbF3QSVqj9jWnMZi2arD9dc3DA,8059
130
+ mojo/apps/fileman/utils/__init__.py,sha256=KbDUNeCSW4d6Rg6h_Bh2H_5ol70oE6twLp3ErNnnPBE,1237
131
+ mojo/apps/fileman/utils/upload.py,sha256=hcH0pUf_dZ3tlkZQw1_YBBeAqxwMEDedsBG-n310uS8,18792
132
+ mojo/apps/incident/__init__.py,sha256=G75zqcH8fatIpQ0Jfp67xg48JtpQR_A6MkN2ykxrjRU,35
133
+ mojo/apps/incident/handlers/__init__.py,sha256=gl8imRiKYCnwB2SBoAavpUfJ9ifkS7WF_DOJKMHJg9Q,128
134
+ mojo/apps/incident/handlers/event_handlers.py,sha256=UkGDYIQq73OdTWFUJlLlsCOhOYZB0cbhKwuGippdnOE,4696
135
+ mojo/apps/incident/migrations/0001_initial.py,sha256=F1qZFxGRjD9qyk_zHkn3FmdyMh94Z0bcnHIvmIEZcJI,4506
136
+ mojo/apps/incident/migrations/0002_rename_bundle_ruleset_bundle_minutes_event_hostname_and_more.py,sha256=9_C_mLwbdr1RcyrtD-pm4EuwuFKInluk5IBuW4_1UJU,1441
137
+ mojo/apps/incident/migrations/0003_alter_event_model_id.py,sha256=pFN_W8Ok46rmQOqKDFrAXYEY0iXphFE4Rh7MSJu0VGY,459
138
+ mojo/apps/incident/migrations/0004_alter_incident_model_id.py,sha256=Cv2mqjYXeHgYBi7BUb_mYw-PuPQKRXj6_uy9bqECNRI,422
139
+ mojo/apps/incident/migrations/0005_incidenthistory.py,sha256=pGv1HkLudn2n7st5RlbAkutLnQ640dxHP4mGf7eMmho,2060
140
+ mojo/apps/incident/migrations/0006_alter_incident_state.py,sha256=fZkbMh-hoArprkwx6J6WI8NsMwbm9zMGg-QdABz63wE,412
141
+ mojo/apps/incident/migrations/0007_event_uid.py,sha256=r_K4nN0iPM-tvQTiYBHwjKO5TgYbTrqpQH6qM8qVLFc,412
142
+ mojo/apps/incident/migrations/0008_ticket_ticketnote.py,sha256=stUfNbwzDZw4yNhkYYdQOyU1NOcVjL1xBRjCH5lpo7k,3064
143
+ mojo/apps/incident/migrations/0009_incident_status.py,sha256=AUnogetohTump7vX_dO2pDUvLykkZxTiJ01k36__-pE,418
144
+ mojo/apps/incident/migrations/0010_event_country_code.py,sha256=pX2K0p2b5qDlNsmG3_HlGkquEFvrmHl2pMt4GcWlFPQ,427
145
+ mojo/apps/incident/migrations/0011_incident_country_code.py,sha256=Lx4Ob0BwDSAoXp4KJwOFvAjv45B2t2ku5_4JHm5L5GQ,433
146
+ mojo/apps/incident/migrations/0012_alter_incident_status.py,sha256=OfVHgjn9YrWG58TbwRp2Fz8xuphnsTQdQO0PU1-2miY,423
147
+ mojo/apps/incident/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
148
+ mojo/apps/incident/models/__init__.py,sha256=M20VFoPle5dNVsXZL65azmGyN6OvInYU8KCReY4lJec,164
149
+ mojo/apps/incident/models/event.py,sha256=5GPwK4c7P6kTKGHbzKGYiVmKH_L_7czO_OqxcHLpcaY,6866
150
+ mojo/apps/incident/models/history.py,sha256=67Lnp_4T8dwFCZMnkFwwTI52gtOFdsKAqfNs5yZ7og0,1492
151
+ mojo/apps/incident/models/incident.py,sha256=EIgPWnmAjWRatZyx5KRKuHDhVlzdvSQ7Vky1AQDSbWo,1387
152
+ mojo/apps/incident/models/rule.py,sha256=74tP-h5KqNRRvbmjksCj4SrKJeWi5Fu3vy18t7k6Jys,10110
153
+ mojo/apps/incident/models/ticket.py,sha256=UPd6Ag3UuKgGJNvQ8m0rp0x0jMcCdJSX_OUwnfqpcyk,2311
154
+ mojo/apps/incident/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
155
+ mojo/apps/incident/parsers/ossec/__init__.py,sha256=2e96VUlQj_WgmSKLaUVxKijdv-tY5juquEUebWRCrdQ,48
156
+ mojo/apps/incident/parsers/ossec/core.py,sha256=lC3DuJolsJtHOdgVCG2qYcVwi_ryM8WNpWk9tfx-Kwg,2429
157
+ mojo/apps/incident/parsers/ossec/parsed.py,sha256=1Fcw7F01lAK70aSf7ga5ka2izB_IUGeIfomEcqUY_Qk,786
158
+ mojo/apps/incident/parsers/ossec/rules.py,sha256=635TmK6uUOQZsgMKDbU5HJIGjYlXUo4I6AIBFCuY0V8,4252
159
+ mojo/apps/incident/parsers/ossec/utils.py,sha256=OkD5unXJAuqQo2_mGCO8bokY0tTOzwAAo28hz7Ux8vg,5061
160
+ mojo/apps/incident/reporter.py,sha256=WoWXKhzFLbjLpSDp0__-UTaXevpAyjcovOeGB05Eizc,2224
161
+ mojo/apps/incident/rest/__init__.py,sha256=aiM-cxQNSNKntTqWitv6vmnSIWpGaScZb4HfeR10m1A,64
162
+ mojo/apps/incident/rest/event.py,sha256=ZlOi88Q8HcvtwCOW65X9RSaTddyXweOCOW3vWgVNOcs,851
163
+ mojo/apps/incident/rest/ossec.py,sha256=Rw7o1LRCZdeHL3wOry6zgT9r1MGVxUzJiwvmyT5GfbI,730
164
+ mojo/apps/incident/rest/ticket.py,sha256=W3OJAccl9bRYC-Q1zyGw2uJ2kmT-nviyK8vdUntUH3Y,1522
165
+ mojo/apps/jobs/__init__.py,sha256=GnUaKtFCOPcOQKHwbSgmbPfml6UcgojU2B5agcQ4BFE,16393
166
+ mojo/apps/jobs/adapters.py,sha256=cJ70QMXTmehDRUn5HsfYj5vjBswTSPiB2CtT19VIM8s,691
167
+ mojo/apps/jobs/cli.py,sha256=oau5s0TAx6fPnXnH_SEzwUXpxtS03Brl3NwqLJ0xlDw,18872
168
+ mojo/apps/jobs/daemon.py,sha256=jkxYYmKKuSyo1af-Z4GDyBe7S31zlTCyC9LsvIYEIS0,11123
169
+ mojo/apps/jobs/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
170
+ mojo/apps/jobs/examples/sample_jobs.py,sha256=GuMwNv9cZQR6Bud0oYlj-Uq0pJZp0nNh8cyfypKADFY,11726
171
+ mojo/apps/jobs/examples/webhook_examples.py,sha256=y5MaD8vXgVTu19bMzsfygycvWroQMFsbvbrPJbc0ets,6500
172
+ mojo/apps/jobs/handlers/__init__.py,sha256=W57uZ7bHfyXU8lFmrpClAV_rLqWO33ornkxXFuy7TOs,122
173
+ mojo/apps/jobs/handlers/webhook.py,sha256=PaSDkMnira10CpzHQImkdeVFvoGHPnmHFCS4W7FqCSU,11013
174
+ mojo/apps/jobs/job_engine.py,sha256=ZpJlrKJN2iLMj5dPMN31D-BAaFOr8quN14JAFfg3CFA,28635
175
+ mojo/apps/jobs/keys.py,sha256=sRssn2-Imwamwk4hRNLvY2KqWqjvo2q2NjrVtmlSwkk,5408
176
+ mojo/apps/jobs/local_queue.py,sha256=uJ1rrv3iihTLqFfVKQQ3Q-qbYln7Cz0Cft2ouHTarDQ,10582
177
+ mojo/apps/jobs/management/__init__.py,sha256=J-ADrNPq_Q2K6GVV1G8MapQEn979E1Bogx6lwbCfBdc,56
178
+ mojo/apps/jobs/management/commands/__init__.py,sha256=J-ADrNPq_Q2K6GVV1G8MapQEn979E1Bogx6lwbCfBdc,56
179
+ mojo/apps/jobs/manager.py,sha256=dxROG7FiTFOytZdvl0YHL82thnQfWjIfvc40TgDd7VY,49206
180
+ mojo/apps/jobs/migrations/0001_initial.py,sha256=pQrryKe83ewo64wpBZirqsnOnB-ESkHheSmSRREfTb4,6210
181
+ mojo/apps/jobs/migrations/0002_alter_job_max_retries_joblog.py,sha256=k2kGZrmd3py06GkL_yGBtE_gYb4Crh6uhmjNZ4YYz3Y,1908
182
+ mojo/apps/jobs/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
183
+ mojo/apps/jobs/models/__init__.py,sha256=WibSDLNAYn25VPDXm7CC_VtIK4BA9VMYyr745DTTeCU,101
184
+ mojo/apps/jobs/models/job.py,sha256=lSF5orWJcsDkU8-ZJTw-ATA04PWZ8tpyiBUiRqDqCyQ,15764
185
+ mojo/apps/jobs/rest/__init__.py,sha256=LBsu8DKEKqn_a7V4D_IID0AU7Kw-NAN9bcKK4DUd7hw,43
186
+ mojo/apps/jobs/rest/control.py,sha256=Xvmff6jr48WX69zzjqmSTiMaDIYBqIMzGwcatR4jkuw,14529
187
+ mojo/apps/jobs/rest/jobs.py,sha256=tefqcizxwPY3ogk1qt9TrSPLd3qitUk8ifAD_uhi0MA,11427
188
+ mojo/apps/jobs/scheduler.py,sha256=LzqL3W1BsXfOeYuPACEuMF7aotqCpPGJ-rbCiubLUak,19942
189
+ mojo/apps/jobs/services/__init__.py,sha256=sCNHfrih3neFm9ZRThKns7inG7oCXJxZtylnZRMK5tU,118
190
+ mojo/apps/jobs/services/job_actions.py,sha256=JUFpPSdi2t7SdjJFw1Hm2E2melNylQ8R7mxtalNsXCA,15843
191
+ mojo/apps/jobs/settings.py,sha256=2P3HJ_iqAn0MKwvhuQHPfooCjHzdZ5wGpA_IIvQZcdQ,6780
192
+ mojo/apps/logit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
193
+ mojo/apps/logit/admin.py,sha256=XLvz6CtwfW3rryp5xfvtylL_CWZ5-CbChK4DB2Hl3qM,1552
194
+ mojo/apps/logit/migrations/0001_initial.py,sha256=7vrTetfEFrUzc3cOoboyktfK_KlsfrGAoCDf4T2sJzk,1348
195
+ mojo/apps/logit/migrations/0002_log_duid_log_payload_log_username.py,sha256=s97JeIMjNmKah2b7YcGauaVg_1liTeUJfq-GCi0wP6U,696
196
+ mojo/apps/logit/migrations/0003_log_level.py,sha256=HzLwBYitzRsHxGkM9gKrgc4A8dzLt4ewl14nCnWLSnc,424
197
+ mojo/apps/logit/migrations/0004_alter_log_level.py,sha256=QFPma7kIEUd2wPzc-OExWJt64ZekSXHtuyCgo7ImDVs,403
198
+ mojo/apps/logit/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
199
+ mojo/apps/logit/models/__init__.py,sha256=cOGwOYzMoshEbZiiasBGkj6wF0SBu3Jdpl-AuakDesw,19
200
+ mojo/apps/logit/models/log.py,sha256=dy0BSqErF09_O92-hnUhXgOSgFFNp5E2T6JgfHzZSlc,2567
201
+ mojo/apps/logit/rest.py,sha256=bPoq9Blqzr1YU43LTLf9DiSLe6DgjcH1ctDnfvidpbs,205
202
+ mojo/apps/metrics/README.md,sha256=i4dHNqTKgBLMSIxyLddD7wifxZRDTn2JqQGPmW3EWIw,2984
203
+ mojo/apps/metrics/__init__.py,sha256=l9-nvs7_Kkp6OzNgcJ091p5VFTvHjDidUHkQ14N5T2k,362
204
+ mojo/apps/metrics/redis_metrics.py,sha256=6M0MolNYzHFH8CvXK0jXJYfh_E_bp3F1WgzRPY1Hj5E,19511
205
+ mojo/apps/metrics/rest/__init__.py,sha256=UBR8Yzh73AMvy66BTsWEoSsOT2w9Nj6aDm45hWJkOzc,95
206
+ mojo/apps/metrics/rest/base.py,sha256=1uEqxlvEQpXNOJqFpQe-HxETiYF_6bxmJ9X5eYclabg,5895
207
+ mojo/apps/metrics/rest/categories.py,sha256=sETaAP7lzXf2qw0chPaKfjer3ilptyxUIDjGZaY0y3g,8296
208
+ mojo/apps/metrics/rest/helpers.py,sha256=5w3DO8joiOMN-QzouzQen1MtxepUvfs6UvpQS10GZkc,1781
209
+ mojo/apps/metrics/rest/permissions.py,sha256=cEihJa7F1yjwU3dT-r24T1IlGCVRUqtbqLlzCLQze9A,2765
210
+ mojo/apps/metrics/rest/values.py,sha256=RMtonBARjLby2CRSJqH4n6MOQNz3BKOKjUghJx0qHGY,8969
211
+ mojo/apps/metrics/utils.py,sha256=qkIS09ZxtCkEYFBodxRB_JfzZPJ3CXPJIpEbkXcD1pw,7774
212
+ mojo/decorators/__init__.py,sha256=XzKewkbEeLd0M1ciA6Qf1kbawOd2VV-FbAT1nMLBoQ0,64
213
+ mojo/decorators/auth.py,sha256=spUgzYYBGrVCdyZJ23QxU3wNbLZ5IHkWet195R4cbW0,1019
214
+ mojo/decorators/cron.py,sha256=8Qc4XJU9wUSxfepRALZbeFmgOOVWikhGMnrcOk5wbIw,1199
215
+ mojo/decorators/http.py,sha256=n4wdnMSYBGfbVsAOg5FECVpGJNvllJ0gcucnePj9s5M,7398
216
+ mojo/decorators/validate.py,sha256=MEaIR8yvsM2nloOVbqjvvnrrA0wZn6OLkov2tJ1qdIw,550
217
+ mojo/errors.py,sha256=MPJ5_B-RQNK69-fQ-Hs1oddjupjfwWNakieVPee9hU4,3281
218
+ mojo/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
219
+ mojo/helpers/aws/__init__.py,sha256=scAJG1zCCKTsm8kfDLYn52S5zcjBgbTuJB9fpFuW6iQ,776
220
+ mojo/helpers/aws/client.py,sha256=JoHStXSar6myZuObgteh06ZvFrKGp5Tv7lme0BFcAPw,203
221
+ mojo/helpers/aws/ec2.py,sha256=HrRxggGxjsG2MbGjWzKsC-bCk7VdyXtzFsbeQdcJEqg,27840
222
+ mojo/helpers/aws/iam.py,sha256=Kn24kEy8cacNWhYdagvEfXR8pG8un9DAYg-uHmptraY,23737
223
+ mojo/helpers/aws/inbound_email.py,sha256=dgYKIX5NWngymO1JVsPc38maXpk2Pf46IQW2YcYfP98,11270
224
+ mojo/helpers/aws/kms.py,sha256=RwlgfCo9s2Rs3y5fgcWnGoR7yK6Ntktoqln5sRQ6wDU,15619
225
+ mojo/helpers/aws/s3.py,sha256=SnLOX7X6gqu3fpi1BlGyTTI9FkEDTBFuhXNxMkwNz3o,22106
226
+ mojo/helpers/aws/ses.py,sha256=BIRZW-co4_VSm73kGN6wPhthlv_3-wKEHvkGsQsIeG0,16051
227
+ mojo/helpers/aws/ses_domain.py,sha256=3_XPgdtSNpVg1oMFZEe36Hb_1Hgw4cWmjLM1E-5Hj_g,34933
228
+ mojo/helpers/aws/sns.py,sha256=-qkJwRBEPWQxkBr18lS4t6I_oW2wLm2LGfOWTyKnXDs,15119
229
+ mojo/helpers/cron.py,sha256=_hoKgYYc7m4oU_eU4uUOIXOhJA0A9Lw0f9GPm5TCcs4,2411
230
+ mojo/helpers/crypto/__init__.py,sha256=_-uy2lQ30OFXEbTclFj6b2TJeYhF94dwRM_qwqgOkS8,201
231
+ mojo/helpers/crypto/aes.py,sha256=8VTAsykOxiSBbdKVK0DxJ_1Y2wGkY0CDRjhXSiMvF8o,1830
232
+ mojo/helpers/crypto/hash.py,sha256=HVgfzmpMO5K5stiiateB1y16SAHS7qOP0nGRGyVW0FU,2078
233
+ mojo/helpers/crypto/privpub/__init__.py,sha256=Om2Iw0r1tV4_W3OwWazLveQFTs4bwnYc35JxRBf9nm4,44
234
+ mojo/helpers/crypto/privpub/hybrid.py,sha256=APkqjHLPg4oGRBrji9e1YYKzr_v10yn5IV18ar04GIk,3422
235
+ mojo/helpers/crypto/privpub/rsa.py,sha256=ZrvHMsPv52t1ctuaAX2I7qwqnR1Yh5wLLCaveekMDsI,3420
236
+ mojo/helpers/crypto/sign.py,sha256=jC_QKm7WcxQix0DuxSk5SGD8L-6mBSl1ZHobPnpsR48,1204
237
+ mojo/helpers/crypto/too.l.py,sha256=6ypxFDOkHylcVfdGRlTtS-Jtig8JHkfVHi5N2w0i-_s,821
238
+ mojo/helpers/crypto/utils.py,sha256=_KWl0t61fw4f101aY-lWs86DjRZethhQQ4JktimzdME,1119
239
+ mojo/helpers/daemon.py,sha256=6cC2XWIUZH59YdrV2dglPqNtJ8UUPbsKSatGsDp44m8,3276
240
+ mojo/helpers/dates.py,sha256=geNPvF4kvb1WAM3aCNnIxQWmoxkEqzN-S6VKWEk5Ca8,2534
241
+ mojo/helpers/dns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
242
+ mojo/helpers/dns/godaddy.py,sha256=l8AboiEeGQ34p2t-i5Z6XDkf3siUgRsqIg1mVciPZnU,2334
243
+ mojo/helpers/filetypes.py,sha256=4BJpH8jQ_bZk-86yy2ZasVgVnxHNLIi96d2umQz_dXI,4163
244
+ mojo/helpers/location/__init__.py,sha256=QKuRolBkUBfcGjeLvn1YHnH5vsGIO-iu4r7Qgpoym_U,102
245
+ mojo/helpers/location/countries.py,sha256=U4Rv6j9l1pQqVXlF7zHyrPxQzf2ExPphTq4IoQ4UbHo,6665
246
+ mojo/helpers/location/geolocation.py,sha256=ZNy8m7JK8Ag7Xsr12v8cgyqaxAOnUPqVIMvkLGq5fTc,7070
247
+ mojo/helpers/logit.py,sha256=ZlsS-FJTTfEUvwHR3LJI13y8-bvUZ1KBAhla2FGIXo8,10898
248
+ mojo/helpers/modules.py,sha256=Tq9agvdqLOMWsvyRYLwyyF-g28Y6zSCdJhfhT8iraj4,3180
249
+ mojo/helpers/paths.py,sha256=dIAGF0MOr9faE72fwne2-BEaarXCvJBsU8yJSjB15hA,2053
250
+ mojo/helpers/redis/__init__.py,sha256=GrJde-QtHSXWOg4fyaZo91isfh8QiB0OAn-9g32BNyk,97
251
+ mojo/helpers/redis/adapter.py,sha256=7dFwoiqGnEOnx2mMJQpVYnBtA6MOpz_8vTuGrilAxF4,18133
252
+ mojo/helpers/redis/client.py,sha256=VwYiCMyJgXNMZcGaoRe_dDCluZZpobsAbmLy3zYe484,1438
253
+ mojo/helpers/redis/pool.py,sha256=nXXrdMMr2RGTbjS_qeOGalLpL0gYqhSISHx4DSs5e84,7800
254
+ mojo/helpers/request.py,sha256=Y5cXOpiGU_qsHLnOeWLrcWeEtEAYm_2D-VHvvAQSePE,2600
255
+ mojo/helpers/request_parser.py,sha256=OHsoBaZJ07OEWMDxVTnwElTEpd-zMtwpNdAKL_4KFzc,8862
256
+ mojo/helpers/response.py,sha256=yjsbSg2_bHsXdFkhd3PvkEgkiefxtb4u_-bV2Zz0Ces,940
257
+ mojo/helpers/settings/__init__.py,sha256=hoBkefiF-jluJeIQ6mHBfMedVs7cFJGRmPZMTiNmHCo,93
258
+ mojo/helpers/settings/helper.py,sha256=TRF9MfUMz3vxr6i-u_OV1bhSm0JRQOreIbHSCUOc0Rc,3646
259
+ mojo/helpers/settings/parser.py,sha256=DmVfQdTd_wClxyhqd2T8AgrgRecAoi5ZdIAVJEm4alE,4709
260
+ mojo/helpers/sysinfo.py,sha256=CHflsP26GZYTWU3LZpUtZ98l66x5QFXllfQJlv3MvRw,4517
261
+ mojo/helpers/ua.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
262
+ mojo/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
263
+ mojo/middleware/auth.py,sha256=oMk8BCHzn49nzxWJLhAd2Albs0bgZF6rI6_pAfd-GGg,948
264
+ mojo/middleware/cors.py,sha256=yrTHZW6txDiMKYMD3fWCyBp35P5eu5T-yWv5lB87iN8,1452
265
+ mojo/middleware/logging.py,sha256=wBNlQGb3qeietV_SsWmpOyUVAgxS-NCsfk7Hke1Dl8M,6549
266
+ mojo/middleware/mojo.py,sha256=bbrigUIMpalpZFmF7OysXhbg_02-9ifHsgrHBA5GO3I,1012
267
+ mojo/migrations/0001_initial.py,sha256=ir1h2kZZ6WnAChhcCejCVd5C0kWhGsXKozNhZeWvUTs,1337
268
+ mojo/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
269
+ mojo/models/__init__.py,sha256=1A4nsKq1ZDt85pFrqLUTVqi-DTKojulrSa6rTJK65-Q,61
270
+ mojo/models/rest.py,sha256=uGthNT8filc3mgkdZQI_iiUZ_bH8pXlh7zCSgzp_iBk,37611
271
+ mojo/models/secrets.py,sha256=nfoLNfvztu7lvv2ssrP2xwRJShnJu-iSE-HNhgEutFs,5471
272
+ mojo/rest/__init__.py,sha256=KjRXymi2g5qLVJ-KOOCFwqDocB2RxeGY6-T5HQU7np4,20
273
+ mojo/rest/info.py,sha256=ftL5NZjswWzIfRsxistZrPN8jbIAyHhygYzcb2M7UMQ,699
274
+ mojo/rest/openapi.py,sha256=sRc9GQh6tbNIV-MnJN7Fn_4NeT0QF37tro8G88MMbck,6448
275
+ mojo/serializers/__init__.py,sha256=8tbn92uhvCvxhqZ_HTcAoorJQs4MXqWXVnWh4SOvCH0,2777
276
+ mojo/serializers/core/__init__.py,sha256=cwpHCNHTx3Eft2lgfG_5c0KpudZtxsemNCsMDKIRhxk,2040
277
+ mojo/serializers/core/cache/__init__.py,sha256=yrsQglmJiwgqrgRz_0AMWG3oFViNufShFUj6xjzege0,3039
278
+ mojo/serializers/core/cache/backends.py,sha256=GFrA2NDCxb8LWR0Jn7-5Ic4aHsqMiEJrHXArCYwBTMA,17600
279
+ mojo/serializers/core/cache/base.py,sha256=at1WYOJzuK83MDufizUsJzIFdHcnUXk8Pwa-J8JTsD0,3143
280
+ mojo/serializers/core/cache/disabled.py,sha256=EJNETI3fYqamix7NbkdHsz8Tr_KN7cOrgY2cWzKkOXs,5636
281
+ mojo/serializers/core/cache/memory.py,sha256=Ks-KTD6NB509_HOqt3ygCTVzwvP5BkBREB0JrhIfY_w,9966
282
+ mojo/serializers/core/cache/redis.py,sha256=OrdNLDfPd75XZMZsZrvkcb4aS47ooN4nFoYMWk2Yae8,18763
283
+ mojo/serializers/core/cache/utils.py,sha256=E1ev4EVk_HEyDstB8NEuKLWocH0TD077_dNr_3jCo3E,14636
284
+ mojo/serializers/core/manager.py,sha256=mjgOPSyrJ1bIVrNVdP6OzCrwEhJcKn_0UxszLqM0sP0,20691
285
+ mojo/serializers/core/serializer.py,sha256=9b73uA19TfYaMkP0B640zDqoIICCm5c6nN24u42F3FA,18190
286
+ mojo/serializers/examples/settings.py,sha256=eKIKLPZIvJ2VHfr6VuOZCoy-0j9w6DZVfXgHUTjqnsc,11543
287
+ mojo/serializers/formats/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
288
+ mojo/serializers/formats/csv.py,sha256=duIhSpGjGaumRYaFEe7qL0W-H4jU-LkIheE3m5awLl8,15029
289
+ mojo/serializers/formats/localizers.py,sha256=vziGn1vI8cx_U7xc5qblXPO-e86qYwyq5e4loEPQjPk,13031
290
+ mojo/serializers/simple.py,sha256=sDQfiBsw2oTK1ZDiVj0-Y0w5G6SoeXsVFblITr2ClPw,8339
291
+ mojo/serializers/suggested_improvements.md,sha256=4YD1vzcVmLNpKFGfuQrL4kE1vVAcQicI1liDXFUvd6Y,15183
292
+ mojo/urls.py,sha256=lkB5Dxz7zaSQI2YC5nHvLgt32rcPeaj-YfknlUw_xzQ,1201
293
+ testit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
294
+ testit/client.py,sha256=QkswF2ubCgIwCoMQgxrnlleD_a72gBOkv4dtaLCo6kQ,5400
295
+ testit/faker.py,sha256=fdrgVkgdgypiGZGigBb9uyWHopflulaHrLOmzBdfCFA,393
296
+ testit/helpers.py,sha256=JUT_Mhd0Pb_fhmyP9zThO8hctIraPBEEnuj0thTsycA,6407
297
+ testit/runner.py,sha256=cxdvtMd_4l4-PoKCO35sP96DKOIw30ozGhNVa4BEI0I,11148
298
+ django_nativemojo-0.1.16.dist-info/LICENSE,sha256=K2Ly2mJoqzHPrWcXQFXWbvDtphQ51huB2RbfGW7WmUM,774
299
+ django_nativemojo-0.1.16.dist-info/METADATA,sha256=_P1w0am3KFK1qOaka3LRMYlVycteaXBs7T7oTkccKZY,4855
300
+ django_nativemojo-0.1.16.dist-info/NOTICE,sha256=FqvhpeIbbnXn4wqLHA6Ap2VhQfU2e7QVFFyRW8L_6ys,256
301
+ django_nativemojo-0.1.16.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
302
+ django_nativemojo-0.1.16.dist-info/RECORD,,
mojo/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
- __version__ = "0.1.15"
1
+ __version__ = "0.1.16"
2
2
 
3
3
  from mojo.helpers.response import JsonResponse
@@ -37,9 +37,24 @@ from mojo.serializers import (
37
37
  clear_serializer_caches,
38
38
  benchmark_serializers,
39
39
  list_serializers,
40
- set_default_serializer
40
+ set_default_serializer,
41
+ HAS_UJSON,
42
+ UJSON_VERSION
41
43
  )
42
44
 
45
+ # Import cache system for enhanced functionality
46
+ try:
47
+ from mojo.serializers.core.cache import (
48
+ get_cache_backend,
49
+ get_cache_stats,
50
+ get_available_backends,
51
+ test_backend_connectivity,
52
+ get_cache_health
53
+ )
54
+ HAS_CACHE_SYSTEM = True
55
+ except ImportError:
56
+ HAS_CACHE_SYSTEM = False
57
+
43
58
 
44
59
  class Command(BaseCommand):
45
60
  help = 'Manage MOJO serializers: benchmark, configure, and monitor performance'
@@ -146,6 +161,14 @@ class Command(BaseCommand):
146
161
  help='Graph configuration to test'
147
162
  )
148
163
 
164
+ # Cache information
165
+ cache_parser = subparsers.add_parser('cache-info', help='Show detailed cache information')
166
+ cache_parser.add_argument(
167
+ '--test-connectivity',
168
+ action='store_true',
169
+ help='Test cache backend connectivity'
170
+ )
171
+
149
172
  def handle(self, *args, **options):
150
173
  """Handle command execution."""
151
174
  action = options.get('action')
@@ -163,6 +186,7 @@ class Command(BaseCommand):
163
186
  'clear-cache': self.handle_clear_cache,
164
187
  'health': self.handle_health,
165
188
  'test': self.handle_test,
189
+ 'cache-info': self.handle_cache_info,
166
190
  }
167
191
 
168
192
  handler = handler_map.get(action)
@@ -196,6 +220,24 @@ class Command(BaseCommand):
196
220
  self.stdout.write(f" Class: {info['class_name']}")
197
221
  self.stdout.write(f" Description: {info['description']}")
198
222
 
223
+ # Show ujson information
224
+ self.stdout.write(f"\nPerformance Information:")
225
+ if HAS_UJSON:
226
+ self.stdout.write(f" ✓ ujson {UJSON_VERSION} available - optimal JSON performance")
227
+ else:
228
+ self.stdout.write(f" ⚠ ujson not available - using standard json (slower)")
229
+ self.stdout.write(f" Install with: pip install ujson")
230
+
231
+ # Show cache backend information
232
+ if HAS_CACHE_SYSTEM:
233
+ try:
234
+ cache_backend = get_cache_backend()
235
+ cache_stats = cache_backend.stats()
236
+ backend_type = cache_stats.get('backend', 'unknown')
237
+ self.stdout.write(f" ✓ Cache backend: {backend_type}")
238
+ except Exception as e:
239
+ self.stdout.write(f" ⚠ Cache backend error: {e}")
240
+
199
241
  def handle_benchmark(self, options):
200
242
  """Benchmark serializer performance."""
201
243
  model_class = self.get_model_class(options['model'])
@@ -279,6 +321,68 @@ class Command(BaseCommand):
279
321
  self.style.SUCCESS("Performance statistics cleared")
280
322
  )
281
323
 
324
+ def handle_cache_info(self, options):
325
+ """Show detailed cache information."""
326
+ if not HAS_CACHE_SYSTEM:
327
+ self.stdout.write(
328
+ self.style.ERROR("Cache system not available")
329
+ )
330
+ return
331
+
332
+ self.stdout.write(self.style.SUCCESS("Cache System Information:"))
333
+
334
+ try:
335
+ # Show available backends
336
+ backends = get_available_backends()
337
+ self.stdout.write(f"\nAvailable Backends:")
338
+ for name, info in backends.items():
339
+ status = "✓" if info['available'] else "✗"
340
+ self.stdout.write(f" {status} {name}: {info['description']}")
341
+ if info.get('ujson_available'):
342
+ self.stdout.write(f" ujson: {info.get('ujson_version', 'available')}")
343
+ if info.get('error'):
344
+ self.stdout.write(f" Error: {info['error']}")
345
+
346
+ # Show current backend health
347
+ health = get_cache_health()
348
+ self.stdout.write(f"\nCache Health: {health['status'].upper()}")
349
+ if health.get('issues'):
350
+ for issue in health['issues']:
351
+ self.stdout.write(f" ⚠ {issue}")
352
+
353
+ # Show recommendations
354
+ if health.get('recommendations'):
355
+ self.stdout.write(f"\nRecommendations:")
356
+ for rec in health['recommendations']:
357
+ self.stdout.write(f" • {rec}")
358
+
359
+ # Test connectivity if requested
360
+ if options.get('test_connectivity'):
361
+ self.stdout.write(f"\nTesting Cache Connectivity:")
362
+ backend_type = health.get('backend_type', 'unknown')
363
+ test_result = test_backend_connectivity(backend_type)
364
+
365
+ if test_result['connectivity']:
366
+ self.stdout.write(f" ✓ {backend_type} backend connectivity OK")
367
+ if test_result['functionality']:
368
+ perf = test_result.get('performance', {})
369
+ self.stdout.write(f" ✓ Functionality test passed")
370
+ if perf:
371
+ self.stdout.write(f" Set time: {perf.get('set_time_ms', 0)}ms")
372
+ self.stdout.write(f" Get time: {perf.get('get_time_ms', 0)}ms")
373
+ else:
374
+ self.stdout.write(f" ✗ Functionality test failed")
375
+ else:
376
+ self.stdout.write(f" ✗ {backend_type} backend connectivity failed")
377
+
378
+ for error in test_result.get('errors', []):
379
+ self.stdout.write(f" Error: {error}")
380
+
381
+ except Exception as e:
382
+ self.stdout.write(
383
+ self.style.ERROR(f"Error getting cache information: {e}")
384
+ )
385
+
282
386
  def handle_clear_cache(self, options):
283
387
  """Clear serializer caches."""
284
388
  serializer_name = options.get('serializer')
@@ -434,6 +538,21 @@ class Command(BaseCommand):
434
538
  f"{data['total_objects']} objects serialized"
435
539
  )
436
540
 
541
+ # Cache statistics
542
+ if HAS_CACHE_SYSTEM:
543
+ try:
544
+ cache_stats = get_cache_stats()
545
+ self.stdout.write(f"\nCache Statistics:")
546
+ self.stdout.write(f" Backend: {cache_stats.get('backend', 'unknown')}")
547
+ self.stdout.write(f" Hit Rate: {cache_stats.get('hit_rate', 0):.1%}")
548
+ self.stdout.write(f" Total Requests: {cache_stats.get('total_requests', 0)}")
549
+ self.stdout.write(f" Cache Size: {cache_stats.get('current_size', 0)}")
550
+ if cache_stats.get('max_size'):
551
+ utilization = cache_stats.get('current_size', 0) / cache_stats.get('max_size', 1)
552
+ self.stdout.write(f" Utilization: {utilization:.1%}")
553
+ except Exception as e:
554
+ self.stdout.write(f"\nCache Stats Error: {e}")
555
+
437
556
  # Individual serializer stats
438
557
  for key, value in stats.items():
439
558
  if key.endswith('_stats') and isinstance(value, dict):
@@ -528,4 +647,5 @@ class Command(BaseCommand):
528
647
  self.stdout.write(" clear-cache - Clear serializer caches")
529
648
  self.stdout.write(" health - Run health checks")
530
649
  self.stdout.write(" test - Test serializer functionality")
650
+ self.stdout.write(" cache-info - Show detailed cache information")
531
651
  self.stdout.write("\nUse 'python manage.py serializer_admin <action> --help' for more details")
@@ -0,0 +1,72 @@
1
+ # Generated by Django 4.2.21 on 2025-08-28
2
+
3
+ from django.conf import settings
4
+ from django.db import migrations, models
5
+ import django.db.models.deletion
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ ('account', '0005_group_last_activity'),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.CreateModel(
16
+ name='GeoLocatedIP',
17
+ fields=[
18
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
19
+ ('created', models.DateTimeField(auto_now_add=True)),
20
+ ('modified', models.DateTimeField(auto_now=True, db_index=True)),
21
+ ('ip_address', models.GenericIPAddressField(db_index=True, unique=True)),
22
+ ('country_code', models.CharField(blank=True, db_index=True, max_length=3, null=True)),
23
+ ('country_name', models.CharField(blank=True, max_length=100, null=True)),
24
+ ('region', models.CharField(blank=True, db_index=True, max_length=100, null=True)),
25
+ ('city', models.CharField(blank=True, max_length=100, null=True)),
26
+ ('postal_code', models.CharField(blank=True, max_length=20, null=True)),
27
+ ('latitude', models.FloatField(blank=True, null=True)),
28
+ ('longitude', models.FloatField(blank=True, null=True)),
29
+ ('timezone', models.CharField(blank=True, max_length=50, null=True)),
30
+ ('provider', models.CharField(blank=True, max_length=50, null=True)),
31
+ ('data', models.JSONField(blank=True, default=dict)),
32
+ ('expires_at', models.DateTimeField(blank=True, default=None, null=True)),
33
+ ],
34
+ options={
35
+ 'verbose_name': 'Geolocated IP',
36
+ 'verbose_name_plural': 'Geolocated IPs',
37
+ },
38
+ ),
39
+ migrations.CreateModel(
40
+ name='UserDevice',
41
+ fields=[
42
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
43
+ ('duid', models.CharField(db_index=True, max_length=255)),
44
+ ('device_info', models.JSONField(blank=True, default=dict)),
45
+ ('user_agent_hash', models.CharField(blank=True, db_index=True, max_length=64, null=True)),
46
+ ('last_ip', models.GenericIPAddressField(blank=True, null=True)),
47
+ ('first_seen', models.DateTimeField(auto_now_add=True)),
48
+ ('last_seen', models.DateTimeField(auto_now=True)),
49
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='devices', to=settings.AUTH_USER_MODEL)),
50
+ ],
51
+ options={
52
+ 'ordering': ['-last_seen'],
53
+ 'unique_together': {('user', 'duid')},
54
+ },
55
+ ),
56
+ migrations.CreateModel(
57
+ name='UserDeviceLocation',
58
+ fields=[
59
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
60
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='device_locations_direct', to=settings.AUTH_USER_MODEL)),
61
+ ('ip_address', models.GenericIPAddressField(db_index=True)),
62
+ ('first_seen', models.DateTimeField(auto_now_add=True)),
63
+ ('last_seen', models.DateTimeField(auto_now=True)),
64
+ ('geolocation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='device_locations', to='account.geolocatedip')),
65
+ ('user_device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='locations', to='account.userdevice')),
66
+ ],
67
+ options={
68
+ 'ordering': ['-last_seen'],
69
+ 'unique_together': {('user', 'user_device', 'ip_address')},
70
+ },
71
+ ),
72
+ ]
@@ -0,0 +1,16 @@
1
+ # Generated by Django 4.2.21 on 2025-08-28 16:24
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('account', '0006_add_device_tracking_models'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.DeleteModel(
14
+ name='UserDeviceLocation',
15
+ ),
16
+ ]
@@ -0,0 +1,33 @@
1
+ # Generated by Django 4.2.21 on 2025-08-28 22:30
2
+
3
+ from django.conf import settings
4
+ from django.db import migrations, models
5
+ import django.db.models.deletion
6
+ import mojo.models.rest
7
+
8
+
9
+ class Migration(migrations.Migration):
10
+
11
+ dependencies = [
12
+ ('account', '0007_delete_userdevicelocation'),
13
+ ]
14
+
15
+ operations = [
16
+ migrations.CreateModel(
17
+ name='UserDeviceLocation',
18
+ fields=[
19
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20
+ ('ip_address', models.GenericIPAddressField(db_index=True)),
21
+ ('first_seen', models.DateTimeField(auto_now_add=True)),
22
+ ('last_seen', models.DateTimeField(auto_now=True)),
23
+ ('geolocation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='device_locations', to='account.geolocatedip')),
24
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='device_locations_direct', to=settings.AUTH_USER_MODEL)),
25
+ ('user_device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='locations', to='account.userdevice')),
26
+ ],
27
+ options={
28
+ 'ordering': ['-last_seen'],
29
+ 'unique_together': {('user', 'user_device', 'ip_address')},
30
+ },
31
+ bases=(models.Model, mojo.models.rest.MojoModel),
32
+ ),
33
+ ]