django-nativemojo 0.1.10__py3-none-any.whl → 0.1.15__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 (120) hide show
  1. django_nativemojo-0.1.15.dist-info/METADATA +136 -0
  2. {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.15.dist-info}/RECORD +105 -65
  3. mojo/__init__.py +1 -1
  4. mojo/apps/account/management/__init__.py +5 -0
  5. mojo/apps/account/management/commands/__init__.py +6 -0
  6. mojo/apps/account/management/commands/serializer_admin.py +531 -0
  7. mojo/apps/account/migrations/0004_user_avatar.py +20 -0
  8. mojo/apps/account/migrations/0005_group_last_activity.py +18 -0
  9. mojo/apps/account/models/group.py +25 -7
  10. mojo/apps/account/models/member.py +15 -4
  11. mojo/apps/account/models/user.py +197 -20
  12. mojo/apps/account/rest/group.py +1 -0
  13. mojo/apps/account/rest/user.py +6 -2
  14. mojo/apps/aws/rest/__init__.py +1 -0
  15. mojo/apps/aws/rest/s3.py +64 -0
  16. mojo/apps/fileman/README.md +8 -8
  17. mojo/apps/fileman/backends/base.py +76 -70
  18. mojo/apps/fileman/backends/filesystem.py +86 -86
  19. mojo/apps/fileman/backends/s3.py +200 -108
  20. mojo/apps/fileman/migrations/0001_initial.py +106 -0
  21. mojo/apps/fileman/migrations/0002_filemanager_parent_alter_filemanager_max_file_size.py +24 -0
  22. mojo/apps/fileman/migrations/0003_remove_file_fileman_fil_upload__c4bc35_idx_and_more.py +25 -0
  23. mojo/apps/fileman/migrations/0004_remove_file_original_filename_and_more.py +39 -0
  24. mojo/apps/fileman/migrations/0005_alter_file_upload_token.py +18 -0
  25. mojo/apps/fileman/migrations/0006_file_download_url_filemanager_forever_urls.py +23 -0
  26. mojo/apps/fileman/migrations/0007_remove_filemanager_forever_urls_and_more.py +22 -0
  27. mojo/apps/fileman/migrations/0008_file_category.py +18 -0
  28. mojo/apps/fileman/migrations/0009_rename_file_path_file_storage_file_path.py +18 -0
  29. mojo/apps/fileman/migrations/0010_filerendition.py +33 -0
  30. mojo/apps/fileman/migrations/0011_alter_filerendition_original_file.py +19 -0
  31. mojo/apps/fileman/models/__init__.py +1 -5
  32. mojo/apps/fileman/models/file.py +204 -58
  33. mojo/apps/fileman/models/manager.py +161 -31
  34. mojo/apps/fileman/models/rendition.py +118 -0
  35. mojo/apps/fileman/renderer/__init__.py +111 -0
  36. mojo/apps/fileman/renderer/audio.py +403 -0
  37. mojo/apps/fileman/renderer/base.py +205 -0
  38. mojo/apps/fileman/renderer/document.py +404 -0
  39. mojo/apps/fileman/renderer/image.py +222 -0
  40. mojo/apps/fileman/renderer/utils.py +297 -0
  41. mojo/apps/fileman/renderer/video.py +304 -0
  42. mojo/apps/fileman/rest/__init__.py +1 -18
  43. mojo/apps/fileman/rest/upload.py +22 -32
  44. mojo/apps/fileman/signals.py +58 -0
  45. mojo/apps/fileman/tasks.py +254 -0
  46. mojo/apps/fileman/utils/__init__.py +40 -16
  47. mojo/apps/incident/migrations/0005_incidenthistory.py +39 -0
  48. mojo/apps/incident/migrations/0006_alter_incident_state.py +18 -0
  49. mojo/apps/incident/models/__init__.py +1 -0
  50. mojo/apps/incident/models/history.py +36 -0
  51. mojo/apps/incident/models/incident.py +1 -1
  52. mojo/apps/incident/reporter.py +3 -1
  53. mojo/apps/incident/rest/event.py +7 -1
  54. mojo/apps/logit/migrations/0004_alter_log_level.py +18 -0
  55. mojo/apps/logit/models/log.py +4 -1
  56. mojo/apps/metrics/utils.py +2 -2
  57. mojo/apps/notify/handlers/ses/message.py +1 -1
  58. mojo/apps/notify/providers/aws.py +2 -2
  59. mojo/apps/tasks/__init__.py +34 -1
  60. mojo/apps/tasks/manager.py +200 -45
  61. mojo/apps/tasks/rest/tasks.py +24 -10
  62. mojo/apps/tasks/runner.py +283 -18
  63. mojo/apps/tasks/task.py +99 -0
  64. mojo/apps/tasks/tq_handlers.py +118 -0
  65. mojo/decorators/auth.py +6 -1
  66. mojo/decorators/http.py +7 -2
  67. mojo/helpers/aws/__init__.py +41 -0
  68. mojo/helpers/aws/ec2.py +804 -0
  69. mojo/helpers/aws/iam.py +748 -0
  70. mojo/helpers/aws/s3.py +451 -11
  71. mojo/helpers/aws/ses.py +483 -0
  72. mojo/helpers/aws/sns.py +461 -0
  73. mojo/helpers/crypto/__pycache__/hash.cpython-310.pyc +0 -0
  74. mojo/helpers/crypto/__pycache__/sign.cpython-310.pyc +0 -0
  75. mojo/helpers/crypto/__pycache__/utils.cpython-310.pyc +0 -0
  76. mojo/helpers/dates.py +18 -0
  77. mojo/helpers/response.py +6 -2
  78. mojo/helpers/settings/__init__.py +2 -0
  79. mojo/helpers/{settings.py → settings/helper.py} +1 -37
  80. mojo/helpers/settings/parser.py +132 -0
  81. mojo/middleware/logging.py +1 -1
  82. mojo/middleware/mojo.py +5 -0
  83. mojo/models/rest.py +261 -46
  84. mojo/models/secrets.py +13 -4
  85. mojo/serializers/__init__.py +100 -0
  86. mojo/serializers/advanced/README.md +363 -0
  87. mojo/serializers/advanced/__init__.py +247 -0
  88. mojo/serializers/advanced/formats/__init__.py +28 -0
  89. mojo/serializers/advanced/formats/csv.py +416 -0
  90. mojo/serializers/advanced/formats/excel.py +516 -0
  91. mojo/serializers/advanced/formats/json.py +239 -0
  92. mojo/serializers/advanced/formats/localizers.py +509 -0
  93. mojo/serializers/advanced/formats/response.py +485 -0
  94. mojo/serializers/advanced/serializer.py +568 -0
  95. mojo/serializers/manager.py +501 -0
  96. mojo/serializers/optimized.py +618 -0
  97. mojo/serializers/settings_example.py +322 -0
  98. mojo/serializers/{models.py → simple.py} +38 -15
  99. testit/helpers.py +21 -4
  100. django_nativemojo-0.1.10.dist-info/METADATA +0 -96
  101. mojo/apps/metrics/rest/db.py +0 -0
  102. mojo/helpers/aws/setup_email.py +0 -0
  103. mojo/ws4redis/README.md +0 -174
  104. mojo/ws4redis/__init__.py +0 -2
  105. mojo/ws4redis/client.py +0 -283
  106. mojo/ws4redis/connection.py +0 -327
  107. mojo/ws4redis/exceptions.py +0 -32
  108. mojo/ws4redis/redis.py +0 -183
  109. mojo/ws4redis/servers/base.py +0 -86
  110. mojo/ws4redis/servers/django.py +0 -171
  111. mojo/ws4redis/servers/uwsgi.py +0 -63
  112. mojo/ws4redis/settings.py +0 -45
  113. mojo/ws4redis/utf8validator.py +0 -128
  114. mojo/ws4redis/websocket.py +0 -403
  115. {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.15.dist-info}/LICENSE +0 -0
  116. {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.15.dist-info}/NOTICE +0 -0
  117. {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.15.dist-info}/WHEEL +0 -0
  118. /mojo/{ws4redis/servers → apps/aws}/__init__.py +0 -0
  119. /mojo/apps/{fileman/models/render.py → aws/models/__init__.py} +0 -0
  120. /mojo/apps/fileman/{rest/__init__ → migrations/__init__.py} +0 -0
