def setUp(self): self.conf = { 'language_mode': askbot.get_lang_mode(), 'language_code': django_settings.LANGUAGE_CODE, 'languages': django_settings.LANGUAGES } django_settings.ASKBOT_LANGUAGE_MODE = 'url-lang' django_settings.LANGUAGE_CODE = 'en' django_settings.LANGUAGES = (('en', 'English'), ('de', 'German')) translation.activate('en')
def question(request, id):#refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it todo: convert this view into class """ #process url parameters #todo: fix inheritance of sort method from questions #before = timezone.now() form = ShowQuestionForm(request.REQUEST) form.full_clean()#always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] answer_sort_method = form.cleaned_data['answer_sort_method'] #load question and maybe refuse showing deleted question #if the question does not exist - try mapping to old questions #and and if it is not found again - then give up try: question_post = models.Post.objects.filter( post_type = 'question', id = id ).select_related('thread')[0] except IndexError: # Handle URL mapping - from old Q/A/C/ URLs to the new one try: question_post = models.Post.objects.filter( post_type='question', old_question_id = id ).select_related('thread')[0] except IndexError: raise Http404 if show_answer: try: old_answer = models.Post.objects.get_answers().get(old_answer_id=show_answer) except models.Post.DoesNotExist: pass else: return HttpResponseRedirect(old_answer.get_absolute_url()) elif show_comment: try: old_comment = models.Post.objects.get_comments().get(old_comment_id=show_comment) except models.Post.DoesNotExist: pass else: return HttpResponseRedirect(old_comment.get_absolute_url()) if show_comment or show_answer: try: show_post = models.Post.objects.get(pk=(show_comment or show_answer)) except models.Post.DoesNotExist: #missing target post will be handled later pass else: if (show_comment and not show_post.is_comment()) \ or (show_answer and not show_post.is_answer()): return HttpResponseRedirect(show_post.get_absolute_url()) try: question_post.assert_is_visible_to(request.user) except exceptions.QuestionHidden as error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('index')) #redirect if slug in the url is wrong if request.path.split('/')[-2] != question_post.slug: logging.debug('no slug match!') lang = translation.get_language() question_url = question_post.get_absolute_url(language=lang) if request.GET: question_url += u'?' + urllib.urlencode(request.GET) return HttpResponseRedirect(question_url) #resolve comment and answer permalinks #they go first because in theory both can be moved to another question #this block "returns" show_post and assigns actual comment and answer #to show_comment and show_answer variables #in the case if the permalinked items or their parents are gone - redirect #redirect also happens if id of the object's origin post != requested id show_post = None #used for permalinks if show_comment: #if url calls for display of a specific comment, #check that comment exists, that it belongs to #the current question #if it is an answer comment and the answer is hidden - #redirect to the default view of the question #if the question is hidden - redirect to the main page #in addition - if url points to a comment and the comment #is for the answer - we need the answer object try: show_comment = models.Post.objects.get_comments().get(id=show_comment) except models.Post.DoesNotExist: error_message = _( 'Sorry, the comment you are looking for has been ' 'deleted and is no longer accessible' ) request.user.message_set.create(message = error_message) return HttpResponseRedirect(question_post.thread.get_absolute_url()) if str(show_comment.thread._question_post().id) != str(id): return HttpResponseRedirect(show_comment.get_absolute_url()) show_post = show_comment.parent try: show_comment.assert_is_visible_to(request.user) except exceptions.AnswerHidden as error: request.user.message_set.create(message = unicode(error)) #use reverse function here because question is not yet loaded return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) except exceptions.QuestionHidden as error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('index')) elif show_answer: #if the url calls to view a particular answer to #question - we must check whether the question exists #whether answer is actually corresponding to the current question #and that the visitor is allowed to see it show_post = get_object_or_404(models.Post, post_type='answer', id=show_answer) if str(show_post.thread._question_post().id) != str(id): return HttpResponseRedirect(show_post.get_absolute_url()) try: show_post.assert_is_visible_to(request.user) except django_exceptions.PermissionDenied as error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) thread = question_post.thread if askbot.get_lang_mode() == 'url-lang': request_lang = translation.get_language() if request_lang != thread.language_code: template = get_template('question/lang_switch_message.html') message = template.render(Context({ 'post_lang': get_language_name(thread.language_code), 'request_lang': get_language_name(request_lang), 'home_url': reverse_i18n(request_lang, 'questions') })) request.user.message_set.create(message=message) return HttpResponseRedirect(thread.get_absolute_url()) logging.debug('answer_sort_method=' + unicode(answer_sort_method)) #load answers and post id's->athor_id mapping #posts are pre-stuffed with the correctly ordered comments question_post, answers, post_to_author, published_answer_ids = thread.get_post_data_for_question_view( sort_method=answer_sort_method, user=request.user ) user_votes = {} user_post_id_list = list() #todo: cache this query set, but again takes only 3ms! if request.user.is_authenticated(): user_votes = Vote.objects.filter( user=request.user, voted_post__id__in = post_to_author.keys() ).values_list('voted_post_id', 'vote') user_votes = dict(user_votes) #we can avoid making this query by iterating through #already loaded posts user_post_id_list = [ post_id for post_id in post_to_author if post_to_author[post_id] == request.user.id ] #resolve page number and comment number for permalinks show_comment_position = None if show_comment: show_page = show_comment.get_page_number(answer_posts=answers) show_comment_position = show_comment.get_order_number() elif show_answer: show_page = show_post.get_page_number(answer_posts=answers) objects_list = Paginator(answers, const.ANSWERS_PAGE_SIZE) if show_page > objects_list.num_pages: return HttpResponseRedirect(question_post.get_absolute_url()) page_objects = objects_list.page(show_page) #count visits signals.question_visited.send(None, request=request, question=question_post, ) paginator_data = { 'is_paginated' : (objects_list.count > const.ANSWERS_PAGE_SIZE), 'pages': objects_list.num_pages, 'current_page_number': show_page, 'page_object': page_objects, 'base_url' : request.path + '?sort=%s&' % answer_sort_method, } paginator_context = functions.setup_paginator(paginator_data) #todo: maybe consolidate all activity in the thread #for the user into just one query? favorited = thread.has_favorite_by_user(request.user) is_cacheable = True if show_page != 1: is_cacheable = False elif show_comment_position > askbot_settings.MAX_COMMENTS_TO_SHOW: is_cacheable = False #maybe load draft initial = {} if request.user.is_authenticated(): #todo: refactor into methor on thread drafts = models.DraftAnswer.objects.filter( author=request.user, thread=thread ) if drafts.count() > 0: initial['text'] = drafts[0].get_text() custom_answer_form_path = django_settings.ASKBOT_NEW_ANSWER_FORM if custom_answer_form_path: answer_form_class = load_module(custom_answer_form_path) else: answer_form_class = AnswerForm answer_form = answer_form_class(initial=initial, user=request.user) user_can_post_comment = ( request.user.is_authenticated() \ and request.user.can_post_comment(question_post) ) new_answer_allowed = True previous_answer = None if request.user.is_authenticated(): if askbot_settings.LIMIT_ONE_ANSWER_PER_USER: for answer in answers: if answer.author_id == request.user.pk: new_answer_allowed = False previous_answer = answer break if request.user.is_authenticated() and askbot_settings.GROUPS_ENABLED: group_read_only = request.user.is_read_only() else: group_read_only = False #session variable added so that the session is #not empty and is not autodeleted, otherwise anonymous #answer posting is impossible request.session['askbot_write_intent'] = True data = { 'active_tab': 'questions', 'answer' : answer_form, 'answers' : page_objects.object_list, 'answer_count': thread.get_answer_count(request.user), 'blank_comment': MockPost(post_type='comment', author=request.user),#data for the js comment template 'category_tree_data': askbot_settings.CATEGORY_TREE, 'favorited' : favorited, 'group_read_only': group_read_only, 'is_cacheable': False,#is_cacheable, #temporary, until invalidation fix 'language_code': translation.get_language(), 'long_time': const.LONG_TIME,#"forever" caching 'new_answer_allowed': new_answer_allowed, 'oldest_answer_id': thread.get_oldest_answer_id(request.user), 'page_class': 'question-page', 'paginator_context' : paginator_context, 'previous_answer': previous_answer, 'published_answer_ids': published_answer_ids, 'question' : question_post, 'show_comment': show_comment, 'show_comment_position': show_comment_position, 'show_post': show_post, 'similar_threads' : thread.get_similar_threads(), 'tab_id' : answer_sort_method, 'thread': thread, 'thread_is_moderated': thread.is_moderated(), 'user_is_thread_moderator': thread.has_moderator(request.user), 'user_votes': user_votes, 'user_post_id_list': user_post_id_list, 'user_can_post_comment': user_can_post_comment,#in general } #shared with ... if askbot_settings.GROUPS_ENABLED: data['sharing_info'] = thread.get_sharing_info() data.update(context.get_for_tag_editor()) extra = context.get_extra('ASKBOT_QUESTION_PAGE_EXTRA_CONTEXT', request, data) data.update(extra) return render(request, 'question.html', data)
def application_settings(request): """The context processor function""" #if not request.path.startswith('/' + settings.ASKBOT_URL): # #todo: this is a really ugly hack, will only work # #when askbot is installed not at the home page. # #this will not work for the # #heavy modders of askbot, because their custom pages # #will not receive the askbot settings in the context # #to solve this properly we should probably explicitly # #add settings to the context per page # return {} my_settings = askbot_settings.as_dict() my_settings['LANGUAGE_CODE'] = getattr(request, 'LANGUAGE_CODE', settings.LANGUAGE_CODE) my_settings['LANGUAGE_MODE'] = askbot.get_lang_mode() my_settings['MULTILINGUAL'] = askbot.is_multilingual() my_settings['LANGUAGES_DICT'] = dict(getattr(settings, 'LANGUAGES', [])) my_settings['ALLOWED_UPLOAD_FILE_TYPES'] = \ settings.ASKBOT_ALLOWED_UPLOAD_FILE_TYPES my_settings['ASKBOT_URL'] = settings.ASKBOT_URL my_settings['STATIC_URL'] = settings.STATIC_URL my_settings['IP_MODERATION_ENABLED'] = getattr( settings, 'ASKBOT_IP_MODERATION_ENABLED', False) my_settings['USE_LOCAL_FONTS'] = getattr(settings, 'ASKBOT_USE_LOCAL_FONTS', False) my_settings['CSRF_COOKIE_NAME'] = settings.CSRF_COOKIE_NAME my_settings['DEBUG'] = settings.DEBUG my_settings['USING_RUNSERVER'] = 'runserver' in sys.argv my_settings['ASKBOT_VERSION'] = askbot.get_version() my_settings['LOGIN_URL'] = url_utils.get_login_url() my_settings['LOGOUT_URL'] = url_utils.get_logout_url() if my_settings['EDITOR_TYPE'] == 'tinymce': tinymce_plugins = settings.TINYMCE_DEFAULT_CONFIG.get('plugins', '').split(',') my_settings['TINYMCE_PLUGINS'] = map(lambda v: v.strip(), tinymce_plugins) else: my_settings['TINYMCE_PLUGINS'] = [] my_settings['LOGOUT_REDIRECT_URL'] = url_utils.get_logout_redirect_url() current_language = get_language() #for some languages we will start searching for shorter words if current_language == 'ja': #we need to open the search box and show info message about #the japanese lang search min_search_word_length = 1 else: min_search_word_length = my_settings['MIN_SEARCH_WORD_LENGTH'] need_scope_links = askbot_settings.ALL_SCOPE_ENABLED or \ askbot_settings.UNANSWERED_SCOPE_ENABLED or \ (request.user.is_authenticated() and askbot_settings.FOLLOWED_SCOPE_ENABLED) context = { 'base_url': site_url(''), 'csrf_token': get_or_create_csrf_token(request), 'empty_search_state': SearchState.get_empty(), 'min_search_word_length': min_search_word_length, 'current_language_code': current_language, 'settings': my_settings, 'moderation_items': api.get_info_on_moderation_items(request.user), 'need_scope_links': need_scope_links, 'noscript_url': const.DEPENDENCY_URLS['noscript'], } use_askbot_login = '******' in settings.INSTALLED_APPS my_settings['USE_ASKBOT_LOGIN_SYSTEM'] = use_askbot_login if use_askbot_login and request.user.is_anonymous(): from askbot.deps.django_authopenid import context as login_context context.update(login_context.login_context(request)) if askbot_settings.GROUPS_ENABLED: #calculate context needed to list all the groups def _get_group_url(group): """calculates url to the group based on its id and name""" group_slug = slugify(group['name']) return reverse('users_by_group', kwargs={ 'group_id': group['id'], 'group_slug': group_slug }) #load id's and names of all groups global_group = models.Group.objects.get_global_group() groups = models.Group.objects.exclude_personal() groups = groups.exclude(id=global_group.id) groups_data = list(groups.values('id', 'name')) #sort groups_data alphanumerically, but case-insensitive groups_data = sorted( groups_data, lambda x, y: cmp(x['name'].lower(), y['name'].lower())) #insert data for the global group at the first position groups_data.insert(0, { 'id': global_group.id, 'name': global_group.name }) #build group_list for the context group_list = list() for group in groups_data: link = _get_group_url(group) group_list.append({'name': group['name'], 'link': link}) context['group_list'] = simplejson.dumps(group_list) return context
def application_settings(request): """The context processor function""" # if not request.path.startswith('/' + settings.ASKBOT_URL): # #todo: this is a really ugly hack, will only work # #when askbot is installed not at the home page. # #this will not work for the # #heavy modders of askbot, because their custom pages # #will not receive the askbot settings in the context # #to solve this properly we should probably explicitly # #add settings to the context per page # return {} my_settings = askbot_settings.as_dict() my_settings['LANGUAGE_CODE'] = getattr(request, 'LANGUAGE_CODE', settings.LANGUAGE_CODE) my_settings['LANGUAGE_MODE'] = askbot.get_lang_mode() my_settings['MULTILINGUAL'] = askbot.is_multilingual() my_settings['LANGUAGES_DICT'] = dict(getattr(settings, 'LANGUAGES', [])) my_settings[ 'ALLOWED_UPLOAD_FILE_TYPES'] = settings.ASKBOT_ALLOWED_UPLOAD_FILE_TYPES my_settings['ASKBOT_URL'] = settings.ASKBOT_URL my_settings['STATIC_URL'] = settings.STATIC_URL my_settings['IP_MODERATION_ENABLED'] = getattr( settings, 'ASKBOT_IP_MODERATION_ENABLED', False) my_settings['USE_LOCAL_FONTS'] = getattr(settings, 'ASKBOT_USE_LOCAL_FONTS', False) my_settings['CSRF_COOKIE_NAME'] = settings.CSRF_COOKIE_NAME my_settings['DEBUG'] = settings.DEBUG my_settings['USING_RUNSERVER'] = 'runserver' in sys.argv my_settings['ASKBOT_VERSION'] = askbot.get_version() my_settings['LOGIN_URL'] = url_utils.get_login_url() my_settings['LOGOUT_URL'] = url_utils.get_logout_url() if my_settings['EDITOR_TYPE'] == 'tinymce': tinymce_plugins = settings.TINYMCE_DEFAULT_CONFIG.get('plugins', '').split(',') my_settings['TINYMCE_PLUGINS'] = [v.strip() for v in tinymce_plugins] my_settings[ 'TINYMCE_EDITOR_DESELECTOR'] = settings.TINYMCE_DEFAULT_CONFIG[ 'editor_deselector'] my_settings['TINYMCE_CONFIG_JSON'] = json.dumps( settings.TINYMCE_DEFAULT_CONFIG) else: my_settings['TINYMCE_PLUGINS'] = [] my_settings['TINYMCE_EDITOR_DESELECTOR'] = '' my_settings['LOGOUT_REDIRECT_URL'] = url_utils.get_logout_redirect_url() current_language = get_language() # for some languages we will start searching for shorter words if current_language == 'ja': # we need to open the search box and show info message about # the japanese lang search min_search_word_length = 1 else: min_search_word_length = my_settings['MIN_SEARCH_WORD_LENGTH'] need_scope_links = askbot_settings.ALL_SCOPE_ENABLED or \ askbot_settings.UNANSWERED_SCOPE_ENABLED or \ (request.user.is_authenticated and askbot_settings.FOLLOWED_SCOPE_ENABLED) context = { 'base_url': site_url(''), 'csrf_token': csrf.get_token(request), 'empty_search_state': SearchState.get_empty(), 'min_search_word_length': min_search_word_length, 'current_language_code': current_language, 'settings': my_settings, 'moderation_items': api.get_info_on_moderation_items(request.user), 'need_scope_links': need_scope_links, 'noscript_url': const.DEPENDENCY_URLS['noscript'], } use_askbot_login = '******' in settings.INSTALLED_APPS my_settings['USE_ASKBOT_LOGIN_SYSTEM'] = use_askbot_login if use_askbot_login and request.user.is_anonymous: from askbot.deps.django_authopenid import context as login_context context.update(login_context.login_context(request)) context['group_list'] = json.dumps(make_group_list()) if askbot_settings.EDITOR_TYPE == 'tinymce': from tinymce.widgets import TinyMCE context['tinymce'] = TinyMCE() return context
#question - we must check whether the question exists #whether answer is actually corresponding to the current question #and that the visitor is allowed to see it show_post = get_object_or_404(models.Post, post_type='answer', id=show_answer) if str(show_post.thread._question_post().id) != str(id): return HttpResponseRedirect(show_post.get_absolute_url()) try: show_post.assert_is_visible_to(request.user) except django_exceptions.PermissionDenied, error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) thread = question_post.thread if askbot.get_lang_mode() == 'url-lang': request_lang = translation.get_language() if request_lang != thread.language_code: template = get_template('question/lang_switch_message.html') message = template.render(Context({ 'post_lang': get_language_name(thread.language_code), 'request_lang': get_language_name(request_lang), 'home_url': reverse_i18n(request_lang, 'questions') })) request.user.message_set.create(message=message) return HttpResponseRedirect(thread.get_absolute_url()) logging.debug('answer_sort_method=' + unicode(answer_sort_method)) #load answers and post id's->athor_id mapping #posts are pre-stuffed with the correctly ordered comments
def application_settings(request): """The context processor function""" #if not request.path.startswith('/' + settings.ASKBOT_URL): # #todo: this is a really ugly hack, will only work # #when askbot is installed not at the home page. # #this will not work for the # #heavy modders of askbot, because their custom pages # #will not receive the askbot settings in the context # #to solve this properly we should probably explicitly # #add settings to the context per page # return {} my_settings = askbot_settings.as_dict() my_settings['LANGUAGE_CODE'] = getattr(request, 'LANGUAGE_CODE', settings.LANGUAGE_CODE) my_settings['LANGUAGE_MODE'] = askbot.get_lang_mode() my_settings['MULTILINGUAL'] = askbot.is_multilingual() my_settings['LANGUAGES_DICT'] = dict(getattr(settings, 'LANGUAGES', [])) my_settings['ALLOWED_UPLOAD_FILE_TYPES'] = \ settings.ASKBOT_ALLOWED_UPLOAD_FILE_TYPES my_settings['ASKBOT_URL'] = settings.ASKBOT_URL my_settings['STATIC_URL'] = settings.STATIC_URL my_settings['IP_MODERATION_ENABLED'] = getattr(settings, 'ASKBOT_IP_MODERATION_ENABLED', False) my_settings['USE_LOCAL_FONTS'] = getattr( settings, 'ASKBOT_USE_LOCAL_FONTS', False ) my_settings['CSRF_COOKIE_NAME'] = settings.CSRF_COOKIE_NAME my_settings['DEBUG'] = settings.DEBUG my_settings['USING_RUNSERVER'] = 'runserver' in sys.argv my_settings['ASKBOT_VERSION'] = askbot.get_version() my_settings['LOGIN_URL'] = url_utils.get_login_url() my_settings['LOGOUT_URL'] = url_utils.get_logout_url() if my_settings['EDITOR_TYPE'] == 'tinymce': tinymce_plugins = settings.TINYMCE_DEFAULT_CONFIG.get('plugins', '').split(',') my_settings['TINYMCE_PLUGINS'] = map(lambda v: v.strip(), tinymce_plugins) my_settings['TINYMCE_EDITOR_DESELECTOR'] = settings.TINYMCE_DEFAULT_CONFIG['editor_deselector'] my_settings['TINYMCE_CONFIG_JSON'] = json.dumps(settings.TINYMCE_DEFAULT_CONFIG) else: my_settings['TINYMCE_PLUGINS'] = [] my_settings['TINYMCE_EDITOR_DESELECTOR'] = '' my_settings['LOGOUT_REDIRECT_URL'] = url_utils.get_logout_redirect_url() current_language = get_language() #for some languages we will start searching for shorter words if current_language == 'ja': #we need to open the search box and show info message about #the japanese lang search min_search_word_length = 1 else: min_search_word_length = my_settings['MIN_SEARCH_WORD_LENGTH'] need_scope_links = askbot_settings.ALL_SCOPE_ENABLED or \ askbot_settings.UNANSWERED_SCOPE_ENABLED or \ (request.user.is_authenticated() and askbot_settings.FOLLOWED_SCOPE_ENABLED) context = { 'base_url': site_url(''), 'csrf_token': get_or_create_csrf_token(request), 'empty_search_state': SearchState.get_empty(), 'min_search_word_length': min_search_word_length, 'current_language_code': current_language, 'settings': my_settings, 'moderation_items': api.get_info_on_moderation_items(request.user), 'need_scope_links': need_scope_links, 'noscript_url': const.DEPENDENCY_URLS['noscript'], } use_askbot_login = '******' in settings.INSTALLED_APPS my_settings['USE_ASKBOT_LOGIN_SYSTEM'] = use_askbot_login if use_askbot_login and request.user.is_anonymous(): from askbot.deps.django_authopenid import context as login_context context.update(login_context.login_context(request)) if askbot_settings.GROUPS_ENABLED: #calculate context needed to list all the groups def _get_group_url(group): """calculates url to the group based on its id and name""" group_slug = slugify(group['name']) return reverse( 'users_by_group', kwargs={'group_id': group['id'], 'group_slug': group_slug} ) #load id's and names of all groups global_group = models.Group.objects.get_global_group() groups = models.Group.objects.exclude_personal() groups = groups.exclude(id=global_group.id) groups_data = list(groups.values('id', 'name')) #sort groups_data alphanumerically, but case-insensitive groups_data = sorted( groups_data, lambda x, y: cmp(x['name'].lower(), y['name'].lower()) ) #insert data for the global group at the first position groups_data.insert(0, {'id': global_group.id, 'name': global_group.name}) #build group_list for the context group_list = list() for group in groups_data: link = _get_group_url(group) group_list.append({'name': group['name'], 'link': link}) context['group_list'] = simplejson.dumps(group_list) if askbot_settings.EDITOR_TYPE == 'tinymce': from tinymce.widgets import TinyMCE context['tinymce'] = TinyMCE() return context