/
lib.py
171 lines (131 loc) · 5.25 KB
/
lib.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
"""
django-helpdesk - A Django powered ticket tracker for small enterprise.
(c) Copyright 2008 Jutda. All Rights Reserved. See LICENSE for details.
lib.py - Common functions (eg multipart e-mail)
"""
import logging
import mimetypes
from django.conf import settings
from django.utils.encoding import smart_text
from helpdesk.models import FollowUpAttachment
logger = logging.getLogger('helpdesk')
def ticket_template_context(ticket):
context = {}
for field in ('title', 'created', 'modified', 'submitter_email',
'status', 'get_status_display', 'on_hold', 'description',
'resolution', 'priority', 'get_priority_display',
'last_escalation', 'ticket', 'ticket_for_url', 'merged_to',
'get_status', 'ticket_url', 'staff_url', '_get_assigned_to'
):
attr = getattr(ticket, field, None)
if callable(attr):
context[field] = '%s' % attr()
else:
context[field] = attr
context['assigned_to'] = context['_get_assigned_to']
return context
def queue_template_context(queue):
context = {}
for field in ('title', 'slug', 'email_address', 'from_address', 'locale'):
attr = getattr(queue, field, None)
if callable(attr):
context[field] = attr()
else:
context[field] = attr
return context
def safe_template_context(ticket):
"""
Return a dictionary that can be used as a template context to render
comments and other details with ticket or queue parameters. Note that
we don't just provide the Ticket & Queue objects to the template as
they could reveal confidential information. Just imagine these two options:
* {{ ticket.queue.email_box_password }}
* {{ ticket.assigned_to.password }}
Ouch!
The downside to this is that if we make changes to the model, we will also
have to update this code. Perhaps we can find a better way in the future.
"""
context = {
'queue': queue_template_context(ticket.queue),
'ticket': ticket_template_context(ticket),
}
context['ticket']['queue'] = context['queue']
return context
def text_is_spam(text, request):
# Based on a blog post by 'sciyoshi':
# http://sciyoshi.com/blog/2008/aug/27/using-akismet-djangos-new-comments-framework/
# This will return 'True' is the given text is deemed to be spam, or
# False if it is not spam. If it cannot be checked for some reason, we
# assume it isn't spam.
from django.contrib.sites.models import Site
from django.core.exceptions import ImproperlyConfigured
try:
from akismet import Akismet
except ImportError:
return False
try:
site = Site.objects.get_current()
except ImproperlyConfigured:
site = Site(domain='configure-django-sites.com')
# see https://akismet.readthedocs.io/en/latest/overview.html#using-akismet
apikey = None
if hasattr(settings, 'TYPEPAD_ANTISPAM_API_KEY'):
apikey = settings.TYPEPAD_ANTISPAM_API_KEY
elif hasattr(settings, 'PYTHON_AKISMET_API_KEY'):
# new env var expected by python-akismet package
apikey = settings.PYTHON_AKISMET_API_KEY
elif hasattr(settings, 'AKISMET_API_KEY'):
# deprecated, but kept for backward compatibility
apikey = settings.AKISMET_API_KEY
else:
return False
ak = Akismet(
blog_url='http://%s/' % site.domain,
key=apikey,
)
if hasattr(settings, 'TYPEPAD_ANTISPAM_API_KEY'):
ak.baseurl = 'api.antispam.typepad.com/1.1/'
if ak.verify_key():
ak_data = {
'user_ip': request.META.get('REMOTE_ADDR', '127.0.0.1'),
'user_agent': request.META.get('HTTP_USER_AGENT', ''),
'referrer': request.META.get('HTTP_REFERER', ''),
'comment_type': 'comment',
'comment_author': '',
}
return ak.comment_check(smart_text(text), data=ak_data)
return False
def process_attachments(followup, attached_files):
max_email_attachment_size = getattr(settings, 'HELPDESK_MAX_EMAIL_ATTACHMENT_SIZE', 512000)
attachments = []
for attached in attached_files:
if attached.size:
filename = smart_text(attached.name)
att = FollowUpAttachment(
followup=followup,
file=attached,
filename=filename,
mime_type=attached.content_type or
mimetypes.guess_type(filename, strict=False)[0] or
'application/octet-stream',
size=attached.size,
)
att.full_clean()
att.save()
if attached.size < max_email_attachment_size:
# Only files smaller than 512kb (or as defined in
# settings.HELPDESK_MAX_EMAIL_ATTACHMENT_SIZE) are sent via email.
attachments.append([filename, att.file])
return attachments
def format_time_spent(time_spent):
"""Format time_spent attribute to "[H]HHh:MMm" text string to be allign in
all graphical outputs
"""
if time_spent:
time_spent = "{0:02d}h:{1:02d}m".format(
time_spent.seconds // 3600,
time_spent.seconds // 60
)
else:
time_spent = ""
return time_spent