comparison gpp/messages/views2.py @ 425:76ba9478ebbd

Initial beta-test commit of a revamped, jquery ui tab-based PM system. This is for #211.
author Brian Neal <bgneal@gmail.com>
date Tue, 26 Apr 2011 00:16:35 +0000
parents
children 77b3b01843b5
comparison
equal deleted inserted replaced
424:8df6e9edac22 425:76ba9478ebbd
1 """
2 Views for the messages application.
3
4 """
5 import datetime
6
7 from django.contrib.auth.decorators import login_required
8 from django.contrib import messages
9 from django.core.paginator import Paginator, EmptyPage, InvalidPage
10 from django.core.urlresolvers import reverse
11 from django.http import HttpResponse
12 from django.http import HttpResponseForbidden
13 from django.http import HttpResponseNotAllowed
14 from django.http import HttpResponseRedirect
15 from django.shortcuts import get_object_or_404
16 from django.shortcuts import render
17 import django.utils.simplejson as json
18
19 from messages.models import Message, Options
20 from messages.forms import OptionsForm, ComposeForm
21 from messages.utils import reply_subject, quote_message
22
23
24 MSGS_PER_PAGE = 20
25
26 TAB_INDICES = {
27 'inbox': 0,
28 'compose': 1,
29 'outbox': 2,
30 'trash': 3,
31 'options': 4,
32 }
33
34
35 def _get_page(request):
36 try:
37 n = int(request.GET.get('page', '1'))
38 except ValueError:
39 n = 1
40 return n
41
42
43 @login_required
44 def index(request, tab=None):
45 """
46 This function displays the base tabbed private messages view.
47
48 """
49 tab_index = TAB_INDICES[tab] if tab else 0
50 return render(request, 'messages/tabbed_base.html', {
51 'tab': tab_index,
52 })
53
54
55 def inbox(request):
56 """
57 Returns the inbox for the user.
58
59 """
60 if not request.user.is_authenticated():
61 return HttpResponseForbidden()
62
63 msg_list = Message.objects.inbox(request.user)
64 paginator = Paginator(msg_list, MSGS_PER_PAGE)
65 try:
66 msgs = paginator.page(_get_page(request))
67 except EmptyPage, InvalidPage:
68 msgs = paginator.page(paginator.num_pages)
69
70 return render(request, 'messages/inbox_tab.html', {
71 'msgs': msgs,
72 'url': reverse('messages-beta_inbox'),
73 })
74
75
76 def outbox(request):
77 """
78 Returns the outbox for the user.
79
80 """
81 if not request.user.is_authenticated():
82 return HttpResponseForbidden()
83
84 msg_list = Message.objects.outbox(request.user)
85 paginator = Paginator(msg_list, MSGS_PER_PAGE)
86 try:
87 msgs = paginator.page(_get_page(request))
88 except EmptyPage, InvalidPage:
89 msgs = paginator.page(paginator.num_pages)
90
91 return render(request, 'messages/outbox_tab.html', {
92 'msgs': msgs,
93 'url': reverse('messages-beta_outbox'),
94 })
95
96
97 def trash(request):
98 """
99 Returns the trash for the user.
100
101 """
102 if not request.user.is_authenticated():
103 return HttpResponseForbidden()
104
105 msg_list = Message.objects.trash(request.user)
106 paginator = Paginator(msg_list, MSGS_PER_PAGE)
107 try:
108 msgs = paginator.page(_get_page(request))
109 except EmptyPage, InvalidPage:
110 msgs = paginator.page(paginator.num_pages)
111
112 return render(request, 'messages/trash_tab.html', {
113 'msgs': msgs,
114 'url': reverse('messages-beta_trash'),
115 })
116
117
118 def message(request):
119 """
120 This view function retrieves a message and returns it as a JSON object.
121
122 """
123 if not request.user.is_authenticated():
124 return HttpResponseForbidden()
125 if request.method != 'POST':
126 return HttpResponseNotAllowed(['POST'])
127
128 msg_id = request.POST.get('msg_id')
129 msg = get_object_or_404(Message.objects.select_related(), pk=msg_id)
130 if msg.sender != request.user and msg.receiver != request.user:
131 return HttpResponseForbidden()
132
133 if msg.receiver == request.user and msg.read_date is None:
134 msg.read_date = datetime.datetime.now()
135 msg.save()
136
137 msg_dict = dict(subject=msg.subject,
138 sender=msg.sender.username,
139 receiver=msg.receiver.username,
140 content=msg.html,
141 re_subject=reply_subject(msg.subject),
142 re_content=quote_message(msg.sender.username, msg.send_date,
143 msg.message))
144
145 result = json.dumps(msg_dict, ensure_ascii=False)
146 return HttpResponse(result, content_type='application/json')
147
148
149 def options(request):
150 """
151 This view handles the displaying and changing of private message options.
152
153 """
154 if not request.user.is_authenticated():
155 return HttpResponseForbidden()
156
157 if request.method == "POST":
158 options = Options.objects.for_user(request.user)
159 form = OptionsForm(request.POST, instance=options, prefix='opts')
160 if form.is_valid():
161 form.save()
162 messages.success(request, 'Options saved.')
163 else:
164 options = Options.objects.for_user(request.user)
165 form = OptionsForm(instance=options, prefix='opts')
166
167 return render(request, 'messages/options_tab.html', {
168 'form': form,
169 })
170
171
172 def compose(request, receiver=None):
173 """
174 Process or prepare the compose form to create a new private message.
175
176 """
177 if not request.user.is_authenticated():
178 return HttpResponseForbidden()
179
180 if request.method == "POST":
181 compose_form = ComposeForm(request.user, request.POST)
182 if compose_form.is_valid():
183 compose_form.save(sender=request.user)
184 messages.success(request, 'Message sent.')
185 return HttpResponseRedirect(reverse('messages-beta_index_named', args=['compose']))
186 else:
187 if receiver is not None:
188 form_data = {'receiver': receiver}
189 compose_form = ComposeForm(request.user, initial=form_data)
190 else:
191 compose_form = ComposeForm(request.user)
192
193 return render(request, 'messages/compose_tab.html', {
194 'compose_form': compose_form,
195 })
196
197
198 def _only_integers(slist):
199 """
200 Accepts a list of strings. Returns a list of integers consisting of only
201 those elements from the original list that could be converted to integers
202
203 """
204 result = []
205 for s in slist:
206 try:
207 n = int(s)
208 except ValueError:
209 pass
210 else:
211 result.append(n)
212 return result
213
214
215 def _delete_msgs(user, msg_ids):
216 """
217 Deletes the messages given by the list of msg_ids. For this to succeed, the
218 user has to be either the sender or receiver on each message.
219
220 """
221 msg_ids = _only_integers(msg_ids)
222 msgs = Message.objects.filter(id__in=msg_ids)
223
224 for msg in msgs:
225 if msg.sender == user:
226 if (msg.receiver_delete_date is not None or
227 msg.read_date is None):
228 # Both parties deleted the message or receiver hasn't read it
229 # yet, we can delete it now
230 msg.delete()
231 else:
232 # receiver still has it in inbox
233 msg.sender_delete_date = datetime.datetime.now()
234 msg.save()
235
236 elif msg.receiver == user:
237 if msg.sender_delete_date is not None:
238 # both parties deleted the message, we can delete it now
239 msg.delete()
240 else:
241 # sender still has it in the outbox
242 msg.receiver_delete_date = datetime.datetime.now()
243 msg.save()
244
245
246 def _undelete_msgs(user, msg_ids):
247 """
248 Attempts to "undelete" the messages given by the msg_ids list.
249 This will only succeed if the user is either the sender or receiver.
250
251 """
252 msg_ids = _only_integers(msg_ids)
253 msgs = Message.objects.filter(id__in=msg_ids)
254 for msg in msgs:
255 if msg.sender == user:
256 msg.sender_delete_date = None
257 msg.save()
258 elif msg.receiver == user:
259 msg.receiver_delete_date = None
260 msg.save()
261
262
263 def bulk(request):
264 """
265 This view processes messages in bulk. Arrays of message ids are expected in
266 the POST query dict: inbox_ids and outbox_ids will be deleted; trash_ids will
267 be undeleted.
268
269 """
270 if not request.user.is_authenticated():
271 return HttpResponseForbidden()
272 if request.method != 'POST':
273 return HttpResponseNotAllowed(['POST'])
274
275 delete_ids = []
276 if 'inbox_ids' in request.POST:
277 delete_ids.extend(request.POST.getlist('inbox_ids'))
278 if 'outbox_ids' in request.POST:
279 delete_ids.extend(request.POST.getlist('outbox_ids'))
280
281 if len(delete_ids):
282 _delete_msgs(request.user, delete_ids)
283
284 if 'trash_ids' in request.POST:
285 _undelete_msgs(request.user, request.POST.getlist('trash_ids'))
286
287 return HttpResponse('');