@@ -0,0 +1,239 @@
1
+ import json
2
+ import datetime
3
+ import math
4
+ from decimal import Decimal
5
+
6
+ # Try to import ujson for better performance
7
+ try:
8
+ import ujson
9
+ HAS_UJSON = True
10
+ except ImportError:
11
+ ujson = None
12
+ HAS_UJSON = False
13
+
14
+ from mojo.helpers import logit
15
+
16
+ logger = logit.get_logger("json_formatter", "json_formatter.log")
17
+
18
+
19
+ class JsonFormatter:
20
+ """
21
+ Enhanced JSON formatter with performance optimizations and Django model support.
22
+ """
23
+
24
+ def __init__(self, use_ujson=None, pretty=False, ensure_ascii=False):
25
+ """
26
+ Initialize JSON formatter.
27
+
28
+ :param use_ujson: Force use of ujson (True/False) or auto-detect (None)
29
+ :param pretty: Enable pretty printing with indentation
30
+ :param ensure_ascii: Ensure ASCII output (escapes unicode)
31
+ """
32
+ self.use_ujson = use_ujson if use_ujson is not None else HAS_UJSON
33
+ self.pretty = pretty
34
+ self.ensure_ascii = ensure_ascii
35
+
36
+ def serialize(self, data, **kwargs):
37
+ """
38
+ Serialize data to JSON string.
39
+
40
+ :param data: Data to serialize
41
+ :param kwargs: Additional options for JSON serialization
42
+ :return: JSON string
43
+ """
44
+ # Preprocess data to handle Django types
45
+ processed_data = self._preprocess_data(data)
46
+
47
+ try:
48
+ if self.use_ujson and HAS_UJSON and not self.pretty:
49
+ # ujson is faster but doesn't support pretty printing or custom encoders
50
+ return ujson.dumps(processed_data, ensure_ascii=self.ensure_ascii, **kwargs)
51
+ else:
52
+ # Use standard json with custom encoder
53
+ json_kwargs = {
54
+ 'cls': ExtendedJSONEncoder,
55
+ 'ensure_ascii': self.ensure_ascii,
56
+ **kwargs
57
+ }
58
+
59
+ if self.pretty:
60
+ json_kwargs.update({
61
+ 'indent': 4,
62
+ 'separators': (',', ': '),
63
+ 'sort_keys': True
64
+ })
65
+
66
+ return json.dumps(processed_data, **json_kwargs)
67
+
68
+ except Exception as e:
69
+ logger.error(f"JSON serialization failed: {e}")
70
+ logger.error(f"Data type: {type(data)}")
71
+
72
+ # Fallback to string representation
73
+ try:
74
+ return json.dumps({
75
+ 'error': 'Serialization failed',
76
+ 'message': str(e),
77
+ 'data_type': str(type(data))
78
+ })
79
+ except Exception:
80
+ return '{"error": "Critical serialization failure"}'
81
+
82
+ def _preprocess_data(self, data):
83
+ """
84
+ Recursively preprocess data to handle Django-specific types.
85
+ This is needed for ujson which doesn't support custom encoders.
86
+ """
87
+ if isinstance(data, dict):
88
+ return {key: self._preprocess_data(value) for key, value in data.items()}
89
+ elif isinstance(data, (list, tuple)):
90
+ return [self._preprocess_data(item) for item in data]
91
+ elif isinstance(data, datetime.datetime):
92
+ return int(data.timestamp())
93
+ elif isinstance(data, datetime.date):
94
+ return data.isoformat()
95
+ elif isinstance(data, datetime.time):
96
+ return data.isoformat()
97
+ elif isinstance(data, Decimal):
98
+ return 0.0 if data.is_nan() else float(data)
99
+ elif isinstance(data, float):
100
+ return 0.0 if math.isnan(data) else data
101
+ elif isinstance(data, set):
102
+ return list(data)
103
+ elif hasattr(data, 'pk') and hasattr(data, '_meta'):
104
+ # Django model instance - return primary key
105
+ return data.pk
106
+ elif hasattr(data, '__dict__') and not isinstance(data, (str, bytes)):
107
+ # Generic object - try to serialize its dict
108
+ try:
109
+ return self._preprocess_data(data.__dict__)
110
+ except Exception:
111
+ return str(data)
112
+ else:
113
+ return data
114
+
115
+ def pretty_serialize(self, data, **kwargs):
116
+ """
117
+ Serialize data with pretty formatting.
118
+ """
119
+ old_pretty = self.pretty
120
+ self.pretty = True
121
+ try:
122
+ result = self.serialize(data, **kwargs)
123
+ finally:
124
+ self.pretty = old_pretty
125
+ return result
126
+
127
+ def compact_serialize(self, data, **kwargs):
128
+ """
129
+ Serialize data in compact format (no extra whitespace).
130
+ """
131
+ old_pretty = self.pretty
132
+ self.pretty = False
133
+ try:
134
+ result = self.serialize(data, **kwargs)
135
+ finally:
136
+ self.pretty = old_pretty
137
+ return result
138
+
139
+
140
+ class ExtendedJSONEncoder(json.JSONEncoder):
141
+ """
142
+ Extended JSON encoder that handles Django model types and other Python objects.
143
+ """
144
+
145
+ def default(self, o):
146
+ """
147
+ Convert objects that aren't natively JSON serializable.
148
+ """
149
+ # Handle datetime objects
150
+ if isinstance(o, datetime.datetime):
151
+ return int(o.timestamp())
152
+ elif isinstance(o, datetime.date):
153
+ return o.isoformat()
154
+ elif isinstance(o, datetime.time):
155
+ return o.isoformat()
156
+
157
+ # Handle numeric types
158
+ elif isinstance(o, Decimal):
159
+ return 0.0 if o.is_nan() else float(o)
160
+ elif isinstance(o, float) and math.isnan(o):
161
+ return 0.0
162
+ elif isinstance(o, complex):
163
+ return {'real': o.real, 'imag': o.imag}
164
+
165
+ # Handle collections
166
+ elif isinstance(o, set):
167
+ return list(o)
168
+ elif isinstance(o, frozenset):
169
+ return list(o)
170
+
171
+ # Handle bytes
172
+ elif isinstance(o, (bytes, bytearray)):
173
+ try:
174
+ return o.decode('utf-8')
175
+ except UnicodeDecodeError:
176
+ return o.decode('utf-8', errors='replace')
177
+
178
+ # Handle Django model instances
179
+ elif hasattr(o, 'pk') and hasattr(o, '_meta'):
180
+ return o.pk
181
+
182
+ # Handle Django QuerySet
183
+ elif hasattr(o, 'model') and hasattr(o, 'query'):
184
+ return list(o.values())
185
+
186
+ # Handle callable objects
187
+ elif callable(o):
188
+ try:
189
+ return o()
190
+ except Exception:
191
+ return f"<callable: {o.__name__ if hasattr(o, '__name__') else str(o)}>"
192
+
193
+ # Handle objects with __dict__
194
+ elif hasattr(o, '__dict__'):
195
+ try:
196
+ return o.__dict__
197
+ except Exception:
198
+ pass
199
+
200
+ # Try to convert to string as last resort
201
+ try:
202
+ return str(o)
203
+ except Exception:
204
+ return f"<unserializable: {type(o).__name__}>"
205
+
206
+
207
+ # Convenience functions
208
+ def to_json(data, pretty=False, use_ujson=None, **kwargs):
209
+ """
210
+ Convert data to JSON string.
211
+
212
+ :param data: Data to serialize
213
+ :param pretty: Enable pretty printing
214
+ :param use_ujson: Force ujson usage
215
+ :param kwargs: Additional JSON options
216
+ :return: JSON string
217
+ """
218
+ formatter = JsonFormatter(use_ujson=use_ujson, pretty=pretty)
219
+ return formatter.serialize(data, **kwargs)
220
+
221
+
222
+ def to_pretty_json(data, **kwargs):
223
+ """
224
+ Convert data to pretty-formatted JSON string.
225
+ """
226
+ return to_json(data, pretty=True, **kwargs)
227
+
228
+
229
+ def to_compact_json(data, **kwargs):
230
+ """
231
+ Convert data to compact JSON string.
232
+ """
233
+ return to_json(data, pretty=False, **kwargs)
234
+
235
+
236
+ # Legacy compatibility
237
+ serialize = to_json
238
+ pretty_json = to_pretty_json
239
+ prettyJSON = to_pretty_json # Maintain old naming convention