django-codenerix-email 4.0.40__py2.py3-none-any.whl → 4.0.42__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.42"
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, errors="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,23 +377,25 @@ 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
- ).decode(
359
- part.get_content_charset() or "utf-8",
360
- "ignore",
361
- )
385
+ ).decode(charset, errors="ignore")
362
386
  elif content_type == "text/html" and not body_html:
387
+ charset = self.validate_encoding(
388
+ part.get_content_charset()
389
+ )
363
390
  body_html = part.get_payload(
364
391
  decode=True
365
- ).decode(
366
- part.get_content_charset() or "utf-8",
367
- "ignore",
368
- )
392
+ ).decode(charset, errors="ignore")
369
393
  else:
394
+ charset = self.validate_encoding(
395
+ msg.get_content_charset()
396
+ )
370
397
  body_plain = msg.get_payload(decode=True).decode(
371
- msg.get_content_charset() or "utf-8",
372
- "ignore",
398
+ charset, errors="ignore"
373
399
  )
374
400
 
375
401
  # Logic to associate replies/bounces with sent emails
@@ -416,9 +442,10 @@ class Command(BaseCommand):
416
442
  headers = {}
417
443
  for header, value in msg.items():
418
444
  decoded_value, encoding = decode_header(value)[0]
445
+ charset = self.validate_encoding(encoding)
419
446
  if isinstance(decoded_value, bytes):
420
447
  decoded_value = decoded_value.decode(
421
- encoding or "utf-8", "ignore"
448
+ charset, errors="ignore"
422
449
  )
423
450
  headers[header] = decoded_value
424
451
 
@@ -596,7 +623,9 @@ class Command(BaseCommand):
596
623
  headers_payload = part.get_payload(decode=True)
597
624
  if isinstance(headers_payload, bytes):
598
625
  # Decode using the specified charset
599
- charset = part.get_content_charset() or "utf-8"
626
+ charset = self.validate_encoding(
627
+ part.get_content_charset()
628
+ )
600
629
  headers_text = headers_payload.decode(
601
630
  charset, errors="ignore"
602
631
  )
@@ -620,7 +649,9 @@ class Command(BaseCommand):
620
649
  payload = part.get_payload(decode=True)
621
650
  if isinstance(payload, bytes):
622
651
  # Decode using the specified charset
623
- charset = part.get_content_charset() or "utf-8"
652
+ charset = self.validate_encoding(
653
+ part.get_content_charset()
654
+ )
624
655
  body_text += payload.decode(
625
656
  charset, errors="ignore"
626
657
  )
@@ -631,7 +662,9 @@ class Command(BaseCommand):
631
662
  payload = msg.get_payload(decode=True)
632
663
  if isinstance(payload, bytes):
633
664
  # Decode using the specified charset
634
- charset = msg.get_content_charset() or "utf-8"
665
+ charset = self.validate_encoding(
666
+ msg.get_content_charset()
667
+ )
635
668
  body_text = payload.decode(
636
669
  charset, errors="ignore"
637
670
  )
@@ -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.42
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=zUdeNRRlJihOcJjhw5Q9V7lfEz0fapMDZg6sDEI2688,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=l9GJtMt8iO4CEAQw7GF-VKHRSXKp1LM0u3anmv8DTNo,313
831
+ codenerix_email/__pycache__/__init__.cpython-311.pyc,sha256=JdakKHcPF2vqH90_mlw7sAfIVJgpl_o6PgPOmfKFPnY,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=C6DYD9WIT9vDDmSvxRf6Ms_SjoHMQYKZB49Bt7yr7cg,37354
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.42.dist-info/LICENSE,sha256=IXMIpi75XsrJt1Sznt4EftT9c_4X0C9eqK4tHhH8H48,11339
1693
+ django_codenerix_email-4.0.42.dist-info/METADATA,sha256=eATIXaTRThHDlWhFC90e3Ungre5mgBrglNznAm4rxhc,2676
1694
+ django_codenerix_email-4.0.42.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110
1695
+ django_codenerix_email-4.0.42.dist-info/top_level.txt,sha256=lljSA0iKE_UBEM5gIrGQwioC_i8Jjnp-aR1LFElENgw,16
1696
+ django_codenerix_email-4.0.42.dist-info/RECORD,,
Binary file