gremmie@1
|
1 """Views for the messages application"""
|
gremmie@1
|
2
|
bgneal@371
|
3 import collections
|
gremmie@1
|
4 import datetime
|
bgneal@371
|
5
|
gremmie@1
|
6 from django.shortcuts import render_to_response
|
gremmie@1
|
7 from django.template import RequestContext
|
gremmie@1
|
8 from django.http import HttpResponseRedirect
|
gremmie@1
|
9 from django.contrib.auth.decorators import login_required
|
bgneal@178
|
10 from django.contrib import messages
|
gremmie@1
|
11 from django.shortcuts import get_object_or_404
|
gremmie@1
|
12 from django.core.urlresolvers import reverse
|
gremmie@1
|
13 from django.http import Http404
|
bgneal@156
|
14 from django.views.decorators.http import require_POST
|
gremmie@1
|
15
|
gremmie@1
|
16 from messages.models import Message
|
gremmie@1
|
17 from messages.models import Options
|
gremmie@1
|
18 from messages.forms import ComposeForm
|
gremmie@1
|
19 from messages.forms import OptionsForm
|
gremmie@1
|
20 from messages.utils import reply_subject
|
gremmie@1
|
21 from messages.utils import quote_message
|
gremmie@1
|
22
|
gremmie@1
|
23
|
gremmie@1
|
24 BOX_MAP = {
|
gremmie@1
|
25 'inbox': 'messages-inbox',
|
gremmie@1
|
26 'outbox': 'messages-outbox',
|
gremmie@1
|
27 'trash': 'messages-trash',
|
gremmie@1
|
28 }
|
gremmie@1
|
29
|
bgneal@371
|
30 MSG_DELETED, MSG_TRASHED, MSG_ERROR = range(3)
|
bgneal@371
|
31
|
gremmie@1
|
32
|
gremmie@1
|
33 def box_redirect(request):
|
gremmie@1
|
34 """
|
gremmie@1
|
35 Determines which box to redirect to by looking for a GET or
|
gremmie@1
|
36 POST parameter.
|
gremmie@1
|
37 """
|
gremmie@1
|
38 if request.method == 'GET':
|
gremmie@1
|
39 box = request.GET.get('box', 'inbox')
|
gremmie@1
|
40 else:
|
gremmie@1
|
41 box = request.POST.get('box', 'inbox')
|
gremmie@1
|
42 if BOX_MAP.has_key(box):
|
gremmie@1
|
43 url = reverse(BOX_MAP[box])
|
gremmie@1
|
44 else:
|
gremmie@1
|
45 url = reverse(BOX_MAP['inbox'])
|
gremmie@1
|
46 return HttpResponseRedirect(url)
|
gremmie@1
|
47
|
gremmie@1
|
48
|
gremmie@1
|
49 @login_required
|
gremmie@1
|
50 def inbox(request):
|
gremmie@1
|
51 """Displays the inbox for the user making the request."""
|
gremmie@1
|
52 msgs = Message.objects.inbox(request.user)
|
gremmie@1
|
53 return render_to_response('messages/inbox.html', {
|
gremmie@1
|
54 'msgs': msgs,
|
bgneal@371
|
55 },
|
gremmie@1
|
56 context_instance = RequestContext(request))
|
gremmie@1
|
57
|
gremmie@1
|
58
|
gremmie@1
|
59 @login_required
|
gremmie@1
|
60 def outbox(request):
|
gremmie@1
|
61 """Displays the outbox for the user making the request."""
|
gremmie@1
|
62 msgs = Message.objects.outbox(request.user)
|
gremmie@1
|
63 return render_to_response('messages/outbox.html', {
|
gremmie@1
|
64 'msgs': msgs,
|
bgneal@371
|
65 },
|
gremmie@1
|
66 context_instance = RequestContext(request))
|
gremmie@1
|
67
|
gremmie@1
|
68
|
gremmie@1
|
69 @login_required
|
gremmie@1
|
70 def trash(request):
|
gremmie@1
|
71 """Displays the trash for the user making the request."""
|
gremmie@1
|
72 msgs = Message.objects.trash(request.user)
|
gremmie@1
|
73 return render_to_response('messages/trash.html', {
|
gremmie@1
|
74 'msgs': msgs,
|
bgneal@371
|
75 },
|
gremmie@1
|
76 context_instance = RequestContext(request))
|
gremmie@1
|
77
|
gremmie@1
|
78
|
gremmie@1
|
79 @login_required
|
gremmie@1
|
80 def view(request, msg_id):
|
gremmie@1
|
81 """
|
gremmie@1
|
82 View a given message. Only the sender or receiver can see
|
gremmie@1
|
83 the message.
|
gremmie@1
|
84 """
|
gremmie@1
|
85 msg = get_object_or_404(Message, pk=msg_id)
|
gremmie@1
|
86 if msg.sender != request.user and msg.receiver != request.user:
|
gremmie@1
|
87 raise Http404
|
gremmie@1
|
88
|
gremmie@1
|
89 if msg.receiver == request.user and msg.read_date is None:
|
gremmie@1
|
90 msg.read_date = datetime.datetime.now()
|
gremmie@1
|
91 msg.save()
|
gremmie@1
|
92
|
gremmie@1
|
93 box = request.GET.get('box', None)
|
gremmie@1
|
94
|
gremmie@1
|
95 return render_to_response('messages/view.html', {
|
gremmie@1
|
96 'box': box,
|
gremmie@1
|
97 'msg': msg,
|
gremmie@1
|
98 'is_deleted': msg.is_deleted(request.user),
|
bgneal@371
|
99 },
|
gremmie@1
|
100 context_instance = RequestContext(request))
|
gremmie@1
|
101
|
gremmie@1
|
102
|
gremmie@1
|
103 @login_required
|
gremmie@1
|
104 def reply(request, msg_id):
|
gremmie@1
|
105 """
|
gremmie@1
|
106 Process or prepare the compose form in order to reply
|
gremmie@1
|
107 to a given message.
|
gremmie@1
|
108 """
|
gremmie@1
|
109 msg = get_object_or_404(Message, pk=msg_id)
|
gremmie@1
|
110
|
gremmie@1
|
111 if request.method == "POST":
|
gremmie@1
|
112 if request.POST.get('submit_button', 'Cancel') == 'Cancel':
|
gremmie@1
|
113 return box_redirect(request)
|
gremmie@1
|
114 compose_form = ComposeForm(request.user, request.POST)
|
gremmie@1
|
115 if compose_form.is_valid():
|
gremmie@1
|
116 compose_form.save(sender=request.user, parent_msg=msg)
|
bgneal@178
|
117 messages.success(request, 'Reply sent.')
|
gremmie@1
|
118 return box_redirect(request)
|
gremmie@1
|
119 else:
|
gremmie@1
|
120 if msg.receiver == request.user:
|
gremmie@1
|
121 receiver_name = msg.sender.username
|
gremmie@1
|
122 else:
|
gremmie@1
|
123 # replying to message in outbox
|
gremmie@1
|
124 receiver_name = msg.receiver.username
|
gremmie@1
|
125
|
gremmie@1
|
126 form_data = {
|
gremmie@1
|
127 'receiver': receiver_name,
|
gremmie@1
|
128 'subject': reply_subject(msg.subject),
|
gremmie@1
|
129 'message': quote_message(msg.sender, msg.send_date, msg.message),
|
gremmie@1
|
130 'box': request.GET.get('box', 'inbox'),
|
gremmie@1
|
131 }
|
gremmie@1
|
132
|
gremmie@1
|
133 compose_form = ComposeForm(request.user, initial=form_data)
|
gremmie@1
|
134
|
gremmie@1
|
135 return render_to_response('messages/compose.html', {
|
gremmie@1
|
136 'compose_form': compose_form,
|
bgneal@371
|
137 },
|
gremmie@1
|
138 context_instance = RequestContext(request))
|
gremmie@1
|
139
|
gremmie@1
|
140
|
gremmie@1
|
141 @login_required
|
gremmie@1
|
142 def compose(request, receiver=None):
|
gremmie@1
|
143 """
|
gremmie@1
|
144 Process or prepare the compose form in order to create
|
gremmie@1
|
145 a new message.
|
gremmie@1
|
146 """
|
gremmie@1
|
147 if request.method == "POST":
|
gremmie@1
|
148 if request.POST.get('submit_button', 'Cancel') == 'Cancel':
|
gremmie@1
|
149 return HttpResponseRedirect(reverse('messages-inbox'))
|
gremmie@1
|
150 compose_form = ComposeForm(request.user, request.POST)
|
gremmie@1
|
151 if compose_form.is_valid():
|
gremmie@1
|
152 compose_form.save(sender=request.user)
|
bgneal@178
|
153 messages.success(request, 'Message sent.')
|
gremmie@1
|
154 return HttpResponseRedirect(reverse('messages-inbox'))
|
gremmie@1
|
155 else:
|
gremmie@1
|
156 if receiver is not None:
|
gremmie@1
|
157 form_data = {
|
gremmie@1
|
158 'receiver': receiver,
|
gremmie@1
|
159 }
|
gremmie@1
|
160 compose_form = ComposeForm(request.user, initial=form_data)
|
gremmie@1
|
161 else:
|
gremmie@1
|
162 compose_form = ComposeForm(request.user)
|
gremmie@1
|
163
|
gremmie@1
|
164 return render_to_response('messages/compose.html', {
|
gremmie@1
|
165 'compose_form': compose_form,
|
bgneal@371
|
166 },
|
gremmie@1
|
167 context_instance = RequestContext(request))
|
gremmie@1
|
168
|
gremmie@1
|
169
|
bgneal@371
|
170 def _delete_message(user, msg):
|
bgneal@371
|
171 """
|
bgneal@371
|
172 Deletes a given message. The user must be either the sender or
|
bgneal@371
|
173 receiver for this to succeed.
|
bgneal@371
|
174 If both parties have deleted the message, it is deleted from the
|
bgneal@371
|
175 database. If only one party has deleted the message, the message
|
bgneal@371
|
176 is just sent to the trash.
|
bgneal@371
|
177
|
bgneal@371
|
178 Returns MSG_DELETED, MSG_TRASHED, or MSG_ERROR to indicate what
|
bgneal@371
|
179 action was performed.
|
bgneal@371
|
180
|
bgneal@371
|
181 """
|
bgneal@371
|
182 if msg.sender == user:
|
bgneal@371
|
183 if (msg.receiver_delete_date is not None or
|
bgneal@371
|
184 msg.read_date is None):
|
bgneal@371
|
185 # Both parties deleted the message or receiver hasn't read it yet,
|
bgneal@371
|
186 # we can delete it now
|
bgneal@371
|
187 msg.delete()
|
bgneal@371
|
188 return MSG_DELETED
|
bgneal@371
|
189 else:
|
bgneal@371
|
190 # receiver still has it in inbox
|
bgneal@371
|
191 msg.sender_delete_date = datetime.datetime.now()
|
bgneal@371
|
192 msg.save()
|
bgneal@371
|
193 return MSG_TRASHED
|
bgneal@371
|
194
|
bgneal@371
|
195 elif msg.receiver == user:
|
bgneal@371
|
196 if msg.sender_delete_date is not None:
|
bgneal@371
|
197 # both parties deleted the message, we can delete it now
|
bgneal@371
|
198 msg.delete()
|
bgneal@371
|
199 return MSG_DELETED
|
bgneal@371
|
200 else:
|
bgneal@371
|
201 # sender still has it in the outbox
|
bgneal@371
|
202 msg.receiver_delete_date = datetime.datetime.now()
|
bgneal@371
|
203 msg.save()
|
bgneal@371
|
204 return MSG_TRASHED
|
bgneal@371
|
205
|
bgneal@371
|
206 return MSG_ERROR
|
bgneal@371
|
207
|
bgneal@371
|
208
|
gremmie@1
|
209 @login_required
|
bgneal@156
|
210 @require_POST
|
gremmie@1
|
211 def delete(request, msg_id):
|
gremmie@1
|
212 """
|
gremmie@1
|
213 Deletes a given message. The user must be either the sender or
|
gremmie@1
|
214 receiver for this to succeed.
|
gremmie@1
|
215 """
|
gremmie@1
|
216 msg = get_object_or_404(Message, pk=msg_id)
|
bgneal@371
|
217 result = _delete_message(request.user, msg)
|
bgneal@371
|
218 if result == MSG_DELETED:
|
bgneal@371
|
219 messages.success(request, 'Message deleted.')
|
bgneal@371
|
220 elif result == MSG_TRASHED:
|
bgneal@371
|
221 messages.success(request, 'Message sent to trash.')
|
gremmie@1
|
222 else:
|
bgneal@371
|
223 messages.error(request, 'Error deleting message.')
|
gremmie@1
|
224
|
gremmie@1
|
225 return box_redirect(request)
|
gremmie@1
|
226
|
gremmie@1
|
227
|
gremmie@1
|
228 @login_required
|
gremmie@1
|
229 def delete_bulk(request):
|
gremmie@1
|
230 """
|
gremmie@1
|
231 Deletes messages in bulk. The message ID's to be deleted are expected
|
gremmie@1
|
232 to be in the delete POST array. The user must be either the sender
|
gremmie@1
|
233 or receiver for this to succeed.
|
gremmie@1
|
234 """
|
gremmie@1
|
235 if request.method == "POST":
|
gremmie@1
|
236 delete_ids = request.POST.getlist('delete_ids')
|
gremmie@1
|
237 try:
|
gremmie@1
|
238 delete_ids = [int(id) for id in delete_ids]
|
gremmie@1
|
239 except ValueError:
|
gremmie@1
|
240 raise Http404
|
bgneal@371
|
241
|
bgneal@371
|
242 msgs = Message.objects.filter(id__in=delete_ids)
|
bgneal@371
|
243
|
bgneal@371
|
244 counts = collections.defaultdict(int)
|
gremmie@1
|
245 for msg in msgs:
|
bgneal@371
|
246 result = _delete_message(request.user, msg)
|
bgneal@371
|
247 counts[result] += 1
|
bgneal@371
|
248
|
bgneal@371
|
249 if counts[MSG_DELETED]:
|
bgneal@371
|
250 messages.success(request, 'Messages deleted: %d' % counts[MSG_DELETED])
|
bgneal@371
|
251 if counts[MSG_TRASHED]:
|
bgneal@371
|
252 messages.success(request, 'Messages sent to trash: %d' % counts[MSG_TRASHED])
|
bgneal@371
|
253 if counts[MSG_ERROR]:
|
bgneal@371
|
254 messages.error(request, 'Message errors: %d' % counts[MSG_ERROR])
|
gremmie@1
|
255
|
gremmie@1
|
256 return box_redirect(request)
|
gremmie@1
|
257
|
gremmie@1
|
258
|
gremmie@1
|
259 @login_required
|
bgneal@156
|
260 @require_POST
|
gremmie@1
|
261 def undelete(request, msg_id):
|
gremmie@1
|
262 """
|
gremmie@1
|
263 Undeletes a given message. The user must be either the sender or
|
gremmie@1
|
264 receiver for this to succeed.
|
gremmie@1
|
265 """
|
gremmie@1
|
266 msg = get_object_or_404(Message, pk=msg_id)
|
gremmie@1
|
267 if msg.sender == request.user:
|
gremmie@1
|
268 msg.sender_delete_date = None
|
gremmie@1
|
269 elif msg.receiver == request.user:
|
gremmie@1
|
270 msg.receiver_delete_date = None
|
gremmie@1
|
271 else:
|
gremmie@1
|
272 raise Http404
|
gremmie@1
|
273 msg.save()
|
bgneal@178
|
274 messages.success(request, 'Message retrieved from the trash.')
|
gremmie@1
|
275
|
gremmie@1
|
276 return box_redirect(request)
|
gremmie@1
|
277
|
gremmie@1
|
278
|
gremmie@1
|
279 @login_required
|
gremmie@1
|
280 def undelete_bulk(request):
|
gremmie@1
|
281 """
|
gremmie@1
|
282 Undeletes messages in bulk. The message ID's to be deleted are expected
|
gremmie@1
|
283 to be in the delete POST array. The user must be either the sender
|
gremmie@1
|
284 or receiver for this to succeed.
|
gremmie@1
|
285 """
|
gremmie@1
|
286 if request.method == "POST":
|
gremmie@1
|
287 undelete_ids = request.POST.getlist('undelete_ids')
|
gremmie@1
|
288 try:
|
gremmie@1
|
289 undelete_ids = [int(id) for id in undelete_ids]
|
gremmie@1
|
290 except ValueError:
|
gremmie@1
|
291 raise Http404
|
gremmie@1
|
292 msgs = Message.objects.filter(id__in = undelete_ids)
|
gremmie@1
|
293 for msg in msgs:
|
gremmie@1
|
294 if msg.sender == request.user:
|
gremmie@1
|
295 msg.sender_delete_date = None
|
gremmie@1
|
296 msg.save()
|
gremmie@1
|
297 elif msg.receiver == request.user:
|
gremmie@1
|
298 msg.receiver_delete_date = None
|
gremmie@1
|
299 msg.save()
|
bgneal@178
|
300 messages.success(request, 'Messages retrieved from the trash.')
|
gremmie@1
|
301
|
gremmie@1
|
302 return box_redirect(request)
|
gremmie@1
|
303
|
gremmie@1
|
304
|
gremmie@1
|
305 @login_required
|
gremmie@1
|
306 def options(request):
|
gremmie@1
|
307 """
|
gremmie@1
|
308 View to display/change user options.
|
gremmie@1
|
309 """
|
gremmie@1
|
310 if request.method == "POST":
|
gremmie@1
|
311 if request.POST.get('submit_button', 'Cancel') == 'Cancel':
|
gremmie@1
|
312 return HttpResponseRedirect(reverse('messages-inbox'))
|
gremmie@1
|
313 options = Options.objects.for_user(request.user)
|
gremmie@1
|
314 form = OptionsForm(request.POST, instance=options)
|
gremmie@1
|
315 if form.is_valid():
|
gremmie@1
|
316 form.save()
|
bgneal@178
|
317 messages.success(request, 'Options saved.')
|
gremmie@1
|
318 return HttpResponseRedirect(reverse('messages-inbox'))
|
gremmie@1
|
319 else:
|
gremmie@1
|
320 try:
|
gremmie@1
|
321 options = Options.objects.for_user(request.user)
|
gremmie@1
|
322 except:
|
gremmie@1
|
323 options = Options()
|
gremmie@1
|
324 options.user = request.user
|
gremmie@1
|
325 options.save()
|
gremmie@1
|
326
|
gremmie@1
|
327 form = OptionsForm(instance=options)
|
gremmie@1
|
328
|
gremmie@1
|
329 return render_to_response('messages/options.html', {
|
gremmie@1
|
330 'form': form,
|
bgneal@371
|
331 },
|
gremmie@1
|
332 context_instance = RequestContext(request))
|
gremmie@1
|
333
|