django-codenerix-email 4.0.40__py2.py3-none-any.whl → 4.0.41__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.
@@ -1,4 +1,4 @@
1
- __version__ = "4.0.40"
1
+ __version__ = "4.0.41"
2
2
 
3
3
  __authors__ = [
4
4
  "Juan Miguel Taboada Godoy <juanmi@juanmitaboada.com>",
@@ -1,4 +1,5 @@
1
1
  import re
2
+ import codecs
2
3
  from textwrap import dedent
3
4
  from argparse import RawTextHelpFormatter
4
5
 
@@ -144,6 +145,24 @@ class Command(BaseCommand):
144
145
  "--rewrite", action="store_true", help="Rewrite existing"
145
146
  )
146
147
 
148
+ def validate_encoding(self, encoding: str | None) -> str:
149
+ """
150
+ Validates and returns a safe encoding name.
151
+ """
152
+ # If an encoding is specified, verify it's valid
153
+ if encoding:
154
+ try:
155
+ # Attempt to look up the encoding to see if it's known
156
+ codecs.lookup(encoding)
157
+ except LookupError:
158
+ # If the lookup fails, the encoding is unknown
159
+ # Fall back to a safe default like 'latin-1'
160
+ encoding = "latin-1"
161
+ else:
162
+ # If no encoding is specified, use a default
163
+ encoding = "utf-8"
164
+ return encoding
165
+
147
166
  def handle(self, *args, **options):
148
167
  # Get configuration
149
168
  self.silent = options["silent"]
@@ -328,10 +347,15 @@ class Command(BaseCommand):
328
347
  # Parse the email
329
348
  msg = message_from_bytes(raw_email)
330
349
 
331
- # Extract subject, efrom, eto & eid
350
+ # Extract subject
332
351
  subject, encoding = decode_header(msg["Subject"])[0]
352
+
353
+ # Decode subject if it's bytes
333
354
  if isinstance(subject, bytes):
334
- subject = subject.decode(encoding or "utf-8")
355
+ charset = self.validate_encoding(encoding)
356
+ subject = subject.decode(charset, "ignore")
357
+
358
+ # Extract other headers
335
359
  efrom = msg.get("From")
336
360
  eto = msg.get("To")
337
361
  eid = msg.get("Message-ID")
@@ -353,22 +377,31 @@ class Command(BaseCommand):
353
377
  for part in msg.walk():
354
378
  content_type = part.get_content_type()
355
379
  if content_type == "text/plain" and not body_plain:
380
+ charset = self.validate_encoding(
381
+ part.get_content_charset()
382
+ )
356
383
  body_plain = part.get_payload(
357
384
  decode=True
358
385
  ).decode(
359
- part.get_content_charset() or "utf-8",
386
+ charset,
360
387
  "ignore",
361
388
  )
362
389
  elif content_type == "text/html" and not body_html:
390
+ charset = self.validate_encoding(
391
+ part.get_content_charset()
392
+ )
363
393
  body_html = part.get_payload(
364
394
  decode=True
365
395
  ).decode(
366
- part.get_content_charset() or "utf-8",
396
+ charset,
367
397
  "ignore",
368
398
  )
369
399
  else:
400
+ charset = self.validate_encoding(
401
+ msg.get_content_charset()
402
+ )
370
403
  body_plain = msg.get_payload(decode=True).decode(
371
- msg.get_content_charset() or "utf-8",
404
+ charset,
372
405
  "ignore",
373
406
  )
374
407
 
@@ -416,9 +449,10 @@ class Command(BaseCommand):
416
449
  headers = {}
417
450
  for header, value in msg.items():
418
451
  decoded_value, encoding = decode_header(value)[0]
452
+ charset = self.validate_encoding(encoding)
419
453
  if isinstance(decoded_value, bytes):
420
454
  decoded_value = decoded_value.decode(
421
- encoding or "utf-8", "ignore"
455
+ charset, "ignore"
422
456
  )
423
457
  headers[header] = decoded_value
424
458
 
@@ -596,7 +630,9 @@ class Command(BaseCommand):
596
630
  headers_payload = part.get_payload(decode=True)
597
631
  if isinstance(headers_payload, bytes):
