mirror of
https://gitea.mueller.network/extern/django-helpdesk.git
synced 2025-04-09 18:39:20 +02:00
UPDATED: Finished moving Message-Id field from <Ticket> to <FollowUp> model.
This commit is contained in:
parent
c2e9ee26af
commit
be07fdff6c
@ -168,9 +168,25 @@ def decode_mail_headers(string):
|
|||||||
decoded = decode_header(string)
|
decoded = decode_header(string)
|
||||||
return u' '.join([unicode(msg, charset or 'utf-8') for msg, charset in decoded])
|
return u' '.join([unicode(msg, charset or 'utf-8') for msg, charset in decoded])
|
||||||
|
|
||||||
|
def create_ticket_cc(ticket, cc_list):
|
||||||
|
|
||||||
|
# Local import to deal with non-defined / circular reference problem
|
||||||
|
from helpdesk.views.staff import User, subscribe_to_ticket_updates
|
||||||
|
|
||||||
|
for cced_email in cc_list:
|
||||||
|
|
||||||
|
user = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
user = User.objects.get(email=cced_email)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
ticket_cc = subscribe_to_ticket_updates(ticket=ticket, user=user, email=cced_email)
|
||||||
|
|
||||||
def create_object_from_email_message(message, ticket_id, payload, files, quiet):
|
def create_object_from_email_message(message, ticket_id, payload, files, quiet):
|
||||||
|
|
||||||
ticket, new = None, False
|
ticket, followup, new = None, None, False
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
|
|
||||||
queue = payload['queue']
|
queue = payload['queue']
|
||||||
@ -178,24 +194,28 @@ def create_object_from_email_message(message, ticket_id, payload, files, quiet):
|
|||||||
|
|
||||||
message_id = message.get('Message-Id')
|
message_id = message.get('Message-Id')
|
||||||
in_reply_to = message.get('In-Reply-To')
|
in_reply_to = message.get('In-Reply-To')
|
||||||
|
cc_list = message.get('Cc')
|
||||||
|
|
||||||
|
if in_reply_to is not None:
|
||||||
|
followup = FollowUp.objects.get(message_id=in_reply_to)
|
||||||
|
ticket = followup.ticket
|
||||||
|
|
||||||
query_set = Ticket.objects.filter(Q(id=ticket_id)|Q(submitter_email_id=message_id))
|
|
||||||
if query_set.count() == 0:
|
|
||||||
ticket = None
|
|
||||||
new = True
|
|
||||||
else:
|
else:
|
||||||
t = query_set.first()
|
try:
|
||||||
|
t = Ticket.objects.get(id=ticket_id)
|
||||||
|
new = False
|
||||||
|
except Ticket.DoesNotExist:
|
||||||
|
ticket = None
|
||||||
|
|
||||||
# New issue, create a new <Ticket> instance
|
# New issue, create a new <Ticket> instance
|
||||||
if ticket is None:
|
if ticket is None:
|
||||||
t = Ticket.objects.create(
|
t = Ticket.objects.create(
|
||||||
title=payload['subject'],
|
title = payload['subject'],
|
||||||
queue=queue,
|
queue = queue,
|
||||||
submitter_email=sender_email,
|
submitter_email = sender_email,
|
||||||
submitter_email_id=message_id,
|
created = now,
|
||||||
created=now,
|
description = payload['body'],
|
||||||
description=payload['body'],
|
priority = payload['priority'],
|
||||||
priority=payload['priority'],
|
|
||||||
)
|
)
|
||||||
t.save()
|
t.save()
|
||||||
|
|
||||||
@ -213,6 +233,7 @@ def create_object_from_email_message(message, ticket_id, payload, files, quiet):
|
|||||||
date = now,
|
date = now,
|
||||||
public = True,
|
public = True,
|
||||||
comment = payload['body'],
|
comment = payload['body'],
|
||||||
|
message_id = message_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
if t.status == Ticket.REOPENED_STATUS:
|
if t.status == Ticket.REOPENED_STATUS:
|
||||||
@ -242,6 +263,9 @@ def create_object_from_email_message(message, ticket_id, payload, files, quiet):
|
|||||||
|
|
||||||
context = safe_template_context(t)
|
context = safe_template_context(t)
|
||||||
|
|
||||||
|
if cc_list is not None:
|
||||||
|
create_ticket_cc(t, cc_list.split(','))
|
||||||
|
|
||||||
if new:
|
if new:
|
||||||
|
|
||||||
if sender_email:
|
if sender_email:
|
||||||
@ -302,6 +326,7 @@ def create_object_from_email_message(message, ticket_id, payload, files, quiet):
|
|||||||
|
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
||||||
def object_from_message(message, queue, quiet):
|
def object_from_message(message, queue, quiet):
|
||||||
# 'message' must be an RFC822 formatted message.
|
# 'message' must be an RFC822 formatted message.
|
||||||
|
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.1 on 2016-02-16 18:13
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('helpdesk', '0012_add_submitter_email_id_field_to_ticket'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='ticket',
|
||||||
|
name='submitter_email_id',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='followup',
|
||||||
|
name='message_id',
|
||||||
|
field=models.CharField(blank=True, editable=False, help_text="The Message ID of the submitter's email.", max_length=256, null=True, verbose_name='E-Mail ID'),
|
||||||
|
),
|
||||||
|
]
|
@ -560,28 +560,6 @@ class Ticket(models.Model):
|
|||||||
return ('helpdesk_view', (self.id,))
|
return ('helpdesk_view', (self.id,))
|
||||||
get_absolute_url = models.permalink(get_absolute_url)
|
get_absolute_url = models.permalink(get_absolute_url)
|
||||||
|
|
||||||
def process_rfc_2822_data(self):
|
|
||||||
|
|
||||||
if len(self.rfc_2822_items) > 0:
|
|
||||||
cc_list = self.rfc_2822_items.get('rfc_2822_cc', [])
|
|
||||||
|
|
||||||
for cced_email in cc_list:
|
|
||||||
|
|
||||||
user = None
|
|
||||||
|
|
||||||
user_model = get_user_model()
|
|
||||||
|
|
||||||
try:
|
|
||||||
user = user_model.objects.get(email=cced_email)
|
|
||||||
except user_model.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Local import to deal with non-defined / circular reference problem
|
|
||||||
from .views import staff
|
|
||||||
|
|
||||||
ticket_cc = staff.subscribe_to_ticket_updates(ticket=self, user=user, email=cced_email)
|
|
||||||
|
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not self.id:
|
if not self.id:
|
||||||
# This is a new ticket as no ID yet exists.
|
# This is a new ticket as no ID yet exists.
|
||||||
@ -594,9 +572,6 @@ class Ticket(models.Model):
|
|||||||
|
|
||||||
super(Ticket, self).save(*args, **kwargs)
|
super(Ticket, self).save(*args, **kwargs)
|
||||||
|
|
||||||
# Process RFC 2822 fields, if any
|
|
||||||
self.process_rfc_2822_data()
|
|
||||||
|
|
||||||
|
|
||||||
class FollowUpManager(models.Manager):
|
class FollowUpManager(models.Manager):
|
||||||
def private_followups(self):
|
def private_followups(self):
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
import email
|
import email
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from helpdesk.models import Queue, CustomField, Ticket, TicketCC
|
from helpdesk.models import Queue, CustomField, FollowUp, Ticket, TicketCC
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.test.client import Client
|
from django.test.client import Client
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
|
||||||
from helpdesk.management.commands.get_email import ticket_from_message
|
from helpdesk.management.commands.get_email import object_from_message
|
||||||
|
|
||||||
try: # python 3
|
try: # python 3
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
@ -57,7 +57,7 @@ class TicketBasicsTestCase(TestCase):
|
|||||||
submitter_email = 'foo@bar.py'
|
submitter_email = 'foo@bar.py'
|
||||||
|
|
||||||
msg.__setitem__('Message-ID', message_id)
|
msg.__setitem__('Message-ID', message_id)
|
||||||
msg.__setitem__('subject', self.ticket_data['title'])
|
msg.__setitem__('Subject', self.ticket_data['title'])
|
||||||
msg.__setitem__('From', submitter_email)
|
msg.__setitem__('From', submitter_email)
|
||||||
msg.__setitem__('To', self.queue_public.email_address)
|
msg.__setitem__('To', self.queue_public.email_address)
|
||||||
msg.__setitem__('Content-Type', 'text/plain;')
|
msg.__setitem__('Content-Type', 'text/plain;')
|
||||||
@ -65,12 +65,15 @@ class TicketBasicsTestCase(TestCase):
|
|||||||
|
|
||||||
email_count = len(mail.outbox)
|
email_count = len(mail.outbox)
|
||||||
|
|
||||||
ticket_from_message(str(msg), self.queue_public, quiet=True)
|
object_from_message(str(msg), self.queue_public, quiet=True)
|
||||||
ticket = Ticket.objects.get(title=self.ticket_data['title'], submitter_email_id=message_id)
|
|
||||||
|
followup = FollowUp.objects.get(message_id=message_id)
|
||||||
|
ticket = Ticket.objects.get(id=followup.ticket.id)
|
||||||
|
|
||||||
self.assertEqual(ticket.ticket_for_url, "q1-%s" % ticket.id)
|
self.assertEqual(ticket.ticket_for_url, "q1-%s" % ticket.id)
|
||||||
|
|
||||||
# As we have created an Ticket from an email, we notify the sender (+1) and the new and update queues (+2)
|
# As we have created an Ticket from an email, we notify the sender (+1)
|
||||||
|
# and the new and update queues (+2)
|
||||||
self.assertEqual(email_count + 1 + 2, len(mail.outbox))
|
self.assertEqual(email_count + 1 + 2, len(mail.outbox))
|
||||||
|
|
||||||
|
|
||||||
@ -81,29 +84,35 @@ class TicketBasicsTestCase(TestCase):
|
|||||||
"rfc_2822_cc" field when creating a <Ticket> instance.
|
"rfc_2822_cc" field when creating a <Ticket> instance.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
msg = email.message.Message()
|
||||||
|
|
||||||
message_id = uuid.uuid4().hex
|
message_id = uuid.uuid4().hex
|
||||||
|
submitter_email = 'foo@bar.py'
|
||||||
|
cc_list = ['bravo@example.net', 'charlie@foobar.com']
|
||||||
|
|
||||||
email_data = {
|
msg.__setitem__('Message-ID', message_id)
|
||||||
'Message-ID': message_id,
|
msg.__setitem__('Subject', self.ticket_data['title'])
|
||||||
'cc': ['bravo@example.net', 'charlie@foobar.com'],
|
msg.__setitem__('From', submitter_email)
|
||||||
}
|
msg.__setitem__('To', self.queue_public.email_address)
|
||||||
|
msg.__setitem__('Cc', ','.join(cc_list))
|
||||||
# Regular ticket from email creation process
|
msg.__setitem__('Content-Type', 'text/plain;')
|
||||||
self.ticket_data = {
|
msg.set_payload(self.ticket_data['description'])
|
||||||
'title': 'Test Ticket',
|
|
||||||
'description': 'Some Test Ticket',
|
|
||||||
'rfc_2822_cc': email_data.get('cc', [])
|
|
||||||
}
|
|
||||||
|
|
||||||
email_count = len(mail.outbox)
|
email_count = len(mail.outbox)
|
||||||
ticket_data = dict(queue=self.queue_public, **self.ticket_data)
|
|
||||||
ticket = Ticket.objects.create(**ticket_data)
|
object_from_message(str(msg), self.queue_public, quiet=True)
|
||||||
|
|
||||||
|
followup = FollowUp.objects.get(message_id=message_id)
|
||||||
|
ticket = Ticket.objects.get(id=followup.ticket.id)
|
||||||
self.assertEqual(ticket.ticket_for_url, "q1-%s" % ticket.id)
|
self.assertEqual(ticket.ticket_for_url, "q1-%s" % ticket.id)
|
||||||
self.assertEqual(email_count, len(mail.outbox))
|
|
||||||
|
# As we have created an Ticket from an email, we notify the sender (+1)
|
||||||
|
# and the new and update queues (+2)
|
||||||
|
self.assertEqual(email_count + 1 + 2, len(mail.outbox))
|
||||||
|
|
||||||
|
|
||||||
# Ensure that <TicketCC> is created
|
# Ensure that <TicketCC> is created
|
||||||
for cc_email in email_data.get('cc', []):
|
for cc_email in cc_list:
|
||||||
|
|
||||||
ticket_cc = TicketCC.objects.get(ticket=ticket, email=cc_email)
|
ticket_cc = TicketCC.objects.get(ticket=ticket, email=cc_email)
|
||||||
self.assertTrue(ticket_cc.ticket, ticket)
|
self.assertTrue(ticket_cc.ticket, ticket)
|
||||||
self.assertTrue(ticket_cc.email, cc_email)
|
self.assertTrue(ticket_cc.email, cc_email)
|
||||||
@ -115,29 +124,28 @@ class TicketBasicsTestCase(TestCase):
|
|||||||
"rfc_2822_cc" field is provided when creating a <Ticket> instance.
|
"rfc_2822_cc" field is provided when creating a <Ticket> instance.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
msg = email.message.Message()
|
||||||
|
|
||||||
message_id = uuid.uuid4().hex
|
message_id = uuid.uuid4().hex
|
||||||
|
submitter_email = 'foo@bar.py'
|
||||||
|
cc_list = ['null@example', 'invalid@foobar']
|
||||||
|
|
||||||
email_data = {
|
msg.__setitem__('Message-ID', message_id)
|
||||||
'Message-ID': message_id,
|
msg.__setitem__('Subject', self.ticket_data['title'])
|
||||||
'cc': ['null@example', 'invalid@foobar'],
|
msg.__setitem__('From', submitter_email)
|
||||||
}
|
msg.__setitem__('To', self.queue_public.email_address)
|
||||||
|
msg.__setitem__('Cc', ','.join(cc_list))
|
||||||
# Regular ticket from email creation process
|
msg.__setitem__('Content-Type', 'text/plain;')
|
||||||
self.ticket_data = {
|
msg.set_payload(self.ticket_data['description'])
|
||||||
'title': 'Test Ticket',
|
|
||||||
'description': 'Some Test Ticket',
|
|
||||||
'rfc_2822_cc': email_data.get('cc', [])
|
|
||||||
}
|
|
||||||
|
|
||||||
email_count = len(mail.outbox)
|
email_count = len(mail.outbox)
|
||||||
ticket_data = dict(queue=self.queue_public, **self.ticket_data)
|
|
||||||
ticket = Ticket.objects.create(**ticket_data)
|
|
||||||
self.assertEqual(ticket.ticket_for_url, "q1-%s" % ticket.id)
|
|
||||||
self.assertEqual(email_count, len(mail.outbox))
|
|
||||||
|
|
||||||
# Ensure that <TicketCC> is created
|
object_from_message(str(msg), self.queue_public, quiet=True)
|
||||||
for cc_email in email_data.get('cc', []):
|
|
||||||
|
|
||||||
|
ticket = Ticket.objects.get(title=self.ticket_data['title'])
|
||||||
|
|
||||||
|
# Ensure that <TicketCC> is created but the email field is not set
|
||||||
|
for cc_email in cc_list:
|
||||||
self.assertEquals(0, TicketCC.objects.filter(ticket=ticket, email=cc_email).count())
|
self.assertEquals(0, TicketCC.objects.filter(ticket=ticket, email=cc_email).count())
|
||||||
|
|
||||||
def test_create_ticket_public(self):
|
def test_create_ticket_public(self):
|
||||||
|
@ -346,6 +346,7 @@ def subscribe_to_ticket_updates(ticket, user=None, email=''):
|
|||||||
except ValidationError:
|
except ValidationError:
|
||||||
email = ''
|
email = ''
|
||||||
|
|
||||||
|
|
||||||
ticketcc = TicketCC()
|
ticketcc = TicketCC()
|
||||||
ticketcc.ticket = ticket
|
ticketcc.ticket = ticket
|
||||||
ticketcc.user = user
|
ticketcc.user = user
|
||||||
|
Loading…
Reference in New Issue
Block a user