django-codenerix-email 4.0.1__py2.py3-none-any.whl → 4.0.3__py2.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.
- codenerix_email/__init__.py +3 -3
- codenerix_email/management/__pycache__/__init__.cpython-310.pyc +0 -0
- codenerix_email/migrations/__pycache__/0001_initial.cpython-310.pyc +0 -0
- codenerix_email/migrations/__pycache__/0002_auto_20170502_1043.cpython-310.pyc +0 -0
- codenerix_email/migrations/__pycache__/0003_auto_20170921_1206.cpython-310.pyc +0 -0
- codenerix_email/migrations/__pycache__/0004_auto_20171108_1628.cpython-310.pyc +0 -0
- codenerix_email/migrations/__pycache__/0005_emailmessage_retries.cpython-310.pyc +0 -0
- codenerix_email/migrations/__pycache__/0006_emailmessage_error.cpython-310.pyc +0 -0
- codenerix_email/migrations/__pycache__/0007_emailmessage_next_retry.cpython-310.pyc +0 -0
- codenerix_email/migrations/__pycache__/0008_auto_20171201_0928.cpython-310.pyc +0 -0
- codenerix_email/migrations/__pycache__/__init__.cpython-310.pyc +0 -0
- codenerix_email/models.py +139 -60
- codenerix_email/views.py +46 -11
- {django_codenerix_email-4.0.1.dist-info → django_codenerix_email-4.0.3.dist-info}/METADATA +8 -7
- {django_codenerix_email-4.0.1.dist-info → django_codenerix_email-4.0.3.dist-info}/RECORD +18 -8
- {django_codenerix_email-4.0.1.dist-info → django_codenerix_email-4.0.3.dist-info}/WHEEL +1 -1
- {django_codenerix_email-4.0.1.dist-info → django_codenerix_email-4.0.3.dist-info}/LICENSE +0 -0
- {django_codenerix_email-4.0.1.dist-info → django_codenerix_email-4.0.3.dist-info}/top_level.txt +0 -0
codenerix_email/__init__.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
__version__ = "4.0.
|
|
1
|
+
__version__ = "4.0.3"
|
|
2
2
|
|
|
3
3
|
__authors__ = [
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
"Juan Miguel Taboada Godoy <juanmi@juanmitaboada.com>",
|
|
5
|
+
"Juan Soler Ruiz <soleronline@gmail.com>",
|
|
6
6
|
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
codenerix_email/models.py
CHANGED
|
@@ -36,40 +36,52 @@ from codenerix.fields import WysiwygAngularField
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
class EmailMessage(CodenerixModel, Debugger):
|
|
39
|
-
efrom = models.EmailField(_(
|
|
40
|
-
eto = models.EmailField(_(
|
|
41
|
-
subject = models.CharField(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
efrom = models.EmailField(_("From"), blank=False, null=False)
|
|
40
|
+
eto = models.EmailField(_("To"), blank=False, null=False)
|
|
41
|
+
subject = models.CharField(
|
|
42
|
+
_("Subject"), max_length=256, blank=False, null=False
|
|
43
|
+
)
|
|
44
|
+
body = models.TextField(_("Body"), blank=False, null=False)
|
|
45
|
+
priority = models.PositiveIntegerField(
|
|
46
|
+
_("Priority"), blank=False, null=False, default=5
|
|
47
|
+
)
|
|
48
|
+
sending = models.BooleanField(
|
|
49
|
+
_("Sending"), blank=False, null=False, default=False
|
|
50
|
+
)
|
|
51
|
+
sent = models.BooleanField(
|
|
52
|
+
_("Sent"), blank=False, null=False, default=False
|
|
53
|
+
)
|
|
54
|
+
error = models.BooleanField(
|
|
55
|
+
_("Error"), blank=False, null=False, default=False
|
|
56
|
+
)
|
|
57
|
+
retries = models.PositiveIntegerField(
|
|
58
|
+
_("Retries"), blank=False, null=False, default=0
|
|
59
|
+
)
|
|
48
60
|
next_retry = models.DateTimeField(_("Next retry"), auto_now_add=True)
|
|
49
|
-
log = models.TextField(_(
|
|
61
|
+
log = models.TextField(_("Log"), blank=True, null=True)
|
|
50
62
|
|
|
51
63
|
def __fields__(self, info):
|
|
52
64
|
fields = []
|
|
53
|
-
fields.append((
|
|
54
|
-
fields.append((
|
|
55
|
-
fields.append((
|
|
56
|
-
fields.append((
|
|
57
|
-
fields.append((
|
|
58
|
-
fields.append((
|
|
59
|
-
fields.append((
|
|
60
|
-
fields.append((
|
|
61
|
-
fields.append((
|
|
62
|
-
fields.append((
|
|
63
|
-
fields.append((
|
|
65
|
+
fields.append(("sending", None, 100))
|
|
66
|
+
fields.append(("error", None, 100))
|
|
67
|
+
fields.append(("sent", _("Send"), 100))
|
|
68
|
+
fields.append(("priority", _("Priority"), 100))
|
|
69
|
+
fields.append(("created", _("Created"), 100))
|
|
70
|
+
fields.append(("efrom", _("From"), 100))
|
|
71
|
+
fields.append(("eto", _("To"), 100))
|
|
72
|
+
fields.append(("subject", _("Subject"), 100))
|
|
73
|
+
fields.append(("retries", _("Retries"), 100))
|
|
74
|
+
fields.append(("next_retry", _("Next retry"), 100))
|
|
75
|
+
fields.append(("pk", _("ID"), 100))
|
|
64
76
|
return fields
|
|
65
77
|
|
|
66
78
|
def __unicode__(self):
|
|
67
79
|
return "{} ({})".format(self.eto, self.pk)
|
|
68
80
|
|
|
69
81
|
def connect(self, legacy=False):
|
|
70
|
-
|
|
82
|
+
"""
|
|
71
83
|
This class will return a connection instance, you can disconnect it with connection.close()
|
|
72
|
-
|
|
84
|
+
"""
|
|
73
85
|
|
|
74
86
|
if not legacy:
|
|
75
87
|
host = settings.CLIENT_EMAIL_HOST
|
|
@@ -85,11 +97,24 @@ class EmailMessage(CodenerixModel, Debugger):
|
|
|
85
97
|
use_tls = settings.EMAIL_USE_TLS
|
|
86
98
|
|
|
87
99
|
# Remember last connection data
|
|
88
|
-
self.__connect_info = {
|
|
100
|
+
self.__connect_info = {"host": host, "port": port, "use_tls": use_tls}
|
|
89
101
|
# Get connection
|
|
90
|
-
return get_connection(
|
|
91
|
-
|
|
92
|
-
|
|
102
|
+
return get_connection(
|
|
103
|
+
host=host,
|
|
104
|
+
port=port,
|
|
105
|
+
username=username,
|
|
106
|
+
password=password,
|
|
107
|
+
use_tls=use_tls,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
def send(
|
|
111
|
+
self,
|
|
112
|
+
connection=None,
|
|
113
|
+
legacy=False,
|
|
114
|
+
silent=True,
|
|
115
|
+
debug=False,
|
|
116
|
+
content_subtype="plain",
|
|
117
|
+
):
|
|
93
118
|
|
|
94
119
|
# Autoconfigure Debugger
|
|
95
120
|
if debug:
|
|
@@ -99,7 +124,8 @@ class EmailMessage(CodenerixModel, Debugger):
|
|
|
99
124
|
# Get connection if not connected yet
|
|
100
125
|
if connection is None:
|
|
101
126
|
# Connect
|
|
102
|
-
|
|
127
|
+
if not silent or debug:
|
|
128
|
+
self.warning("Not connected, connecting...")
|
|
103
129
|
connection = self.connect(legacy)
|
|
104
130
|
|
|
105
131
|
if self.eto:
|
|
@@ -109,13 +135,23 @@ class EmailMessage(CodenerixModel, Debugger):
|
|
|
109
135
|
# Manually open the connection
|
|
110
136
|
try:
|
|
111
137
|
connection.open()
|
|
112
|
-
except (
|
|
138
|
+
except (
|
|
139
|
+
smtplib.SMTPAuthenticationError,
|
|
140
|
+
OSError,
|
|
141
|
+
TimeoutError,
|
|
142
|
+
) as e:
|
|
113
143
|
connection = None
|
|
114
144
|
if self.log is None:
|
|
115
|
-
self.log =
|
|
145
|
+
self.log = ""
|
|
116
146
|
exceptiontxt = str(type(e)).split(".")[-1].split("'")[0]
|
|
117
|
-
ci = getattr(self,
|
|
118
|
-
error =
|
|
147
|
+
ci = getattr(self, "__connect_info", {})
|
|
148
|
+
error = "{}: {} [HOST={}:{} TLS={}]\n".format(
|
|
149
|
+
exceptiontxt,
|
|
150
|
+
e,
|
|
151
|
+
ci.get("host", "-"),
|
|
152
|
+
ci.get("port", "-"),
|
|
153
|
+
ci.get("use_tls", "-"),
|
|
154
|
+
)
|
|
119
155
|
self.warning(error)
|
|
120
156
|
self.log += error
|
|
121
157
|
# We will not retry anymore
|
|
@@ -124,8 +160,14 @@ class EmailMessage(CodenerixModel, Debugger):
|
|
|
124
160
|
self.priority += 1
|
|
125
161
|
# Set new retry
|
|
126
162
|
self.retries += 1
|
|
127
|
-
self.next_retry = timezone.now() + timezone.timedelta(
|
|
128
|
-
|
|
163
|
+
self.next_retry = timezone.now() + timezone.timedelta(
|
|
164
|
+
seconds=getattr(
|
|
165
|
+
settings, "CLIENT_EMAIL_RETRIES_WAIT", 5400
|
|
166
|
+
)
|
|
167
|
+
) # retry every 1.5h
|
|
168
|
+
if self.retries >= getattr(
|
|
169
|
+
settings, "CLIENT_EMAIL_RETRIES", 10
|
|
170
|
+
): # 10 retries * 1.5h = 15h
|
|
129
171
|
self.error = True
|
|
130
172
|
# Save all
|
|
131
173
|
self.save()
|
|
@@ -133,7 +175,13 @@ class EmailMessage(CodenerixModel, Debugger):
|
|
|
133
175
|
raise
|
|
134
176
|
|
|
135
177
|
if connection:
|
|
136
|
-
email = EM(
|
|
178
|
+
email = EM(
|
|
179
|
+
self.subject,
|
|
180
|
+
self.body,
|
|
181
|
+
self.efrom,
|
|
182
|
+
[self.eto],
|
|
183
|
+
connection=connection,
|
|
184
|
+
)
|
|
137
185
|
email.content_subtype = content_subtype
|
|
138
186
|
for at in self.attachments.all():
|
|
139
187
|
with open(at.path) as f:
|
|
@@ -171,8 +219,19 @@ class EmailMessage(CodenerixModel, Debugger):
|
|
|
171
219
|
self.priority += 1
|
|
172
220
|
# Set new retry
|
|
173
221
|
self.retries += 1
|
|
174
|
-
self.next_retry =
|
|
175
|
-
|
|
222
|
+
self.next_retry = (
|
|
223
|
+
timezone.now()
|
|
224
|
+
+ timezone.timedelta(
|
|
225
|
+
seconds=getattr(
|
|
226
|
+
settings,
|
|
227
|
+
"CLIENT_EMAIL_RETRIES_WAIT",
|
|
228
|
+
5400,
|
|
229
|
+
)
|
|
230
|
+
)
|
|
231
|
+
) # retry every 1.5h
|
|
232
|
+
if self.retries >= getattr(
|
|
233
|
+
settings, "CLIENT_EMAIL_RETRIES", 10
|
|
234
|
+
): # 10 retries * 1.5h = 15h
|
|
176
235
|
self.error = True
|
|
177
236
|
# Save the email
|
|
178
237
|
self.save()
|
|
@@ -183,29 +242,41 @@ class EmailMessage(CodenerixModel, Debugger):
|
|
|
183
242
|
|
|
184
243
|
|
|
185
244
|
class EmailAttachment(CodenerixModel):
|
|
186
|
-
email = models.ForeignKey(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
245
|
+
email = models.ForeignKey(
|
|
246
|
+
EmailMessage,
|
|
247
|
+
on_delete=models.CASCADE,
|
|
248
|
+
blank=False,
|
|
249
|
+
null=False,
|
|
250
|
+
related_name="attachments",
|
|
251
|
+
)
|
|
252
|
+
filename = models.CharField(
|
|
253
|
+
_("Filename"), max_length=256, blank=False, null=False
|
|
254
|
+
)
|
|
255
|
+
mime = models.CharField(
|
|
256
|
+
_("Mimetype"), max_length=256, blank=False, null=False
|
|
257
|
+
)
|
|
258
|
+
path = models.FileField(_("Path"), blank=False, null=False)
|
|
190
259
|
|
|
191
260
|
def __fields__(self, info):
|
|
192
261
|
fields = []
|
|
193
|
-
fields.append((
|
|
194
|
-
fields.append((
|
|
195
|
-
fields.append((
|
|
196
|
-
fields.append((
|
|
262
|
+
fields.append(("email", _("Email"), 100))
|
|
263
|
+
fields.append(("filename", _("Filename"), 100))
|
|
264
|
+
fields.append(("mime", _("Mimetype"), 100))
|
|
265
|
+
fields.append(("path", _("Path"), 100))
|
|
197
266
|
return fields
|
|
198
267
|
|
|
199
268
|
|
|
200
269
|
class EmailTemplate(CodenerixModel):
|
|
201
|
-
cid = models.CharField(
|
|
202
|
-
|
|
270
|
+
cid = models.CharField(
|
|
271
|
+
_("CID"), unique=True, max_length=30, blank=False, null=False
|
|
272
|
+
)
|
|
273
|
+
efrom = models.TextField(_("From"), blank=True, null=False)
|
|
203
274
|
|
|
204
275
|
def __fields__(self, info):
|
|
205
276
|
fields = []
|
|
206
|
-
fields.append((
|
|
207
|
-
fields.append((
|
|
208
|
-
fields.append((
|
|
277
|
+
fields.append(("pk", _("PK"), 100))
|
|
278
|
+
fields.append(("cid", _("CID"), 100))
|
|
279
|
+
fields.append(("efrom", _("From"), 100))
|
|
209
280
|
return fields
|
|
210
281
|
|
|
211
282
|
def __str__(self):
|
|
@@ -216,13 +287,13 @@ class EmailTemplate(CodenerixModel):
|
|
|
216
287
|
|
|
217
288
|
@staticmethod
|
|
218
289
|
def get(cid=None, context={}, pk=None, lang=None):
|
|
219
|
-
|
|
290
|
+
"""
|
|
220
291
|
Usages:
|
|
221
292
|
EmailTemplate.get('PACO', ctx) => EmailMessage(): le falta el eto
|
|
222
293
|
> cid: PACO
|
|
223
294
|
EmailTemplate.get(pk='PACO', context=ctx) => EmailMessage(): le falta el eto
|
|
224
295
|
> pk: PACO (we don't have CID)
|
|
225
|
-
|
|
296
|
+
"""
|
|
226
297
|
if cid:
|
|
227
298
|
template = EmailTemplate.objects.filter(cid=cid).first()
|
|
228
299
|
else:
|
|
@@ -238,7 +309,9 @@ class EmailTemplate(CodenerixModel):
|
|
|
238
309
|
lang = settings.LANGUAGES_DATABASES[0].lower()
|
|
239
310
|
|
|
240
311
|
e = EmailMessage()
|
|
241
|
-
e.subject = Template(getattr(self, lang).subject).render(
|
|
312
|
+
e.subject = Template(getattr(self, lang).subject).render(
|
|
313
|
+
Context(context)
|
|
314
|
+
)
|
|
242
315
|
e.body = Template(getattr(self, lang).body).render(Context(context))
|
|
243
316
|
e.efrom = Template(self.efrom).render(Context(context))
|
|
244
317
|
return e
|
|
@@ -247,24 +320,28 @@ class EmailTemplate(CodenerixModel):
|
|
|
247
320
|
if self.cid:
|
|
248
321
|
self.cid = self.cid.upper()
|
|
249
322
|
if len(re.findall(r"[A-Za-z0-9]+", self.cid)) != 1:
|
|
250
|
-
raise ValidationError(
|
|
323
|
+
raise ValidationError(
|
|
324
|
+
_(
|
|
325
|
+
"CID can contains only number and letters with no spaces"
|
|
326
|
+
)
|
|
327
|
+
)
|
|
251
328
|
|
|
252
329
|
|
|
253
330
|
class GenText(CodenerixModel): # META: Abstract class
|
|
254
331
|
class Meta(CodenerixModel.Meta):
|
|
255
332
|
abstract = True
|
|
256
333
|
|
|
257
|
-
subject = models.TextField(_(
|
|
258
|
-
body = WysiwygAngularField(_(
|
|
334
|
+
subject = models.TextField(_("Subject"), blank=True, null=False)
|
|
335
|
+
body = WysiwygAngularField(_("Body"), blank=True, null=False)
|
|
259
336
|
|
|
260
337
|
def __fields__(self, info):
|
|
261
338
|
fields = []
|
|
262
|
-
fields.append((
|
|
263
|
-
fields.append((
|
|
339
|
+
fields.append(("subject", _("Subject"), 100))
|
|
340
|
+
fields.append(("body", _("Body"), 100))
|
|
264
341
|
return fields
|
|
265
342
|
|
|
266
343
|
def __unicode__(self):
|
|
267
|
-
return
|
|
344
|
+
return "{}".format(self.subject)
|
|
268
345
|
|
|
269
346
|
def __str__(self):
|
|
270
347
|
return self.__unicode__()
|
|
@@ -279,5 +356,7 @@ for info in MODELS:
|
|
|
279
356
|
model = info[1]
|
|
280
357
|
for lang_code in settings.LANGUAGES_DATABASES:
|
|
281
358
|
query = "class {}Text{}(GenText):\n".format(model, lang_code)
|
|
282
|
-
query += " {} = models.OneToOneField({}, on_delete=models.CASCADE, blank=False, null=False, related_name='{}')\n".format(
|
|
359
|
+
query += " {} = models.OneToOneField({}, on_delete=models.CASCADE, blank=False, null=False, related_name='{}')\n".format(
|
|
360
|
+
field, model, lang_code.lower()
|
|
361
|
+
)
|
|
283
362
|
exec(query)
|
codenerix_email/views.py
CHANGED
|
@@ -18,26 +18,56 @@
|
|
|
18
18
|
# See the License for the specific language governing permissions and
|
|
19
19
|
# limitations under the License.
|
|
20
20
|
|
|
21
|
+
from typing import Optional, Tuple, List, Dict, Any
|
|
22
|
+
|
|
21
23
|
from django.utils.translation import gettext as _
|
|
22
24
|
from django.conf import settings
|
|
25
|
+
from django.http import HttpRequest
|
|
23
26
|
|
|
24
27
|
from codenerix.multiforms import MultiForm
|
|
25
|
-
from codenerix.views import
|
|
28
|
+
from codenerix.views import (
|
|
29
|
+
GenList,
|
|
30
|
+
GenCreate,
|
|
31
|
+
GenCreateModal,
|
|
32
|
+
GenUpdate,
|
|
33
|
+
GenUpdateModal,
|
|
34
|
+
GenDelete,
|
|
35
|
+
GenDetail,
|
|
36
|
+
)
|
|
26
37
|
from codenerix_email.models import EmailTemplate, EmailMessage, MODELS
|
|
27
38
|
from codenerix_email.forms import EmailTemplateForm, EmailMessageForm
|
|
28
39
|
|
|
29
|
-
formsfull
|
|
40
|
+
formsfull: Dict[
|
|
41
|
+
str,
|
|
42
|
+
List[
|
|
43
|
+
Tuple[
|
|
44
|
+
Optional[HttpRequest],
|
|
45
|
+
Optional[str],
|
|
46
|
+
Optional[str],
|
|
47
|
+
]
|
|
48
|
+
],
|
|
49
|
+
] = {}
|
|
30
50
|
|
|
31
51
|
for info in MODELS:
|
|
32
52
|
field = info[0]
|
|
33
53
|
model = info[1]
|
|
34
54
|
formsfull[model] = [(None, None, None)]
|
|
35
55
|
for lang_code in settings.LANGUAGES_DATABASES:
|
|
36
|
-
query = "from codenerix_email.models import {}Text{}\n".format(
|
|
37
|
-
|
|
56
|
+
query = "from codenerix_email.models import {}Text{}\n".format(
|
|
57
|
+
model, lang_code
|
|
58
|
+
)
|
|
59
|
+
query += "from codenerix_email.forms import {}TextForm{}".format(
|
|
60
|
+
model, lang_code
|
|
61
|
+
)
|
|
38
62
|
exec(query)
|
|
39
63
|
|
|
40
|
-
formsfull[model].append(
|
|
64
|
+
formsfull[model].append(
|
|
65
|
+
(
|
|
66
|
+
eval("{}TextForm{}".format(model, lang_code.upper())),
|
|
67
|
+
field,
|
|
68
|
+
None,
|
|
69
|
+
)
|
|
70
|
+
)
|
|
41
71
|
|
|
42
72
|
|
|
43
73
|
# ############################################
|
|
@@ -45,8 +75,8 @@ for info in MODELS:
|
|
|
45
75
|
class EmailTemplateList(GenList):
|
|
46
76
|
model = EmailTemplate
|
|
47
77
|
extra_context = {
|
|
48
|
-
|
|
49
|
-
|
|
78
|
+
"menu": ["EmailTemplate", "people"],
|
|
79
|
+
"bread": [_("EmailTemplate"), _("People")],
|
|
50
80
|
}
|
|
51
81
|
|
|
52
82
|
|
|
@@ -79,12 +109,17 @@ class EmailTemplateDelete(GenDelete):
|
|
|
79
109
|
class EmailMessageList(GenList):
|
|
80
110
|
model = EmailMessage
|
|
81
111
|
show_details = True
|
|
82
|
-
default_ordering = [
|
|
112
|
+
default_ordering = ["-created"]
|
|
83
113
|
static_partial_row = "codenerix_email/partials/emailmessages_rows.html"
|
|
84
|
-
gentranslate = {
|
|
114
|
+
gentranslate = {
|
|
115
|
+
"sending": _("Sending"),
|
|
116
|
+
"sent": _("Sent"),
|
|
117
|
+
"notsent": _("Not sent!"),
|
|
118
|
+
"waiting": _("Waiting"),
|
|
119
|
+
}
|
|
85
120
|
extra_context = {
|
|
86
|
-
|
|
87
|
-
|
|
121
|
+
"menu": ["EmailMessage", "people"],
|
|
122
|
+
"bread": [_("EmailMessage"), _("People")],
|
|
88
123
|
}
|
|
89
124
|
|
|
90
125
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-codenerix-email
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.3
|
|
4
4
|
Summary: Codenerix Email is a module that enables CODENERIX to set send emails in a general manner.
|
|
5
5
|
Home-page: https://github.com/codenerix/django-codenerix-email
|
|
6
6
|
Author: Juan Miguel Taboada Godoy <juanmi@juanmitaboada.com>, Juan Soler Ruiz <soleronline@gmail.com>
|
|
7
|
-
Author-email: UNKNOWN
|
|
8
7
|
License: Apache License Version 2.0
|
|
9
8
|
Keywords: django,codenerix,management,erp,crm,send email
|
|
10
9
|
Platform: OS Independent
|
|
@@ -24,6 +23,7 @@ Classifier: Programming Language :: Python :: 3.4
|
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.5
|
|
25
24
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
26
25
|
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
26
|
+
License-File: LICENSE
|
|
27
27
|
Requires-Dist: django-codenerix
|
|
28
28
|
Requires-Dist: django-codenerix-extensions
|
|
29
29
|
|
|
@@ -41,7 +41,12 @@ Codenerix Email is a module that enables `CODENERIX <https://www.codenerix.com/>
|
|
|
41
41
|
Demo
|
|
42
42
|
****
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
You can have a look to our demos online:
|
|
45
|
+
|
|
46
|
+
* `CODENERIX Simple Agenda DEMO <http://demo.codenerix.com>`_.
|
|
47
|
+
* `CODENERIX Full ERP DEMO <https://erp.codenerix.com>`_.
|
|
48
|
+
|
|
49
|
+
You can find some working examples in GITHUB at `django-codenerix-examples <https://github.com/codenerix/django-codenerix-examples>`_ project.
|
|
45
50
|
|
|
46
51
|
**********
|
|
47
52
|
Quickstart
|
|
@@ -70,8 +75,4 @@ Coming soon... do you help us?
|
|
|
70
75
|
|
|
71
76
|
You can get in touch with us `here <https://codenerix.com/contact/>`_.
|
|
72
77
|
|
|
73
|
-
*******
|
|
74
|
-
Credits
|
|
75
|
-
*******
|
|
76
|
-
|
|
77
78
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
codenerix_email/__init__.py,sha256=
|
|
1
|
+
codenerix_email/__init__.py,sha256=UaXiukSpFEY8Zrksuir-RttIUViJuy6On8wUs47f-vA,148
|
|
2
2
|
codenerix_email/admin.py,sha256=o3b-MaD7xsWeta0yfU9YNeKBmHQIcmHqXmP2t-hrrWc,1208
|
|
3
3
|
codenerix_email/apps.py,sha256=WXqu1XQibDDyCvvQYt2JbTK4GIpW8BNv5DCbRJS2mmk,149
|
|
4
4
|
codenerix_email/forms.py,sha256=Px6ThD6NE9b23S_lGAXxr6ek6A1YssUMbKP9irTCgw8,3157
|
|
5
|
-
codenerix_email/models.py,sha256=
|
|
5
|
+
codenerix_email/models.py,sha256=HFdK717lddRfQMR0UUqkoVnymhVjYkXEKSaIw01AKTg,12659
|
|
6
6
|
codenerix_email/urls.py,sha256=QYrSJdhCp2PLrcfv_Y7X4OzxqQ0Q2-z7ObDPE-_WLdw,2595
|
|
7
|
-
codenerix_email/views.py,sha256=
|
|
7
|
+
codenerix_email/views.py,sha256=YAYEgJDaNqlUoLH6Qwnv7GxqrqJbPE4kBL3BZs2oP9Y,3804
|
|
8
8
|
codenerix_email/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
codenerix_email/management/__pycache__/__init__.cpython-310.pyc,sha256=7vUcYbg6ZpWdEhb0hq2FSiwMtpBWIjMTv8H8rcgtiOY,179
|
|
9
10
|
codenerix_email/management/__pycache__/__init__.cpython-35.pyc,sha256=sBoEWs6zdI0al-7t1deW9SE_Ln2RNDl2LyIiOO9gfRA,160
|
|
10
11
|
codenerix_email/management/__pycache__/__init__.cpython-39.pyc,sha256=uPXklfliVd3b8pLOJQT9ZeKcqmJMrGychvt68BsPulY,168
|
|
11
12
|
codenerix_email/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -20,27 +21,36 @@ codenerix_email/migrations/0006_emailmessage_error.py,sha256=qEZ-GQDufZDTdiH5w4c
|
|
|
20
21
|
codenerix_email/migrations/0007_emailmessage_next_retry.py,sha256=aSOTLqoYFo2V78r5dn-HmEs-loutCoqS-BF97_Vy_sU,602
|
|
21
22
|
codenerix_email/migrations/0008_auto_20171201_0928.py,sha256=cqlgf9IfNgU-IJey073K1FT-pp6i2gXDgLnU-xrFir0,731
|
|
22
23
|
codenerix_email/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
+
codenerix_email/migrations/__pycache__/0001_initial.cpython-310.pyc,sha256=Sm54OKfGHUMvSVgbXiFAe9E2d85HqlLoMEaBEBP53mE,2005
|
|
23
25
|
codenerix_email/migrations/__pycache__/0001_initial.cpython-35.pyc,sha256=o1rDga25c1uGi8Lwkc1_cxhPLANeqXCRzt7LlQcA9q0,2373
|
|
24
26
|
codenerix_email/migrations/__pycache__/0001_initial.cpython-39.pyc,sha256=mQWff6-hcg9Z9K81-Nzrs_1YSOhbjM9kE0YrFbV6RIs,2020
|
|
27
|
+
codenerix_email/migrations/__pycache__/0002_auto_20170502_1043.cpython-310.pyc,sha256=WAPjfkNFQmN3-XkDyD14MSAN9BO81TJ1WtkaBShkt9Y,1500
|
|
25
28
|
codenerix_email/migrations/__pycache__/0002_auto_20170502_1043.cpython-35.pyc,sha256=bS7TIZyg_w_TjQmp2SvPUGj8UzEwD-7eOOh1e5hbBMA,1692
|
|
26
29
|
codenerix_email/migrations/__pycache__/0002_auto_20170502_1043.cpython-39.pyc,sha256=iQ0y2-fNC6oNKxgDuWkYTmoyotm59a5gM0sdmrS8AXM,1515
|
|
30
|
+
codenerix_email/migrations/__pycache__/0003_auto_20170921_1206.cpython-310.pyc,sha256=eBWNWUvCRT3Hx7RB3q8a-sfwnaAGGL1R3HAuZVF9B-I,694
|
|
27
31
|
codenerix_email/migrations/__pycache__/0003_auto_20170921_1206.cpython-35.pyc,sha256=_Ie38P9DBAPqdJKfO_QO41ulOkYjfH3LSoEz3_X6r4k,782
|
|
28
32
|
codenerix_email/migrations/__pycache__/0003_auto_20170921_1206.cpython-39.pyc,sha256=eXU1dbbIu4mk9de7nDH7a6KGkkRGgDPE75ZXlXez6mU,709
|
|
33
|
+
codenerix_email/migrations/__pycache__/0004_auto_20171108_1628.cpython-310.pyc,sha256=lK9340jHiOmqQmzJ5W68rRkUszDzT46fVPsSp8LhISA,676
|
|
29
34
|
codenerix_email/migrations/__pycache__/0004_auto_20171108_1628.cpython-35.pyc,sha256=qqDGLd7cwnb2oWfu-HtGc52yay0BGyZdHusRFrcwF-A,713
|
|
30
35
|
codenerix_email/migrations/__pycache__/0004_auto_20171108_1628.cpython-39.pyc,sha256=GJkiiBltA2oJP_pLcXFhNocsmZ9-6JMwrjoCgWTvMUc,691
|
|
36
|
+
codenerix_email/migrations/__pycache__/0005_emailmessage_retries.cpython-310.pyc,sha256=4YqPVee-54TJz2Pzw6GSKrml9mfcsdoyrblnDBqYfRI,691
|
|
31
37
|
codenerix_email/migrations/__pycache__/0005_emailmessage_retries.cpython-35.pyc,sha256=q1iyggKDYSixO10GNa7NwkaCp1zc4XmJMf3_I6MFdng,728
|
|
32
38
|
codenerix_email/migrations/__pycache__/0005_emailmessage_retries.cpython-39.pyc,sha256=L27pZOAApj_zps1H-o1Dasoo6vsbjEV2LOcYWPMTkPI,706
|
|
39
|
+
codenerix_email/migrations/__pycache__/0006_emailmessage_error.cpython-310.pyc,sha256=5jrOldyWL3nDXJSGHuO92Isv3tDTSW9TZMgwE1M2Zts,675
|
|
33
40
|
codenerix_email/migrations/__pycache__/0006_emailmessage_error.cpython-35.pyc,sha256=TF2SGyuip9sWJPB1rxcbBKhxKzuRe_XUqUz2p6_9QzE,712
|
|
34
41
|
codenerix_email/migrations/__pycache__/0006_emailmessage_error.cpython-39.pyc,sha256=wL1FWhI8nFruZd5pxDbysqPDvzUVBz_5X36nSQcB2rA,690
|
|
42
|
+
codenerix_email/migrations/__pycache__/0007_emailmessage_next_retry.cpython-310.pyc,sha256=ZNGZ_u-sVBgyXgsKExk4YH_kx2tyFTio6bm9Cb_ONcI,802
|
|
35
43
|
codenerix_email/migrations/__pycache__/0007_emailmessage_next_retry.cpython-35.pyc,sha256=SRZaXtSXw295g226C-SZlpYPSZWsCCvIDH1Cb1-JD2I,854
|
|
36
44
|
codenerix_email/migrations/__pycache__/0007_emailmessage_next_retry.cpython-39.pyc,sha256=_SpjnrjYSI3XLxJ7SxT2J8_SMsaNf78vR-RqEQnBjZA,817
|
|
45
|
+
codenerix_email/migrations/__pycache__/0008_auto_20171201_0928.cpython-310.pyc,sha256=sSx4Lnfdlze3mRSRtYy0Q1c3_bzNVT7jL2x180MMYkg,779
|
|
37
46
|
codenerix_email/migrations/__pycache__/0008_auto_20171201_0928.cpython-35.pyc,sha256=Df1c2lc4oumQRChm11uns52Kj1NyBvNlosTEpn2dDi8,839
|
|
38
47
|
codenerix_email/migrations/__pycache__/0008_auto_20171201_0928.cpython-39.pyc,sha256=YQE0mlPzQ-MXjrPcJVK74O_rg6hsSnKJfTlqttYYlPU,794
|
|
48
|
+
codenerix_email/migrations/__pycache__/__init__.cpython-310.pyc,sha256=PdaaABMdLCzCMnJmxaylT_jnLb8l7rr6n5C4CGDX37A,151
|
|
39
49
|
codenerix_email/migrations/__pycache__/__init__.cpython-35.pyc,sha256=2g70xiMW6oJNkIpRM-0Dr5h7AUac-3xyCXPONxp9BBw,147
|
|
40
50
|
codenerix_email/migrations/__pycache__/__init__.cpython-39.pyc,sha256=qNj2NH0YvoWPnCKxkVZPsEFsbM05y7t1njMskNISdVQ,168
|
|
41
51
|
codenerix_email/static/codenerix_email/partials/emailmessages_rows.html,sha256=4J7KBRZPoWs_QaJ-hqCnz7A3DUW1mmZDYkBmgbrTh0w,994
|
|
42
|
-
django_codenerix_email-4.0.
|
|
43
|
-
django_codenerix_email-4.0.
|
|
44
|
-
django_codenerix_email-4.0.
|
|
45
|
-
django_codenerix_email-4.0.
|
|
46
|
-
django_codenerix_email-4.0.
|
|
52
|
+
django_codenerix_email-4.0.3.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
53
|
+
django_codenerix_email-4.0.3.dist-info/METADATA,sha256=vdKaQEUfC-A04WQ0y3JmDWIfTdBFLaMYXEzPjDnJnM0,2618
|
|
54
|
+
django_codenerix_email-4.0.3.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110
|
|
55
|
+
django_codenerix_email-4.0.3.dist-info/top_level.txt,sha256=lljSA0iKE_UBEM5gIrGQwioC_i8Jjnp-aR1LFElENgw,16
|
|
56
|
+
django_codenerix_email-4.0.3.dist-info/RECORD,,
|
|
File without changes
|
{django_codenerix_email-4.0.1.dist-info → django_codenerix_email-4.0.3.dist-info}/top_level.txt
RENAMED
|
File without changes
|