def reopen(request, id):#re-open question """view to initiate and process question close this is not an ajax view """ question = get_object_or_404(models.Question, id=id) # open question try: if request.method == 'POST' : request.user.reopen_question(question) return HttpResponseRedirect(question.get_absolute_url()) else: request.user.assert_can_reopen_question(question) closed_by_profile_url = question.closed_by.get_profile_url() closed_by_username = question.closed_by.username data = { 'question' : question, 'closed_by_profile_url': closed_by_profile_url, 'closed_by_username': closed_by_username, } context = RequestContext(request, data) template = ENV.get_template('reopen.html') return HttpResponse(template.render(context)) except exceptions.PermissionDenied, e: request.user.message_set.create(message = unicode(e)) return HttpResponseRedirect(question.get_absolute_url())
def close(request, id):#close question """view to initiate and process question close """ question = get_object_or_404(models.Question, id=id) try: if request.method == 'POST': form = CloseForm(request.POST) if form.is_valid(): reason = form.cleaned_data['reason'] request.user.close_question( question = question, reason = reason ) return HttpResponseRedirect(question.get_absolute_url()) else: request.user.assert_can_close_question(question) form = CloseForm() template = ENV.get_template('close.html') data = {'form': form, 'question': question} context = RequestContext(request, data) return HttpResponse(template.render(context)) except exceptions.PermissionDenied, e: request.user.message_set.create(message = unicode(e)) return HttpResponseRedirect(question.get_absolute_url())
def send_email_key(request): """ url = /email/sendkey/ view that is shown right after sending email key email sending is called internally raises 404 if email validation is off if current email is valid shows 'key_not_sent' view of authopenid/changeemail.html template """ if askbot_settings.EMAIL_VALIDATION == True: if request.user.email_isvalid: template = ENV.get_template('authopenid/changeemail.html') data = { 'email': request.user.email, 'action_type': 'key_not_sent', 'change_link': reverse('user_changeemail') } context = RequestContext(request, data) return HttpResponse(template.render(context)) else: send_new_email_key(request.user) return validation_email_sent(request) else: raise Http404
def user_favorites(request, user): favorited_q_id_list= models.FavoriteQuestion.objects.filter( user = user ).values_list('question__id', flat=True) questions = models.Question.objects.filter( id__in=favorited_q_id_list ).order_by( '-score', '-last_activity_at' ).select_related( 'last_activity_by__id', 'last_activity_by__username', 'last_activity_by__reputation', 'last_activity_by__gold', 'last_activity_by__silver', 'last_activity_by__bronze' )[:const.USER_VIEW_DATA_SIZE] data = { 'active_tab':'users', 'tab_name' : 'favorites', 'tab_description' : _('users favorite questions'), 'page_title' : _('profile - favorite questions'), 'questions' : questions, 'favorited_myself': favorited_q_id_list, 'view_user' : user } context = RequestContext(request, data) template = ENV.get_template('user_profile/user_favorites.html') return HttpResponse(template.render(context))
def send_email_key(request): """ url = /email/sendkey/ view that is shown right after sending email key email sending is called internally raises 404 if email validation is off if current email is valid shows 'key_not_sent' view of authopenid/changeemail.html template """ if askbot_settings.EMAIL_VALIDATION == True: if request.user.email_isvalid: template = ENV.get_template("authopenid/changeemail.html") data = { "email": request.user.email, "action_type": "key_not_sent", "change_link": reverse("user_changeemail"), } context = RequestContext(request, data) return HttpResponse(template.render(context)) else: send_new_email_key(request.user) return validation_email_sent(request) else: raise Http404
def validation_email_sent(request): """this function is called only if EMAIL_VALIDATION setting is set to True bolean value, basically dead now""" assert askbot_settings.EMAIL_VALIDATION == True logging.debug("") template = ENV.get_template("authopenid/changeemail.html") data = {"email": request.user.email, "change_email_url": reverse("user_changeemail"), "action_type": "validate"} context = RequestContext(request, data) return HttpResponse(template.render(context))
def edit_answer(request, id): answer = get_object_or_404(models.Answer, id=id) try: request.user.assert_can_edit_answer(answer) latest_revision = answer.get_latest_revision() if request.method == "POST": if 'select_revision' in request.POST: # user has changed revistion number revision_form = forms.RevisionForm( answer, latest_revision, request.POST ) if revision_form.is_valid(): # Replace with those from the selected revision rev = revision_form.cleaned_data['revision'] selected_revision = models.AnswerRevision.objects.get( answer = answer, revision = rev ) form = forms.EditAnswerForm(answer, selected_revision) else: form = forms.EditAnswerForm( answer, latest_revision, request.POST ) else: form = forms.EditAnswerForm(answer, latest_revision, request.POST) if form.is_valid(): if form.has_changed(): request.user.edit_answer( answer = answer, body_text = form.cleaned_data['text'], revision_comment = form.cleaned_data['summary'], wiki = form.cleaned_data.get('wiki', answer.wiki), #todo: add wiki field to form ) return HttpResponseRedirect(answer.get_absolute_url()) else: revision_form = forms.RevisionForm(answer, latest_revision) form = forms.EditAnswerForm(answer, latest_revision) template = ENV.get_template('answer_edit.html') data = { 'active_tab': 'questions', 'answer': answer, 'revision_form': revision_form, 'form': form, } context = RequestContext(request, data) return HttpResponse(template.render(context)) except exceptions.PermissionDenied, e: request.user.message_set.create(message = unicode(e)) return HttpResponseRedirect(answer.get_absolute_url())
def faq(request): template = ENV.get_template('faq.html') data = { 'view_name':'faq', 'gravatar_faq_url': reverse('faq') + '#gravatar', #'send_email_key_url': reverse('send_email_key'), 'ask_question_url': reverse('ask'), 'page_class': 'meta', } context = RequestContext(request, data) return HttpResponse(template.render(context))
def validation_email_sent(request): """this function is called only if EMAIL_VALIDATION setting is set to True bolean value, basically dead now""" assert (askbot_settings.EMAIL_VALIDATION == True) logging.debug('') template = ENV.get_template('authopenid/changeemail.html') data = { 'email': request.user.email, 'change_email_url': reverse('user_changeemail'), 'action_type': 'validate' } context = RequestContext(request, data) return HttpResponse(template.render(context))
def _send_email_key(user): """private function. sends email containing validation key to user's email address """ subject = _("Recover your %(site)s account") % {"site": askbot_settings.APP_SHORT_NAME} message_template = ENV.get_template("authopenid/email_validation.txt") import settings message_context = Context( {"validation_link": askbot_settings.APP_URL + reverse("user_account_recover", kwargs={"key": user.email_key})} ) message = message_template.render(message_context) send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [user.email])
def validation_email_sent(request): """this function is called only if EMAIL_VALIDATION setting is set to True bolean value, basically dead now""" assert(askbot_settings.EMAIL_VALIDATION == True) logging.debug('') template = ENV.get_template('authopenid/changeemail.html') data = { 'email': request.user.email, 'change_email_url': reverse('user_changeemail'), 'action_type': 'validate' } context = RequestContext(request, data) return HttpResponse(template.render(context))
def edit_question(request, id): """edit question view """ question = get_object_or_404(models.Question, id = id) latest_revision = question.get_latest_revision() revision_form = None try: request.user.assert_can_edit_question(question) if request.method == 'POST': if 'select_revision' in request.POST:#revert-type edit # user has changed revistion number revision_form = forms.RevisionForm(question, latest_revision, request.POST) if revision_form.is_valid(): # Replace with those from the selected revision form = forms.EditQuestionForm(question, models.QuestionRevision.objects.get(question=question, revision=revision_form.cleaned_data['revision'])) else: form = forms.EditQuestionForm(question, latest_revision, request.POST) else:#new content edit # Always check modifications against the latest revision form = forms.EditQuestionForm(question, latest_revision, request.POST) if form.is_valid(): if form.has_changed(): request.user.edit_question( question = question, title = form.cleaned_data['title'], body_text = form.cleaned_data['text'], revision_comment = form.cleaned_data['summary'], tags = form.cleaned_data['tags'], wiki = form.cleaned_data.get('wiki', question.wiki) ) return HttpResponseRedirect(question.get_absolute_url()) else: revision_form = forms.RevisionForm(question, latest_revision) form = forms.EditQuestionForm(question, latest_revision) data = { 'active_tab': 'questions', 'question': question, 'revision_form': revision_form, 'form' : form, 'tags' : _get_tags_cache_json() } context = RequestContext(request, data) template = ENV.get_template('question_edit.html') return HttpResponse(template.render(context)) except exceptions.PermissionDenied, e: request.user.message_set.create(message = unicode(e)) return HttpResponseRedirect(question.get_absolute_url())
def retag_question(request, id): """retag question view """ question = get_object_or_404(models.Question, id = id) try: request.user.assert_can_retag_question(question) if request.method == 'POST': form = forms.RetagQuestionForm(question, request.POST) if form.is_valid(): if form.has_changed(): request.user.retag_question( question = question, tags = form.cleaned_data['tags'] ) if request.is_ajax(): response_data = {'success': True} data = simplejson.dumps(response_data) return HttpResponse(data, mimetype="application/json") else: return HttpResponseRedirect(question.get_absolute_url()) elif request.is_ajax(): response_data = { 'message': unicode(form.errors['tags']), 'success': False } data = simplejson.dumps(response_data) return HttpResponse(data, mimetype="application/json") else: form = forms.RetagQuestionForm(question) data = { 'active_tab': 'questions', 'question': question, 'form' : form, 'tags' : _get_tags_cache_json(), } context = RequestContext(request, data) template = ENV.get_template('question_retag.html') return HttpResponse(template.render(context)) except exceptions.PermissionDenied, e: if request.is_ajax(): response_data = { 'message': unicode(e), 'success': False } data = simplejson.dumps(response_data) return HttpResponse(data, mimetype="application/json") else: request.user.message_set.create(message = unicode(e)) return HttpResponseRedirect(question.get_absolute_url())
def _send_email_key(user): """private function. sends email containing validation key to user's email address """ subject = _("Email verification subject line") message_template = ENV.get_template('authopenid/email_validation.txt') import settings message_context = Context({ 'validation_link': askbot_settings.APP_URL + reverse( 'user_account_recover', kwargs={'key':user.email_key} ) }) message = message_template.render(message_context) send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [user.email])
def process_exception(self, request, exception): #todo: move this to separate middleware exc_type, exc_value, exc_traceback = sys.exc_info() logging.critical(''.join(traceback.format_tb(exc_traceback))) logging.critical(exc_type) logging.critical(exc_value) if exc_type == Http404: return None if getattr(settings, 'DEBUG', False) == True: return None else: #todo - we have a strange requirement - maybe remove #500.html needs RequestContext, while handler500 only receives Context from askbot.skins.loaders import ENV template = ENV.get_template('500.jinja.html') return HttpResponse(template.render(RequestContext(request)))
def logout(request):#refactor/change behavior? #currently you click logout and you get #to this view which actually asks you again - do you really want to log out? #I guess rationale was to tell the user that s/he may be still logged in #through their external login sytem and we'd want to remind them about it #however it might be a little annoying #why not just show a message: you are logged out of forum, but #if you really want to log out -> go to your openid provider data = { 'view_name':'logout', 'next' : get_next_url(request), 'page_class': 'meta', } context = RequestContext(request, data) template = ENV.get_template('logout.html') return HttpResponse(template.render(context))
def _send_email_key(user): """private function. sends email containing validation key to user's email address """ subject = _("Recover your %(site)s account") % { 'site': askbot_settings.APP_SHORT_NAME } message_template = ENV.get_template('authopenid/email_validation.txt') import settings message_context = Context({ 'validation_link': askbot_settings.APP_URL + reverse('user_account_recover', kwargs={'key': user.email_key}) }) message = message_template.render(message_context) send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [user.email])
def tags(request):#view showing a listing of available tags - plain list stag = "" is_paginated = True sortby = request.GET.get('sort', 'used') try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 if request.method == "GET": stag = request.GET.get("q", "").strip() if stag != '': objects_list = Paginator(models.Tag.objects.filter(deleted=False).exclude(used_count=0).extra(where=['name like %s'], params=['%' + stag + '%']), DEFAULT_PAGE_SIZE) else: if sortby == "name": objects_list = Paginator(models.Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("name"), DEFAULT_PAGE_SIZE) else: objects_list = Paginator(models.Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-used_count"), DEFAULT_PAGE_SIZE) try: tags = objects_list.page(page) except (EmptyPage, InvalidPage): tags = objects_list.page(objects_list.num_pages) paginator_data = { 'is_paginated' : is_paginated, 'pages': objects_list.num_pages, 'page': page, 'has_previous': tags.has_previous(), 'has_next': tags.has_next(), 'previous': tags.previous_page_number(), 'next': tags.next_page_number(), 'base_url' : reverse('tags') + '?sort=%s&' % sortby } paginator_context = extra_tags.cnprog_paginator(paginator_data) data = { 'view_name':'tags', 'active_tab': 'tags', 'tags' : tags, 'stag' : stag, 'tab_id' : sortby, 'keywords' : stag, 'paginator_context' : paginator_context } context = RequestContext(request, data) template = ENV.get_template('tags.html') return HttpResponse(template.render(context))
def process_exception(self, request, exception): #todo: move this to separate middleware exc_type, exc_value, exc_traceback = sys.exc_info() logging.critical(''.join(traceback.format_tb(exc_traceback))) logging.critical(exc_type) logging.critical(exc_value) if exc_type == Http404: return None if getattr(settings, 'DEBUG', False) == True: return None else: #todo - we have a strange requirement - maybe remove #500.html needs RequestContext, while handler500 only receives Context #need to log some more details about the request logging.critical(utils.http.get_request_info(request)) from askbot.skins.loaders import ENV template = ENV.get_template('500.jinja.html') return HttpResponse(template.render(RequestContext(request)))
def verifyemail(request, id=None, key=None): """ view that is shown when user clicks email validation link url = /email/verify/{{user.id}}/{{user.email_key}}/ """ logging.debug("") if askbot_settings.EMAIL_VALIDATION == True: user = User.objects.get(id=id) if user: if user.email_key == key: user.email_isvalid = True clear_email_validation_message(user) user.save() template = ENV.get_template("authopenid/changeemail.html") data = {"action_type": "validation_complete"} context = RequestContext(request, data) return HttpResponse(template.render(context)) else: logging.error("hmm, no user found for email validation message - foul play?") raise Http404
def edit_user(request, id): """View that allows to edit user profile. This view is accessible to profile owners or site administrators """ user = get_object_or_404(models.User, id=id) if not(request.user == user or request.user.is_superuser): raise Http404 if request.method == "POST": form = forms.EditUserForm(user, request.POST) if form.is_valid(): new_email = sanitize_html(form.cleaned_data['email']) set_new_email(user, new_email) if askbot_settings.EDITABLE_SCREEN_NAME: user.username = sanitize_html(form.cleaned_data['username']) user.real_name = sanitize_html(form.cleaned_data['realname']) user.website = sanitize_html(form.cleaned_data['website']) user.location = sanitize_html(form.cleaned_data['city']) user.date_of_birth = form.cleaned_data.get('birthday', None) user.about = sanitize_html(form.cleaned_data['about']) user.save() # send user updated signal if full fields have been updated award_badges_signal.send(None, event = 'update_user_profile', actor = user, context_object = user ) return HttpResponseRedirect(user.get_profile_url()) else: form = forms.EditUserForm(user) data = { 'active_tab': 'users', 'form' : form, 'gravatar_faq_url' : reverse('faq') + '#gravatar', } context = RequestContext(request, data) template = ENV.get_template('user_profile/user_edit.html') return HttpResponse(template.render(context))
def revisions(request, id, object_name=None): assert(object_name in ('Question', 'Answer')) post = get_object_or_404(models.get_model(object_name), id=id) revisions = list(post.revisions.all()) revisions.reverse() for i, revision in enumerate(revisions): revision.html = revision.as_html() if i == 0: revision.diff = revisions[i].html revision.summary = _('initial version') else: revision.diff = htmldiff(revisions[i-1].html, revision.html) data = { 'view_name':'answer_revisions', 'active_tab':'questions', 'post': post, 'revisions': revisions, } context = RequestContext(request, data) template = ENV.get_template('revisions.html') return HttpResponse(template.render(context))
def user_email_subscriptions(request, user): if request.method == 'POST': email_feeds_form = forms.EditUserEmailFeedsForm(request.POST) tag_filter_form = forms.TagFilterSelectionForm(request.POST, instance=user) if email_feeds_form.is_valid() and tag_filter_form.is_valid(): action_status = None tag_filter_saved = tag_filter_form.save() if tag_filter_saved: action_status = _('changes saved') if 'save' in request.POST: feeds_saved = email_feeds_form.save(user) if feeds_saved: action_status = _('changes saved') elif 'stop_email' in request.POST: email_stopped = email_feeds_form.reset().save(user) initial_values = forms.EditUserEmailFeedsForm.NO_EMAIL_INITIAL email_feeds_form = forms.EditUserEmailFeedsForm(initial=initial_values) if email_stopped: action_status = _('email updates canceled') else: email_feeds_form = forms.EditUserEmailFeedsForm() email_feeds_form.set_initial_values(user) tag_filter_form = forms.TagFilterSelectionForm(instance=user) action_status = None template = ENV.get_template('user_profile/user_email_subscriptions.html') data = { 'active_tab': 'users', 'tab_name': 'email_subscriptions', 'tab_description': _('email subscription settings'), 'page_title': _('profile - email subscriptions'), 'view_user': user, 'email_feeds_form': email_feeds_form, 'tag_filter_selection_form': tag_filter_form, 'action_status': action_status, } context = RequestContext(request, data) return HttpResponse(template.render(context))
def badge(request, id): #todo: supplement database data with the stuff from badges.py badge = get_object_or_404(BadgeData, id=id) badge_recipients = User.objects.filter( award_user__badge = badge ).annotate( last_awarded_at = Max('award_user__awarded_at'), award_count = Count('award_user') ).order_by( '-last_awarded_at' ) template = ENV.get_template('badge.html') data = { 'view_name': badge, 'active_tab': 'badges', 'badge_recipients' : badge_recipients, 'badge' : badge, 'page_class': 'meta', } context = RequestContext(request, data) return HttpResponse(template.render(context))
def feedback(request): data = {'view_name':'feedback', 'page_class': 'meta'} form = None if request.method == "POST": form = FeedbackForm(request.POST) if form.is_valid(): if not request.user.is_authenticated: data['email'] = form.cleaned_data.get('email',None) data['message'] = form.cleaned_data['message'] data['name'] = form.cleaned_data.get('name',None) message = render_to_response('feedback_email.txt',data,context_instance=RequestContext(request)) mail_moderators(_('Q&A forum feedback'), message) msg = _('Thanks for the feedback!') request.user.message_set.create(message=msg) return HttpResponseRedirect(get_next_url(request)) else: form = FeedbackForm(initial={'next':get_next_url(request)}) data['form'] = form context = RequestContext(request, data) template = ENV.get_template('feedback.html') return HttpResponse(template.render(context))
def user_reputation(request, user): reputes = models.Repute.objects.filter(user=user).order_by('-reputed_at') #select_related() adds stuff needed for the query reputes = reputes.select_related( 'question__title', 'question__id', 'user__username' ) #reputes = reputates.annotate(positive=Sum("positive"), negative=Sum("negative")) #prepare data for the graph rep_list = [] #last values go in first rep_list.append('[%s,%s]' % ( calendar.timegm( datetime.datetime.now().timetuple() ) * 1000, user.reputation ) ) #ret remaining values in for rep in reputes: dic = '[%s,%s]' % (calendar.timegm(rep.reputed_at.timetuple()) * 1000, rep.reputation) rep_list.append(dic) reps = ','.join(rep_list) reps = '[%s]' % reps data = { 'active_tab':'users', 'tab_name': 'reputation', 'tab_description': _('user reputation in the community'), 'page_title': _('profile - user reputation'), 'view_user': user, 'reputation': reputes, 'reps': reps } context = RequestContext(request, data) template = ENV.get_template('user_profile/user_reputation.html') return HttpResponse(template.render(context))
def verifyemail(request, id=None, key=None): """ view that is shown when user clicks email validation link url = /email/verify/{{user.id}}/{{user.email_key}}/ """ logging.debug('') if askbot_settings.EMAIL_VALIDATION == True: user = User.objects.get(id=id) if user: if user.email_key == key: user.email_isvalid = True clear_email_validation_message(user) user.save() template = ENV.get_template('authopenid/changeemail.html') data = {'action_type': 'validation_complete'} context = RequestContext(request, data) return HttpResponse(template.render(context)) else: logging.error( 'hmm, no user found for email validation message - foul play?' ) raise Http404
def badges(request):#user status/reputation system #todo: supplement database data with the stuff from badges.py known_badges = badge_data.BADGES.keys() badges = BadgeData.objects.filter(slug__in = known_badges).order_by('slug') my_badges = [] if request.user.is_authenticated(): my_badges = Award.objects.filter( user=request.user ).values( 'badge_id' ).distinct() #my_badges.query.group_by = ['badge_id'] template = ENV.get_template('badges.html') data = { 'active_tab': 'badges', 'badges' : badges, 'view_name': 'badges', 'mybadges' : my_badges, 'feedback_faq_url' : reverse('feedback'), } context = RequestContext(request, data) return HttpResponse(template.render(context))
'answers' : page_objects.object_list, 'user_answer_votes': user_answer_votes, 'tags' : question.tags.all(), 'tab_id' : answer_sort_method, 'favorited' : favorited, 'similar_questions' : question.get_similar_questions(), 'language_code': translation.get_language(), 'paginator_context' : paginator_context, 'show_post': show_post, 'show_comment': show_comment, 'comment_order_number': comment_order_number } if request.user.is_authenticated(): data['tags_autocomplete'] = _get_tags_cache_json() context = RequestContext(request, data) template = ENV.get_template('question.html') return HttpResponse(template.render(context)) def revisions(request, id, object_name=None): assert(object_name in ('Question', 'Answer')) post = get_object_or_404(models.get_model(object_name), id=id) revisions = list(post.revisions.all()) revisions.reverse() for i, revision in enumerate(revisions): revision.html = revision.as_html() if i == 0: revision.diff = revisions[i].html revision.summary = _('initial version') else: revision.diff = htmldiff(revisions[i-1].html, revision.html) data = {
else: #this branch is for the initial load of ask form form = forms.AskForm() if 'title' in request.GET: #normally this title is inherited from search query #but it is possible to ask with a parameter title in the url query form.initial['title'] = request.GET['title'] else: #attempt to extract title from previous search query search_state = request.session.get('search_state',None) if search_state: query = search_state.query form.initial['title'] = query tags = _get_tags_cache_json() template = ENV.get_template('ask.html') data = { 'active_tab': 'ask', 'form' : form, 'tags' : tags, 'email_validation_faq_url':reverse('faq') + '#validate', } context = RequestContext(request, data) return HttpResponse(template.render(context)) @login_required def retag_question(request, id): """retag question view """ question = get_object_or_404(models.Question, id = id)
def signup_with_password(request): """Create a password-protected account template: authopenid/signup_with_password.html """ logging.debug(get_request_info(request)) next = get_next_url(request) login_form = forms.LoginForm(initial={'next': next}) #this is safe because second decorator cleans this field provider_name = request.REQUEST['login_provider'] if askbot_settings.USE_RECAPTCHA: RegisterForm = forms.SafeClassicRegisterForm else: RegisterForm = forms.ClassicRegisterForm logging.debug('request method was %s' % request.method) if request.method == 'POST': form = RegisterForm(request.POST) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST) #validation outside if to remember form values logging.debug('validating classic register form') form1_is_valid = form.is_valid() if form1_is_valid: logging.debug('classic register form validated') else: logging.debug('classic register form is not valid') form2_is_valid = email_feeds_form.is_valid() if form2_is_valid: logging.debug('email feeds form validated') else: logging.debug('email feeds form is not valid') if form1_is_valid and form2_is_valid: logging.debug('both forms are valid') next = form.cleaned_data['next'] username = form.cleaned_data['username'] password = form.cleaned_data['password1'] email = form.cleaned_data['email'] provider_name = form.cleaned_data['login_provider'] User.objects.create_user(username, email, password) logging.debug('new user %s created' % username) if provider_name != 'local': raise NotImplementedError('must run create external user code') user = authenticate(username=username, password=password, provider_name=provider_name, method='password') login(request, user) logging.debug('new user logged in') email_feeds_form.save(user) logging.debug('email feeds form saved') # send email #subject = _("Welcome email subject line") #message_template = ENV.get_template( # 'authopenid/confirm_email.txt' #) #message_context = Context({ # 'signup_url': askbot_settings.APP_URL + reverse('user_signin'), # 'username': username, # 'password': password, #}) #message = message_template.render(message_context) #send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, # [user.email]) #logging.debug('new password acct created, confirmation email sent!') return HttpResponseRedirect(next) else: #todo: this can be solved with a decorator, maybe form.initial['login_provider'] = provider_name logging.debug('create classic account forms were invalid') else: #todo: here we have duplication of get_password_login_provider... form = RegisterForm(initial={ 'next': next, 'login_provider': provider_name }) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm() logging.debug('printing legacy signup form') major_login_providers = util.get_major_login_providers() minor_login_providers = util.get_minor_login_providers() context_data = { 'form': form, 'page_class': 'openid-signin', 'email_feeds_form': email_feeds_form, 'major_login_providers': major_login_providers.values(), 'minor_login_providers': minor_login_providers.values(), 'login_form': login_form } template = ENV.get_template('authopenid/signup_with_password.html') context = RequestContext(request, context_data) return HttpResponse(template.render(context))
def register(request, login_provider_name=None, user_identifier=None): """ this function is used via it's own url with request.method=POST or as a simple function call from "finalize_generic_signin" in which case request.method must ge 'GET' and login_provider_name and user_identifier arguments must not be None this function may need to be refactored to simplify the usage pattern template : authopenid/complete.html """ logging.debug('') next_url = get_next_url(request) user = None is_redirect = False username = request.session.get('username', '') email = request.session.get('email', '') logging.debug('request method is %s' % request.method) register_form = forms.OpenidRegisterForm( initial={ 'next': next_url, 'username': request.session.get('username', ''), 'email': request.session.get('email', ''), }) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm() if request.method == 'GET': assert (login_provider_name is not None) assert (user_identifier is not None) #store this data into the session #to persist for the post request request.session['login_provider_name'] = login_provider_name request.session['user_identifier'] = user_identifier elif request.method == 'POST': if 'login_provider_name' not in request.session \ or 'user_identifier' not in request.session: logging.critical('illegal attempt to register') return HttpResponseRedirect(reverse('user_signin')) #load this data from the session user_identifier = request.session['user_identifier'] login_provider_name = request.session['login_provider_name'] logging.debug('trying to create new account associated with openid') register_form = forms.OpenidRegisterForm(request.POST) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST) if not register_form.is_valid(): logging.debug('OpenidRegisterForm is INVALID') elif not email_feeds_form.is_valid(): logging.debug('SimpleEmailSubscribeForm is INVALID') else: logging.debug( 'OpenidRegisterForm and SimpleEmailSubscribeForm are valid') is_redirect = True username = register_form.cleaned_data['username'] email = register_form.cleaned_data['email'] user = User.objects.create_user(username, email) logging.debug('creating new openid user association for %s') UserAssociation( openid_url=user_identifier, user=user, provider_name=login_provider_name, last_used_timestamp=datetime.datetime.now()).save() del request.session['user_identifier'] del request.session['login_provider_name'] logging.debug('logging the user in') user = authenticate(method='force', user_id=user.id) if user is None: error_message = 'please make sure that ' + \ 'askbot.deps.django_authopenid.backends.AuthBackend' + \ 'is in your settings.AUTHENTICATION_BACKENDS' raise Exception(error_message) login(request, user) logging.debug('saving email feed settings') email_feeds_form.save(user) #check if we need to post a question that was added anonymously #this needs to be a function call becase this is also done #if user just logged in and did not need to create the new account if user != None: if askbot_settings.EMAIL_VALIDATION == True: logging.debug('sending email validation') send_new_email_key(user, nomessage=True) output = validation_email_sent(request) set_email_validation_message( user) #message set after generating view return output if user.is_authenticated(): logging.debug('success, send user to main page') return HttpResponseRedirect(reverse('index')) else: logging.debug('have really strange error') raise Exception( 'openid login failed') #should not ever get here providers = { 'yahoo': '<font color="purple">Yahoo!</font>', 'flickr': '<font color="#0063dc">flick</font><font color="#ff0084">r</font>™', 'google': 'Google™', 'aol': '<font color="#31658e">AOL</font>', 'myopenid': 'MyOpenID', } if login_provider_name not in providers: provider_logo = login_provider_name logging.error( 'openid provider named "%s" has no pretty customized logo' % login_provider_name) else: provider_logo = providers[login_provider_name] logging.debug('printing authopenid/complete.html output') template = ENV.get_template('authopenid/complete.html') data = { 'openid_register_form': register_form, 'email_feeds_form': email_feeds_form, 'provider': mark_safe(provider_logo), 'username': username, 'email': email, 'login_type': 'openid', 'gravatar_faq_url': reverse('faq') + '#gravatar', } context = RequestContext(request, data) return HttpResponse(template.render(context))
def show_signin_view(request, login_form=None, account_recovery_form=None, account_recovery_message=None, sticky=False, view_subtype='default'): """url-less utility function that populates context of template 'authopenid/signin.html' and returns its rendered output """ allowed_subtypes = ('default', 'add_openid', 'email_sent', 'change_openid', 'bad_key') assert (view_subtype in allowed_subtypes) if sticky: next_url = reverse('user_signin') else: next_url = get_next_url(request) if login_form is None: login_form = forms.LoginForm(initial={'next': next_url}) if account_recovery_form is None: account_recovery_form = forms.AccountRecoveryForm( ) #initial = initial_data) #if request is GET if request.method == 'GET': logging.debug('request method was GET') #todo: this sthuff must be executed on some signal #because askbot should have nothing to do with the login app from askbot.models import AnonymousQuestion as AQ session_key = request.session.session_key logging.debug( 'retrieving anonymously posted question associated with session %s' % session_key) qlist = AQ.objects.filter(session_key=session_key).order_by('-added_at') if len(qlist) > 0: question = qlist[0] else: question = None from askbot.models import AnonymousAnswer as AA session_key = request.session.session_key logging.debug('retrieving posted answer associated with session %s' % session_key) alist = AA.objects.filter(session_key=session_key).order_by('-added_at') if len(alist) > 0: answer = alist[0] else: answer = None if request.user.is_authenticated(): existing_login_methods = UserAssociation.objects.filter( user=request.user) if view_subtype == 'default': page_title = _('Please click any of the icons below to sign in') elif view_subtype == 'email_sent': page_title = _('Account recovery email sent') elif view_subtype == 'change_openid': if len(existing_login_methods) == 0: page_title = _('Please add one or more login methods.') else: page_title = _( 'If you wish, please add, remove or re-validate your login methods' ) elif view_subtype == 'add_openid': page_title = _( 'Please wait a second! Your account is recovered, but ...') elif view_subtype == 'bad_key': page_title = _( 'Sorry, this account recovery key has expired or is invalid') logging.debug('showing signin view') data = { 'page_class': 'openid-signin', 'view_subtype': view_subtype, #add_openid|default 'page_title': page_title, 'question': question, 'answer': answer, 'login_form': login_form, 'use_password_login': util.use_password_login(), 'account_recovery_form': account_recovery_form, 'openid_error_message': request.REQUEST.get('msg', ''), 'account_recovery_message': account_recovery_message, 'use_password_login': util.use_password_login(), } major_login_providers = util.get_major_login_providers() minor_login_providers = util.get_minor_login_providers() active_provider_names = None if request.user.is_authenticated(): data['existing_login_methods'] = existing_login_methods active_provider_names = [ item.provider_name for item in existing_login_methods ] util.set_login_provider_tooltips( major_login_providers, active_provider_names=active_provider_names) util.set_login_provider_tooltips( minor_login_providers, active_provider_names=active_provider_names) data['major_login_providers'] = major_login_providers.values() data['minor_login_providers'] = minor_login_providers.values() template = ENV.get_template('authopenid/signin.html') context = RequestContext(request, data) return HttpResponse(template.render(context))
def questions(request): """ List of Questions, Tagged questions, and Unanswered questions. matching search query or user selection """ #don't allow to post to this view if request.method == 'POST': raise Http404 #todo: redo SearchState to accept input from #view_log, session and request parameters search_state = request.session.get('search_state', SearchState()) view_log = request.session['view_log'] if view_log.get_previous(1) != 'questions': if view_log.get_previous(2) != 'questions': #print 'user stepped too far, resetting search state' search_state.reset() if request.user.is_authenticated(): search_state.set_logged_in() form = AdvancedSearchForm(request.GET) #todo: form is used only for validation... if form.is_valid(): search_state.update_from_user_input( form.cleaned_data, request.GET, ) #todo: better put these in separately then analyze #what neesd to be done, otherwise there are two routines #that take request.GET I don't like this use of parameters #another weakness is that order of routine calls matters here search_state.relax_stickiness( request.GET, view_log ) request.session['search_state'] = search_state request.session.modified = True #force reset for debugging #search_state.reset() #request.session.modified = True #todo: have this call implemented for sphinx, mysql and pgsql (qs, meta_data, related_tags) = models.Question.objects.run_advanced_search( request_user = request.user, search_state = search_state, ) paginator = Paginator(qs, search_state.page_size) if paginator.num_pages < search_state.page: raise Http404 page = paginator.page(search_state.page) contributors = models.Question.objects.get_question_and_answer_contributors(page.object_list) paginator_context = { 'is_paginated' : (paginator.count > search_state.page_size), 'pages': paginator.num_pages, 'page': search_state.page, 'has_previous': page.has_previous(), 'has_next': page.has_next(), 'previous': page.previous_page_number(), 'next': page.next_page_number(), 'base_url' : request.path + '?sort=%s&' % search_state.sort,#todo in T sort=>sort_method 'page_size' : search_state.page_size,#todo in T pagesize -> page_size } if request.is_ajax(): q_count = paginator.count question_counter = ungettext( '%(q_num)s question', '%(q_num)s questions', q_count ) % { 'q_num': humanize.intcomma(q_count), } if q_count > search_state.page_size: paginator_tpl = ENV.get_template('paginator.html') #todo: remove this patch on context after all templates are moved to jinja paginator_context['base_url'] = request.path + '?sort=%s&' % search_state.sort data = { 'paginator_context': extra_tags.cnprog_paginator(paginator_context) } paginator_html = paginator_tpl.render(Context(data)) else: paginator_html = '' ajax_data = { #current page is 1 by default now #because ajax is only called by update in the search button 'paginator': paginator_html, 'question_counter': question_counter, 'questions': list(), 'related_tags': list(), 'faces': list() } badge_levels = dict(const.BADGE_TYPE_CHOICES) def pluralize_badge_count(count, level): return ungettext( '%(badge_count)d %(badge_level)s badge', '%(badge_count)d %(badge_level)s badges', count ) % { 'badge_count': count, 'badge_level': badge_levels[level] } gold_badge_css_class = const.BADGE_CSS_CLASSES[const.GOLD_BADGE], silver_badge_css_class = const.BADGE_CSS_CLASSES[const.SILVER_BADGE], bronze_badge_css_class = const.BADGE_CSS_CLASSES[const.BRONZE_BADGE], for tag in related_tags: tag_data = { 'name': tag.name, 'used_count': humanize.intcomma(tag.local_used_count) } ajax_data['related_tags'].append(tag_data) for contributor in contributors: ajax_data['faces'].append(extra_tags.gravatar(contributor, 48)) for question in page.object_list: timestamp = question.last_activity_at author = question.last_activity_by if question.score == 0: votes_class = 'no-votes' else: votes_class = 'some-votes' if question.answer_count == 0: answers_class = 'no-answers' elif question.answer_accepted: answers_class = 'accepted' else: answers_class = 'some-answers' if question.view_count == 0: views_class = 'no-views' else: views_class = 'some-views' question_data = { 'title': question.title, 'summary': question.summary, 'id': question.id, 'tags': question.get_tag_names(), 'votes': extra_filters.humanize_counter(question.score), 'votes_class': votes_class, 'votes_word': ungettext('vote', 'votes', question.score), 'answers': extra_filters.humanize_counter(question.answer_count), 'answers_class': answers_class, 'answers_word': ungettext('answer', 'answers', question.answer_count), 'views': extra_filters.humanize_counter(question.view_count), 'views_class': views_class, 'views_word': ungettext('view', 'views', question.view_count), 'timestamp': unicode(timestamp), 'timesince': functions.diff_date(timestamp), 'u_id': author.id, 'u_name': author.username, 'u_rep': author.reputation, 'u_gold': author.gold, 'u_gold_title': pluralize_badge_count( author.gold, const.GOLD_BADGE ), 'u_gold_badge_symbol': const.BADGE_DISPLAY_SYMBOL, 'u_gold_css_class': gold_badge_css_class, 'u_silver': author.silver, 'u_silver_title': pluralize_badge_count( author.silver, const.SILVER_BADGE ), 'u_silver_badge_symbol': const.BADGE_DISPLAY_SYMBOL, 'u_silver_css_class': silver_badge_css_class, 'u_bronze': author.bronze, 'u_bronze_title': pluralize_badge_count( author.bronze, const.BRONZE_BADGE ), 'u_bronze_badge_symbol': const.BADGE_DISPLAY_SYMBOL, 'u_bronze_css_class': bronze_badge_css_class, } ajax_data['questions'].append(question_data) return HttpResponse( simplejson.dumps(ajax_data), mimetype = 'application/json' ) tags_autocomplete = _get_tags_cache_json() reset_method_count = 0 if search_state.query: reset_method_count += 1 if search_state.tags: reset_method_count += 1 if meta_data.get('author_name',None): reset_method_count += 1 template_context = RequestContext(request, { 'language_code': translation.get_language(), 'reset_method_count': reset_method_count, 'view_name': 'questions', 'active_tab': 'questions', 'questions' : page, 'contributors' : contributors, 'author_name' : meta_data.get('author_name',None), 'tab_id' : search_state.sort, 'questions_count' : paginator.count, 'tags' : related_tags, 'query': search_state.query, 'search_tags' : search_state.tags, 'tags_autocomplete' : tags_autocomplete, 'is_unanswered' : False,#remove this from template 'interesting_tag_names': meta_data.get('interesting_tag_names',None), 'ignored_tag_names': meta_data.get('ignored_tag_names',None), 'sort': search_state.sort, 'show_sort_by_relevance': askbot.conf.should_show_sort_by_relevance(), 'scope': search_state.scope, 'context' : paginator_context, }) assert(request.is_ajax() == False) #ajax request is handled in a separate branch above #before = datetime.datetime.now() template = ENV.get_template('questions.html') response = HttpResponse(template.render(template_context)) #after = datetime.datetime.now() #print after - before return response
def signup_with_password(request): """Create a password-protected account template: authopenid/signup_with_password.html """ logging.debug(get_request_info(request)) next = get_next_url(request) # this is safe because second decorator cleans this field provider_name = request.REQUEST["login_provider"] if askbot_settings.USE_RECAPTCHA: RegisterForm = forms.SafeClassicRegisterForm else: RegisterForm = forms.ClassicRegisterForm logging.debug("request method was %s" % request.method) if request.method == "POST": form = RegisterForm(request.POST) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST) # validation outside if to remember form values logging.debug("validating classic register form") form1_is_valid = form.is_valid() if form1_is_valid: logging.debug("classic register form validated") else: logging.debug("classic register form is not valid") form2_is_valid = email_feeds_form.is_valid() if form2_is_valid: logging.debug("email feeds form validated") else: logging.debug("email feeds form is not valid") if form1_is_valid and form2_is_valid: logging.debug("both forms are valid") next = form.cleaned_data["next"] username = form.cleaned_data["username"] password = form.cleaned_data["password1"] email = form.cleaned_data["email"] provider_name = form.cleaned_data["login_provider"] User.objects.create_user(username, email, password) logging.debug("new user %s created" % username) if provider_name != "local": raise NotImplementedError("must run create external user code") user = authenticate(username=username, password=password, provider_name=provider_name, method="password") login(request, user) logging.debug("new user logged in") email_feeds_form.save(user) logging.debug("email feeds form saved") # send email # subject = _("Welcome email subject line") # message_template = ENV.get_template( # 'authopenid/confirm_email.txt' # ) # message_context = Context({ # 'signup_url': askbot_settings.APP_URL + reverse('user_signin'), # 'username': username, # 'password': password, # }) # message = message_template.render(message_context) # send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, # [user.email]) # logging.debug('new password acct created, confirmation email sent!') return HttpResponseRedirect(next) else: # todo: this can be solved with a decorator, maybe form.initial["login_provider"] = provider_name logging.debug("create classic account forms were invalid") else: # todo: here we have duplication of get_password_login_provider... form = RegisterForm(initial={"next": next, "login_provider": provider_name}) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm() logging.debug("printing legacy signup form") context_data = {"form": form, "email_feeds_form": email_feeds_form} template = ENV.get_template("authopenid/signup_with_password.html") context = RequestContext(request, context_data) return HttpResponse(template.render(context))
def show_signin_view( request, login_form=None, account_recovery_form=None, account_recovery_message=None, sticky=False, view_subtype="default", ): """url-less utility function that populates context of template 'authopenid/signin.html' and returns its rendered output """ allowed_subtypes = ("default", "add_openid", "email_sent", "change_openid", "bad_key") assert view_subtype in allowed_subtypes if sticky: next_url = reverse("user_signin") else: next_url = get_next_url(request) if login_form is None: login_form = forms.LoginForm(initial={"next": next_url}) if account_recovery_form is None: account_recovery_form = forms.AccountRecoveryForm() # initial = initial_data) # if request is GET if request.method == "GET": logging.debug("request method was GET") # todo: this sthuff must be executed on some signal # because askbot should have nothing to do with the login app from askbot.models import AnonymousQuestion as AQ session_key = request.session.session_key logging.debug("retrieving anonymously posted question associated with session %s" % session_key) qlist = AQ.objects.filter(session_key=session_key).order_by("-added_at") if len(qlist) > 0: question = qlist[0] else: question = None from askbot.models import AnonymousAnswer as AA session_key = request.session.session_key logging.debug("retrieving posted answer associated with session %s" % session_key) alist = AA.objects.filter(session_key=session_key).order_by("-added_at") if len(alist) > 0: answer = alist[0] else: answer = None if request.user.is_authenticated(): existing_login_methods = UserAssociation.objects.filter(user=request.user) if view_subtype == "default": page_title = _("Please click any of the icons below to sign in") elif view_subtype == "email_sent": page_title = _("Account recovery email sent") elif view_subtype == "change_openid": if len(existing_login_methods) == 0: page_title = _("Please add one or more login methods.") else: page_title = _("If you wish, please add, remove or re-validate your login methods") elif view_subtype == "add_openid": page_title = _("Please wait a second! Your account is recovered, but ...") elif view_subtype == "bad_key": page_title = _("Sorry, this account recovery key has expired or is invalid") logging.debug("showing signin view") data = { "page_class": "openid-signin", "view_subtype": view_subtype, # add_openid|default "page_title": page_title, "question": question, "answer": answer, "login_form": login_form, "use_password_login": util.use_password_login(), "account_recovery_form": account_recovery_form, "openid_error_message": request.REQUEST.get("msg", ""), "account_recovery_message": account_recovery_message, "use_password_login": util.use_password_login(), } major_login_providers = util.get_major_login_providers() minor_login_providers = util.get_minor_login_providers() active_provider_names = None if request.user.is_authenticated(): data["existing_login_methods"] = existing_login_methods active_provider_names = [item.provider_name for item in existing_login_methods] util.set_login_provider_tooltips(major_login_providers, active_provider_names=active_provider_names) util.set_login_provider_tooltips(minor_login_providers, active_provider_names=active_provider_names) data["major_login_providers"] = major_login_providers.values() data["minor_login_providers"] = minor_login_providers.values() template = ENV.get_template("authopenid/signin.html") context = RequestContext(request, data) return HttpResponse(template.render(context))
def register(request, login_provider_name=None, user_identifier=None): """ this function is used via it's own url with request.method=POST or as a simple function call from "finalize_generic_signin" in which case request.method must ge 'GET' and login_provider_name and user_identifier arguments must not be None this function may need to be refactored to simplify the usage pattern template : authopenid/complete.html """ logging.debug("") next_url = get_next_url(request) user = None is_redirect = False username = request.session.get("username", "") email = request.session.get("email", "") logging.debug("request method is %s" % request.method) register_form = forms.OpenidRegisterForm( initial={ "next": next_url, "username": request.session.get("username", ""), "email": request.session.get("email", ""), } ) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm() if request.method == "GET": assert login_provider_name is not None assert user_identifier is not None # store this data into the session # to persist for the post request request.session["login_provider_name"] = login_provider_name request.session["user_identifier"] = user_identifier elif request.method == "POST": if "login_provider_name" not in request.session or "user_identifier" not in request.session: logging.critical("illegal attempt to register") return HttpResponseRedirect(reverse("user_signin")) # load this data from the session user_identifier = request.session["user_identifier"] login_provider_name = request.session["login_provider_name"] logging.debug("trying to create new account associated with openid") register_form = forms.OpenidRegisterForm(request.POST) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST) if not register_form.is_valid(): logging.debug("OpenidRegisterForm is INVALID") elif not email_feeds_form.is_valid(): logging.debug("SimpleEmailSubscribeForm is INVALID") else: logging.debug("OpenidRegisterForm and SimpleEmailSubscribeForm are valid") is_redirect = True username = register_form.cleaned_data["username"] email = register_form.cleaned_data["email"] user = User.objects.create_user(username, email) logging.debug("creating new openid user association for %s") UserAssociation( openid_url=user_identifier, user=user, provider_name=login_provider_name, last_used_timestamp=datetime.datetime.now(), ).save() del request.session["user_identifier"] del request.session["login_provider_name"] logging.debug("logging the user in") user = authenticate(method="force", user_id=user.id) if user is None: error_message = ( "please make sure that " + "askbot.deps.django_authopenid.backends.AuthBackend" + "is in your settings.AUTHENTICATION_BACKENDS" ) raise Exception(error_message) login(request, user) logging.debug("saving email feed settings") email_feeds_form.save(user) # check if we need to post a question that was added anonymously # this needs to be a function call becase this is also done # if user just logged in and did not need to create the new account if user != None: if askbot_settings.EMAIL_VALIDATION == True: logging.debug("sending email validation") send_new_email_key(user, nomessage=True) output = validation_email_sent(request) set_email_validation_message(user) # message set after generating view return output if user.is_authenticated(): logging.debug("success, send user to main page") return HttpResponseRedirect(reverse("index")) else: logging.debug("have really strange error") raise Exception("openid login failed") # should not ever get here providers = { "yahoo": '<font color="purple">Yahoo!</font>', "flickr": '<font color="#0063dc">flick</font><font color="#ff0084">r</font>™', "google": "Google™", "aol": '<font color="#31658e">AOL</font>', "myopenid": "MyOpenID", } if login_provider_name not in providers: provider_logo = login_provider_name logging.error('openid provider named "%s" has no pretty customized logo' % login_provider_name) else: provider_logo = providers[login_provider_name] logging.debug("printing authopenid/complete.html output") template = ENV.get_template("authopenid/complete.html") data = { "openid_register_form": register_form, "email_feeds_form": email_feeds_form, "provider": mark_safe(provider_logo), "username": username, "email": email, "login_type": "openid", "gravatar_faq_url": reverse("faq") + "#gravatar", } context = RequestContext(request, data) return HttpResponse(template.render(context))
def render(self, context): jinja_template = ENV.get_template(self.filename) return jinja_template.render(context)