598
632
  # Decode using the specified charset
599
- charset = part.get_content_charset() or "utf-8"
633
+ charset = self.validate_encoding(
634
+ part.get_content_charset()
635
+ )
600
636
  headers_text = headers_payload.decode(
601
637
  charset, errors="ignore"
602
638
  )
@@ -620,7 +656,9 @@ class Command(BaseCommand):
620
656
  payload = part.get_payload(decode=True)
621
657
  if isinstance(payload, bytes):
622
658
  # Decode using the specified charset
623
- charset = part.get_content_charset() or "utf-8"
659
+ charset = self.validate_encoding(
660
+ part.get_content_charset()
661
+ )
624
662
  body_text += payload.decode(
625
663
  charset, errors="ignore"
626
664
  )
@@ -631,7 +669,9 @@ class Command(BaseCommand):
631
669
  payload = msg.get_payload(decode=True)
632
670
  if isinstance(payload, bytes):
633
671
  # Decode using the specified charset
634
- charset = msg.get_content_charset() or "utf-8"
672
+ charset = self.validate_encoding(
673
+ msg.get_content_charset()
674
+ )
635
675
  body_text = payload.decode(
636
676
  charset, errors="ignore"
637
677
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-codenerix-email
3
- Version: 4.0.40
3
+ Version: 4.0.41
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>
@@ -1,5 +1,4 @@
1
- codenerix_email/.models.py.swp,sha256=sktik9iVIMa7EutN3nhqiJvvO3pAA4ZPGkD4cFvMxp0,40960
2
- codenerix_email/__init__.py,sha256=iu8TZi-9JIsQubz2hdtLDE1F9L-XrdUGhgRaDCNilME,149
1
+ codenerix_email/__init__.py,sha256=fvnPvF-O5l4qg-_eeRjKHdMZDzfLHFHFDi1l8fzeLQ4,149
3
2
  codenerix_email/admin.py,sha256=w259UKFk_opGEl6PJjYHXWAHQ_8emgqmiixKT5Rid4A,1180
4
3
  codenerix_email/apps.py,sha256=WXqu1XQibDDyCvvQYt2JbTK4GIpW8BNv5DCbRJS2mmk,149
5
4
  codenerix_email/forms.py,sha256=P5w-ebxLR1V10RFDqO_R5vvZV-vY6SLTzVb1OLdFZE0,5710
@@ -828,8 +827,8 @@ codenerix_email/.mypy_cache/3.10/zoneinfo/_common.data.json,sha256=e4xbNKL_yQ5h5
828
827
  codenerix_email/.mypy_cache/3.10/zoneinfo/_common.meta.json,sha256=5K19XWobpSjKwiv7bZFZRcxsEfoh7b-FhYcmqB-2Iic,1737
829
828
  codenerix_email/.mypy_cache/3.10/zoneinfo/_tzpath.data.json,sha256=CFx7Q1XfUhhuNX69prkxyirG8rfvEDCNgEHWQigKC_A,5632
830
829
  codenerix_email/.mypy_cache/3.10/zoneinfo/_tzpath.meta.json,sha256=d1HJ_xFBI1orlZSVhH0gHWLI-dJG3zY-ZOlctOl62yU,1765
831
- codenerix_email/__pycache__/__init__.cpython-310.pyc,sha256=eWWSyDve9FPvyJlFakWAx-ukvTzE6-yzrdbtlV30aaE,313
832
- codenerix_email/__pycache__/__init__.cpython-311.pyc,sha256=TXTEa1LmC28a-J-IxfH9kCJ0ZXggGZexMZDC4yPBvdM,337
830
+ codenerix_email/__pycache__/__init__.cpython-310.pyc,sha256=15V6lHDQ0IWV_UqdkRd4uPnweplUuyHbpl8lpW1wUTI,313
831
+ codenerix_email/__pycache__/__init__.cpython-311.pyc,sha256=UWUl2oUBod7dR46Nr9F955JjBzb5Hw5FLg0DZAJ3XNk,337
833
832
  codenerix_email/__pycache__/__init__.cpython-35.pyc,sha256=dl9lYAgrokJptUj3JAhiqTlX7d_CbncOxZeTc1USc88,308
834
833
  codenerix_email/__pycache__/__init__.cpython-37.pyc,sha256=5d1CeFU5DrfnwrRpvSw1bHvLN9hoHXjUA3ln3rXCDo8,306
835
834
  codenerix_email/__pycache__/__init__.cpython-39.pyc,sha256=0c6KWU_eOTlF5l9fNWv8l41b0LcfVQNUsqDvJTv2YyU,300
@@ -869,7 +868,7 @@ codenerix_email/management/__pycache__/__init__.cpython-35.pyc,sha256=sBoEWs6zdI
869
868
  codenerix_email/management/__pycache__/__init__.cpython-39.pyc,sha256=uPXklfliVd3b8pLOJQT9ZeKcqmJMrGychvt68BsPulY,168
870
869
  codenerix_email/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
871
870
  codenerix_email/management/commands/email_test.py,sha256=SPsiq0s48sEX_G3piNHq-c1gDOH800H2zTvM19ei2LY,5605
872
- codenerix_email/management/commands/emails_recv.py,sha256=iksLQQKh-oXWBe5PAg16KsdjZQfdVFfO5y_sI4BBf84,36089
871
+ codenerix_email/management/commands/emails_recv.py,sha256=6MRABJzVSvOcGzz7qH-1_q9U3o8yNGBVlPB6lkvYlfU,37562
873
872
  codenerix_email/management/commands/emails_send.py,sha256=scCFklro4WVMYm-1ataSjUMsPT-Ie5u_DdA55CQcTCQ,7944
874
873
  codenerix_email/management/commands/recv_emails.py,sha256=aXmhdXlamiNxRpMIDSKBXUBhkOcwi5l_Pme7jSQUCME,273
875
874
  codenerix_email/management/commands/send_emails.py,sha256=a1MnpvZKAEFdXNfmI5oFUkVxy4PZ1AjaJS6GH90zeD0,273
@@ -1690,8 +1689,8 @@ codenerix_email/migrations/__pycache__/__init__.cpython-35.pyc,sha256=2g70xiMW6o
1690
1689
  codenerix_email/migrations/__pycache__/__init__.cpython-39.pyc,sha256=qNj2NH0YvoWPnCKxkVZPsEFsbM05y7t1njMskNISdVQ,168
1691
1690
  codenerix_email/static/codenerix_email/emailmessages_rows.html,sha256=cA2ru5ti9WnPhhvFNEpI2tTR7gZzUYXWdzngRKU6a7k,2196
1692
1691
  codenerix_email/static/codenerix_email/emailreceiveds_rows.html,sha256=u9DXVdzKhx9WlJgcK_cT2DfGp9bGIKTBn3LDQplB4g4,2032
1693
- django_codenerix_email-4.0.40.dist-info/LICENSE,sha256=IXMIpi75XsrJt1Sznt4EftT9c_4X0C9eqK4tHhH8H48,11339
1694
- django_codenerix_email-4.0.40.dist-info/METADATA,sha256=n1dhoEWbAVnuKJfC3Xy9uyoITL0owxv6hKaRLeRQEB8,2676
1695
- django_codenerix_email-4.0.40.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110
1696
- django_codenerix_email-4.0.40.dist-info/top_level.txt,sha256=lljSA0iKE_UBEM5gIrGQwioC_i8Jjnp-aR1LFElENgw,16
1697
- django_codenerix_email-4.0.40.dist-info/RECORD,,
1692
+ django_codenerix_email-4.0.41.dist-info/LICENSE,sha256=IXMIpi75XsrJt1Sznt4EftT9c_4X0C9eqK4tHhH8H48,11339
1693
+ django_codenerix_email-4.0.41.dist-info/METADATA,sha256=EZuTjqR4JMJ9UnNCudgk6mNmFnIlBjZng24g08-k_JA,2676
1694
+ django_codenerix_email-4.0.41.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110
1695
+ django_codenerix_email-4.0.41.dist-info/top_level.txt,sha256=lljSA0iKE_UBEM5gIrGQwioC_i8Jjnp-aR1LFElENgw,16
1696
+ django_codenerix_email-4.0.41.dist-info/RECORD,,
Binary file