]> git.openstreetmap.org Git - osqa.git/blob - forum/views/writers.py
Fix error when unconfirmed users ask questions
[osqa.git] / forum / views / writers.py
1 # encoding:utf-8
2 import os.path
3
4 import datetime
5
6 from django.core.urlresolvers import reverse
7 from django.core.files.storage import FileSystemStorage
8 from django.views.decorators.csrf import csrf_exempt
9 from django.shortcuts import render_to_response, get_object_or_404
10 from django.template import RequestContext
11 from django.http import HttpResponseRedirect, HttpResponse, Http404
12 from django.utils.html import *
13 from django.utils.translation import ugettext as _
14
15 from django.contrib import messages
16
17 from forum import settings as django_settings
18 from forum.actions import AskAction, AnswerAction, ReviseAction, RollbackAction, RetagAction, AnswerToQuestionAction, CommentToQuestionAction
19 from forum.forms import *
20 from forum.models import *
21 from forum.utils import html
22 from forum.http_responses import HttpResponseUnauthorized
23
24 from vars import PENDING_SUBMISSION_SESSION_ATTR
25
26 @csrf_exempt
27 def upload(request):#ajax upload file to a question or answer
28     class FileTypeNotAllow(Exception):
29         pass
30     class FileSizeNotAllow(Exception):
31         pass
32     class UploadPermissionNotAuthorized(Exception):
33         pass
34
35     xml_template = "<result><msg><![CDATA[%s]]></msg><error><![CDATA[%s]]></error><file_url>%s</file_url></result>"
36
37     try:
38         f = request.FILES['file-upload']
39         # check upload permission
40         if not request.user.can_upload_files():
41             raise UploadPermissionNotAuthorized()
42
43         # check file type
44         try:
45             file_name_suffix = os.path.splitext(f.name)[1].lower()
46         except KeyError:
47             raise FileTypeNotAllow()
48
49         if not file_name_suffix in ('.jpg', '.jpeg', '.gif', '.png', '.bmp', '.tiff', '.ico'):
50             raise FileTypeNotAllow()
51
52         storage = FileSystemStorage(str(settings.UPFILES_FOLDER), str(settings.UPFILES_ALIAS))
53         new_file_name = storage.save("_".join(f.name.split()), f)
54         # check file size
55         # byte
56         size = storage.size(new_file_name)
57
58         if size > float(settings.ALLOW_MAX_FILE_SIZE) * 1024 * 1024:
59             storage.delete(new_file_name)
60             raise FileSizeNotAllow()
61
62         result = xml_template % ('Good', '', str(settings.UPFILES_ALIAS) + new_file_name)
63     except UploadPermissionNotAuthorized:
64         result = xml_template % ('', _('uploading images is limited to users with >60 reputation points'), '')
65     except FileTypeNotAllow:
66         result = xml_template % ('', _("allowed file types are 'jpg', 'jpeg', 'gif', 'bmp', 'png', 'tiff'"), '')
67     except FileSizeNotAllow:
68         result = xml_template % ('', _("maximum upload file size is %sM") % settings.ALLOW_MAX_FILE_SIZE, '')
69     except Exception, e:
70         result = xml_template % ('', _('Error uploading file. Please contact the site administrator. Thank you. %s' % e), '')
71
72     return HttpResponse(result, content_type="application/xml")
73
74 def ask(request):
75     form = None
76
77     if request.POST:
78         if request.session.pop('reviewing_pending_data', False):
79             form = AskForm(initial=request.POST, user=request.user)
80         elif "text" in request.POST:
81             form = AskForm(request.POST, user=request.user)
82             if form.is_valid():
83                 if request.user.is_authenticated() and request.user.email_valid_and_can_ask():
84                     ask_action = AskAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=form.cleaned_data)
85                     question = ask_action.node
86
87                     if settings.WIKI_ON and request.POST.get('wiki', False):
88                         question.nstate.wiki = ask_action
89
90                     return HttpResponseRedirect(question.get_absolute_url())
91                 else:
92                     request.session[PENDING_SUBMISSION_SESSION_ATTR] = {
93                         'POST': request.POST,
94                         'data_name': _("question"),
95                         'type': 'ask',
96                         'submission_url': reverse('ask'),
97                         'time': datetime.datetime.now()
98                     }
99
100                     if request.user.is_authenticated():
101                         messages.info(request, _("Your question is pending until you %s.") % html.hyperlink(
102                             django_settings.APP_URL + reverse('send_validation_email', prefix='/'), _("validate your email")
103                         ))
104                         return HttpResponseRedirect(reverse('index'))
105                     else:
106                         return HttpResponseRedirect(reverse('auth_signin'))
107         elif "go" in request.POST:
108             form = AskForm({'title': request.POST['q']}, user=request.user)
109             
110     if not form:
111         form = AskForm(user=request.user)
112
113     return render_to_response('ask.html', {
114         'form' : form,
115         'tab' : 'ask'
116         }, context_instance=RequestContext(request))
117
118 def convert_to_question(request, id):
119     user = request.user
120
121     node_type = request.GET.get('node_type', 'answer')
122     if node_type == 'comment':
123         node = get_object_or_404(Comment, id=id)
124         action_class = CommentToQuestionAction
125     else:
126         node = get_object_or_404(Answer, id=id)
127         action_class = AnswerToQuestionAction
128
129     if not user.can_convert_to_question(node):
130         return HttpResponseUnauthorized(request)
131
132     return _edit_question(request, node, template='node/convert_to_question.html', summary=_("Converted to question"),
133                            action_class =action_class, allow_rollback=False, url_getter=lambda a: Question.objects.get(id=a.id).get_absolute_url())
134
135 def edit_question(request, id):
136     question = get_object_or_404(Question, id=id)
137     if question.nis.deleted and not request.user.can_view_deleted_post(question):
138         raise Http404
139     if request.user.can_edit_post(question):
140         return _edit_question(request, question)
141     elif request.user.can_retag_questions():
142         return _retag_question(request, question)
143     else:
144         raise Http404
145
146 def _retag_question(request, question):
147     if request.method == 'POST':
148         form = RetagQuestionForm(question, request.POST)
149         if form.is_valid():
150             if form.has_changed():
151                 RetagAction(user=request.user, node=question, ip=request.META['REMOTE_ADDR']).save(data=dict(tagnames=form.cleaned_data['tags']))
152
153             return HttpResponseRedirect(question.get_absolute_url())
154     else:
155         form = RetagQuestionForm(question)
156     return render_to_response('question_retag.html', {
157         'question': question,
158         'form' : form,
159         #'tags' : _get_tags_cache_json(),
160     }, context_instance=RequestContext(request))
161
162 def _edit_question(request, question, template='question_edit.html', summary='', action_class=ReviseAction,
163                    allow_rollback=True, url_getter=lambda q: q.get_absolute_url(), additional_context=None):
164     if request.method == 'POST':
165         revision_form = RevisionForm(question, data=request.POST)
166         revision_form.is_valid()
167         revision = question.revisions.get(revision=revision_form.cleaned_data['revision'])
168
169         if 'select_revision' in request.POST:
170             form = EditQuestionForm(question, request.user, revision)
171         else:
172             form = EditQuestionForm(question, request.user, revision, data=request.POST)
173
174         if not 'select_revision' in request.POST and form.is_valid():
175             if form.has_changed():
176                 action = action_class(user=request.user, node=question, ip=request.META['REMOTE_ADDR']).save(data=form.cleaned_data)
177
178                 if settings.WIKI_ON:
179                     if request.POST.get('wiki', False) and not question.nis.wiki:
180                         question.nstate.wiki = action
181                     elif question.nis.wiki and (not request.POST.get('wiki', False)) and request.user.can_cancel_wiki(question):
182                         question.nstate.wiki = None
183             else:
184                 if not revision == question.active_revision:
185                     if allow_rollback:
186                         RollbackAction(user=request.user, node=question).save(data=dict(activate=revision))
187                     else:
188                         pass
189
190             return HttpResponseRedirect(url_getter(question))
191     else:
192         revision_form = RevisionForm(question)
193         form = EditQuestionForm(question, request.user, initial={'summary': summary})
194
195     context = {
196         'question': question,
197         'revision_form': revision_form,
198         'form' : form,
199     }
200
201     if not (additional_context is None):
202         context.update(additional_context)
203
204     return render_to_response(template, context, context_instance=RequestContext(request))
205
206
207 def edit_answer(request, id):
208     answer = get_object_or_404(Answer, id=id)
209     if answer.deleted and not request.user.can_view_deleted_post(answer):
210         raise Http404
211     elif not request.user.can_edit_post(answer):
212         raise Http404
213
214     if request.method == "POST":
215         revision_form = RevisionForm(answer, data=request.POST)
216         revision_form.is_valid()
217         revision = answer.revisions.get(revision=revision_form.cleaned_data['revision'])
218
219         if 'select_revision' in request.POST:
220             form = EditAnswerForm(answer, request.user, revision)
221         else:
222             form = EditAnswerForm(answer, request.user, revision, data=request.POST)
223
224         if not 'select_revision' in request.POST and form.is_valid():
225             if form.has_changed():
226                 action = ReviseAction(user=request.user, node=answer, ip=request.META['REMOTE_ADDR']).save(data=form.cleaned_data)
227
228                 if settings.WIKI_ON:
229                     if request.POST.get('wiki', False) and not answer.nis.wiki:
230                         answer.nstate.wiki = action
231                     elif answer.nis.wiki and (not request.POST.get('wiki', False)) and request.user.can_cancel_wiki(answer):
232                         answer.nstate.wiki = None
233             else:
234                 if not revision == answer.active_revision:
235                     RollbackAction(user=request.user, node=answer, ip=request.META['REMOTE_ADDR']).save(data=dict(activate=revision))
236
237             return HttpResponseRedirect(answer.get_absolute_url())
238
239     else:
240         revision_form = RevisionForm(answer)
241         form = EditAnswerForm(answer, request.user)
242     return render_to_response('answer_edit.html', {
243                               'answer': answer,
244                               'revision_form': revision_form,
245                               'form': form,
246                               }, context_instance=RequestContext(request))
247
248 def answer(request, id):
249     question = get_object_or_404(Question, id=id)
250
251     if request.POST:
252         form = AnswerForm(request.POST, request.user)
253
254         if request.session.pop('reviewing_pending_data', False) or not form.is_valid():
255             request.session['redirect_POST_data'] = request.POST
256             return HttpResponseRedirect(question.get_absolute_url() + '#fmanswer')
257
258         if request.user.is_authenticated() and request.user.email_valid_and_can_answer():
259             answer_action = AnswerAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(dict(question=question, **form.cleaned_data))
260             answer = answer_action.node
261
262             if settings.WIKI_ON and request.POST.get('wiki', False):
263                 answer.nstate.wiki = answer_action
264
265             return HttpResponseRedirect(answer.get_absolute_url())
266         else:
267             request.session[PENDING_SUBMISSION_SESSION_ATTR] = {
268                 'POST': request.POST,
269                 'data_name': _("answer"),
270                 'type': 'answer',
271                 'submission_url': reverse('answer', kwargs={'id': id}),
272                 'time': datetime.datetime.now()
273             }
274
275             if request.user.is_authenticated():
276                 messages.info(request, _("Your answer is pending until you %s.") % html.hyperlink(
277                     django_settings.APP_URL + reverse('send_validation_email', prefix='/'), _("validate your email")
278                 ))
279                 return HttpResponseRedirect(question.get_absolute_url())
280             else:
281                 return HttpResponseRedirect(reverse('auth_signin'))
282
283     return HttpResponseRedirect(question.get_absolute_url())
284
285
286 def manage_pending_data(request, action, forward=None):
287     pending_data = request.session.pop(PENDING_SUBMISSION_SESSION_ATTR, None)
288
289     if not pending_data:
290         raise Http404
291
292     if action == _("cancel"):
293         return HttpResponseRedirect(forward or request.META.get('HTTP_REFERER', '/'))
294     else:
295         if action == _("review"):
296             request.session['reviewing_pending_data'] = True
297
298         request.session['redirect_POST_data'] = pending_data['POST']
299         return HttpResponseRedirect(pending_data['submission_url'])
300
301