forked from extern/django-helpdesk
Merge branch 'main' into pypi_release
This commit is contained in:
commit
b716e046b2
@ -687,8 +687,8 @@ def extract_part_data(
|
|||||||
name = f"part-{counter}{ext}"
|
name = f"part-{counter}{ext}"
|
||||||
else:
|
else:
|
||||||
name = f"part-{counter}_{name}"
|
name = f"part-{counter}_{name}"
|
||||||
|
payload = part.as_string() if part.is_multipart() else part.get_payload(decode=True)
|
||||||
files.append(SimpleUploadedFile(name, part.get_payload(decode=True), mimetypes.guess_type(name)[0]))
|
files.append(SimpleUploadedFile(name, payload, mimetypes.guess_type(name)[0]))
|
||||||
logger.debug("Found MIME attachment %s", name)
|
logger.debug("Found MIME attachment %s", name)
|
||||||
return part_body, part_full_body
|
return part_body, part_full_body
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import helpdesk.email
|
|||||||
from helpdesk.email import extract_part_data, object_from_message
|
from helpdesk.email import extract_part_data, object_from_message
|
||||||
from helpdesk.exceptions import DeleteIgnoredTicketException, IgnoreTicketException
|
from helpdesk.exceptions import DeleteIgnoredTicketException, IgnoreTicketException
|
||||||
from helpdesk.management.commands.get_email import Command
|
from helpdesk.management.commands.get_email import Command
|
||||||
from helpdesk.models import FollowUp, FollowUpAttachment, IgnoreEmail, Queue, Ticket, TicketCC
|
from helpdesk.models import Attachment, FollowUp, FollowUpAttachment, IgnoreEmail, Queue, Ticket, TicketCC
|
||||||
from helpdesk.tests import utils
|
from helpdesk.tests import utils
|
||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
@ -230,6 +230,29 @@ class GetEmailCommonTests(TestCase):
|
|||||||
followup = ticket.followup_set.get()
|
followup = ticket.followup_set.get()
|
||||||
self.assertEqual(1, followup.followupattachment_set.count())
|
self.assertEqual(1, followup.followupattachment_set.count())
|
||||||
|
|
||||||
|
def test_email_with_multipart_as_attachment(self):
|
||||||
|
"""
|
||||||
|
Is a multipart attachment to an email correctly saved as an attachment
|
||||||
|
"""
|
||||||
|
att_filename = 'email_attachment.eml'
|
||||||
|
message, _, _ = utils.generate_multipart_email(type_list=['plain', 'html'])
|
||||||
|
email_attachment, _, _ = utils.generate_multipart_email(type_list=['plain', 'html'])
|
||||||
|
att_content = email_attachment.as_string()
|
||||||
|
message.attach(utils.generate_file_mime_part(filename=att_filename, content=att_content))
|
||||||
|
|
||||||
|
object_from_message(message.as_string(), self.queue_public, self.logger)
|
||||||
|
|
||||||
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
|
self.assertEqual(f'[test-1] {message.get("subject")} (Opened)', mail.outbox[0].subject)
|
||||||
|
|
||||||
|
ticket = Ticket.objects.get()
|
||||||
|
followup = ticket.followup_set.get()
|
||||||
|
att_retrieved: Attachment = followup.followupattachment_set.get()
|
||||||
|
self.assertTrue(att_retrieved.filename.endswith(att_filename), "Filename of attached multipart not detected: %s" % (att_retrieved.filename))
|
||||||
|
with att_retrieved.file.open('r') as f:
|
||||||
|
retrieved_content = f.read()
|
||||||
|
self.assertEquals(att_content, retrieved_content, "Retrieved attachment content different to original :\n\n%s\n\n%s" % (att_content, retrieved_content))
|
||||||
|
|
||||||
|
|
||||||
class GetEmailParametricTemplate(object):
|
class GetEmailParametricTemplate(object):
|
||||||
"""TestCase that checks basic email functionality across methods and socks configs."""
|
"""TestCase that checks basic email functionality across methods and socks configs."""
|
||||||
|
@ -141,14 +141,15 @@ def generate_email_address(
|
|||||||
# format email address for RFC 2822 and return
|
# format email address for RFC 2822 and return
|
||||||
return email.utils.formataddr((real_name, email_address)), email_address, first_name, last_name
|
return email.utils.formataddr((real_name, email_address)), email_address, first_name, last_name
|
||||||
|
|
||||||
def generate_file_mime_part(locale: str="en_US",filename: str = None) -> Message:
|
def generate_file_mime_part(locale: str="en_US",filename: str = None, content: str = None) -> Message:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param locale: change this to generate locale specific file name and attachment content
|
:param locale: change this to generate locale specific file name and attachment content
|
||||||
:param filename: pass a file name if you want to specify a specific name otherwise a random name will be generated
|
:param filename: pass a file name if you want to specify a specific name otherwise a random name will be generated
|
||||||
|
:param content: pass a string value if you want have specific content otherwise a random string will be generated
|
||||||
"""
|
"""
|
||||||
part = MIMEBase('application', 'octet-stream')
|
part = MIMEBase('application', 'octet-stream')
|
||||||
part.set_payload(get_fake("text", locale=locale, min_length=1024))
|
part.set_payload(get_fake("text", locale=locale, min_length=1024) if content is None else content)
|
||||||
encoders.encode_base64(part)
|
encoders.encode_base64(part)
|
||||||
if not filename:
|
if not filename:
|
||||||
filename = get_fake("word", locale=locale, min_length=8) + ".txt"
|
filename = get_fake("word", locale=locale, min_length=8) + ".txt"
|
||||||
@ -227,7 +228,7 @@ def generate_mime_part(locale: str="en_US",
|
|||||||
return msg
|
return msg
|
||||||
|
|
||||||
def generate_multipart_email(locale: str="en_US",
|
def generate_multipart_email(locale: str="en_US",
|
||||||
type_list: typing.List[str]=["plain", "html", "attachment"],
|
type_list: typing.List[str]=["plain", "html", "image"],
|
||||||
use_short_email: bool=False
|
use_short_email: bool=False
|
||||||
) -> typing.Tuple[Message, typing.Tuple[str, str], typing.Tuple[str, str]]:
|
) -> typing.Tuple[Message, typing.Tuple[str, str], typing.Tuple[str, str]]:
|
||||||
"""
|
"""
|
||||||
|
@ -10,7 +10,7 @@ from ..lib import format_time_spent
|
|||||||
from ..templated_email import send_templated_mail
|
from ..templated_email import send_templated_mail
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.decorators import user_passes_test
|
from django.contrib.auth.decorators import user_passes_test
|
||||||
@ -24,7 +24,7 @@ from django.http import Http404, HttpResponse, HttpResponseRedirect, JsonRespons
|
|||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.dateparse import parse_datetime
|
from django.utils.dateparse import parse_date, parse_datetime
|
||||||
from django.utils.html import escape
|
from django.utils.html import escape
|
||||||
from django.utils.timezone import make_aware
|
from django.utils.timezone import make_aware
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
@ -521,7 +521,8 @@ def get_due_date_from_request_or_ticket(
|
|||||||
due_date = request.POST.get('due_date', None) or None
|
due_date = request.POST.get('due_date', None) or None
|
||||||
|
|
||||||
if due_date is not None:
|
if due_date is not None:
|
||||||
due_date = make_aware(parse_datetime(due_date))
|
parsed_date = parse_datetime(due_date) or datetime.combine(parse_date(due_date), time())
|
||||||
|
due_date = make_aware(parsed_date)
|
||||||
else:
|
else:
|
||||||
due_date_year = int(request.POST.get('due_date_year', 0))
|
due_date_year = int(request.POST.get('due_date_year', 0))
|
||||||
due_date_month = int(request.POST.get('due_date_month', 0))
|
due_date_month = int(request.POST.get('due_date_month', 0))
|
||||||
|
Loading…
Reference in New Issue
Block a user