def create_users(self): "Create the users and return an array of created users" users = [] #add admin with the same password - this user will be admin automatically admin = User.objects.create_user('admin', '*****@*****.**') admin.set_password('admin') admin.save() self.print_if_verbose("Created User 'admin'") users.append(admin) #this user will have regular privileges, because it's second joe = User.objects.create_user('joe', '*****@*****.**') joe.set_password('joe') joe.save() self.print_if_verbose("Created User 'joe'") # Keeping the created users in array - we will iterate over them # several times, we don't want querying the model each and every time. for i in range(NUM_USERS): s_idx = str(i) username = self.bad_stuff() + USERNAME_TEMPLATE % s_idx user = User.objects.create_user(username, EMAIL_TEMPLATE % s_idx) user.set_password(PASSWORD_TEMPLATE % s_idx) user.receive_reputation(INITIAL_REPUTATION, get_language()) user.save() self.print_if_verbose("Created User '%s'" % user.username) users.append(user) return users
def items(self, item): """get questions for the feed """ if not askbot_settings.RSS_ENABLED: raise Http404 #initial filtering filters = get_content_filter() filters['deleted'] = False filters['language_code'] = get_language() qs = Post.objects.get_questions().filter(**filters) # get search string and tags from GET query = self.request.GET.get("q", None) tags = self.request.GET.getlist("tags") if query: # if there's a search string, use the # question search method qs = qs.get_by_text_query(query) if tags: # if there are tags in GET, filter the # questions additionally for tag in tags: qs = qs.filter(thread__tags__name=tag) return qs.order_by('-thread__last_activity_at')[:30]
def user_reputation(request, user, context): reputes = models.Repute.objects.filter( user=user, language_code=get_language()).select_related('question', 'question__thread', 'user') # prepare data for the graph - last values go in first reputation = const.MIN_REPUTATION rep_list = list() rep_list.append( '[%s, %s]' % (calendar.timegm(user.date_joined.timetuple()) * 1000, reputation)) for rep in reputes.order_by('reputed_at'): reputation += (rep.positive + rep.negative) rep_list.append( '[%s,%s]' % (calendar.timegm(rep.reputed_at.timetuple()) * 1000, reputation)) reps = ','.join(rep_list) reps = '[%s]' % reps data = { 'active_tab': 'users', 'page_class': 'user-profile-page', 'tab_name': 'reputation', 'page_title': _("Profile - User's Karma"), 'reputation': reputes.order_by('-reputed_at')[:100], 'reps': reps } context.update(data) return render(request, 'user_profile/user_reputation.html', context)
def user_reputation(request, user, context): reputes = models.Repute.objects.filter( user=user, language_code=get_language() ).select_related( 'question', 'question__thread', 'user' ) # prepare data for the graph - last values go in first reputation = const.MIN_REPUTATION rep_list = list() rep_list.append('[%s, %s]' % (calendar.timegm(user.date_joined.timetuple()) * 1000, reputation)) for rep in reputes.order_by('reputed_at'): reputation += (rep.positive + rep.negative) rep_list.append('[%s,%s]' % (calendar.timegm(rep.reputed_at.timetuple()) * 1000, reputation)) reps = ','.join(rep_list) reps = '[%s]' % reps data = { 'active_tab':'users', 'page_class': 'user-profile-page', 'tab_name': 'reputation', 'page_title': _("Profile - User's Karma"), 'reputation': reputes.order_by('-reputed_at')[:100], 'reps': reps } context.update(data) return render(request, 'user_profile/user_reputation.html', context)
def items(self, item): """get questions for the feed """ if askbot_settings.RSS_ENABLED is False: raise Http404 #initial filtering filters = {'deleted': False} filters['language_code'] = get_language() if askbot_settings.CONTENT_MODERATION_MODE == 'premoderation': filters['approved'] = True qs = Post.objects.get_questions().filter(**filters) #get search string and tags from GET query = self.request.GET.get("q", None) tags = self.request.GET.getlist("tags") if query: #if there's a search string, use the #question search method qs = qs.get_by_text_query(query) if tags: #if there are tags in GET, filter the #questions additionally for tag in tags: qs = qs.filter(thread__tags__name=tag) return qs.order_by('-thread__last_activity_at')[:30]
def items(self, item): """get questions for the feed """ if askbot_settings.RSS_ENABLED is False: raise Http404 #initial filtering filters = {'deleted': False} filters['language_code'] = get_language() if askbot_settings.CONTENT_MODERATION_MODE == 'premoderation': filters['approved'] = True qs = Post.objects.get_questions().filter(**filters) #get search string and tags from GET query = self.request.GET.get("q", None) tags = self.request.GET.getlist("tags") if query: #if there's a search string, use the #question search method qs = qs.get_by_text_query(query) if tags: #if there are tags in GET, filter the #questions additionally for tag in tags: qs = qs.filter(thread__tags__name = tag) return qs.order_by('-thread__last_activity_at')[:30]
def get_skin(): """retreives the skin environment for a given request (request var is not used at this time)""" skin_name = askbot_settings.ASKBOT_DEFAULT_SKIN skin_name += '-' + get_language() try: return SKINS[skin_name] except KeyError: msg_fmt = 'skin "%s" not found, check value of "ASKBOT_EXTRA_SKINS_DIR"' raise ImproperlyConfigured(msg_fmt % skin_name)
def get_skin(cls): """retreives the skin environment for a given request (request var is not used at this time)""" key = cls.build_sibling_key( [askbot_settings.ASKBOT_DEFAULT_SKIN, get_language()]) try: return cls.siblings[key] except KeyError: msg_fmt = 'skin "%s" not found, check value of "ASKBOT_EXTRA_SKINS_DIR"' raise ImproperlyConfigured(msg_fmt % askbot_settings.ASKBOT_DEFAULT_SKIN)
def run_full_text_search(query_set, query_text, text_search_vector_name): """runs full text search against the query set and the search text. All words in the query text are added to the search with the & operator - i.e. the more terms in search, the narrower it is. It is also assumed that we ar searching in the same table as the query set was built against, also it is assumed that the table has text search vector stored in the column called with value of`text_search_vector_name`. """ original_qs = query_set table_name = query_set.model._meta.db_table rank_clause = 'ts_rank(' + table_name + \ '.' + text_search_vector_name + \ ', plainto_tsquery(%s, %s))' where_clause = table_name + '.' + \ text_search_vector_name + \ ' @@ plainto_tsquery(%s, %s)' language_code = get_language() #a hack with japanese search for the short queries if language_code in ['ja', 'zh-cn'] and len(query_text) in (1, 2): mul = 4/len(query_text) #4 for 1 and 2 for 2 query_text = (query_text + ' ')*mul #the table name is a hack, because user does not have the language code if askbot.is_multilingual() and table_name == 'askbot_thread': where_clause += " AND " + table_name + \ '.' + "language_code='" + language_code + "'" search_query = '|'.join(query_text.split())#apply "OR" operator language_name = LANGUAGE_NAMES.get(language_code, 'english') extra_params = (language_name, search_query,) extra_kwargs = { 'select': {'relevance': rank_clause}, 'where': [where_clause,], 'params': extra_params, 'select_params': extra_params, } result_qs = query_set.extra(**extra_kwargs) #added to allow search that can be ignored by postgres FTS. if not result_qs and len(query_text) < 5: return original_qs.filter( models.Q(title__icontains=search_query) | models.Q(tagnames__icontains=search_query) | models.Q(posts__text__icontains = search_query) ).extra(select={'relevance': rank_clause}, select_params=extra_params) return result_qs
def load_template(self, template_name, template_dirs=None): bits = template_name.split(os.path.sep) #setting JINJA2_TEMPLATES is list of apps using Jinja2 templates jinja2_apps = getattr(django_settings, 'JINJA2_TEMPLATES', None) if jinja2_apps != None and bits[0] not in jinja2_apps: raise TemplateDoesNotExist try: env = APP_DIR_ENVS[get_language()] return env.get_template(template_name), template_name except TemplateNotFound: raise TemplateDoesNotExist
def factory(**options): # JINJA2_EXTENSIONS was a thing in Coffin. We keep it around because it # may be used in Askbot. Should think about deprecating its use. options["extensions"] = DEFAULT_EXTENSIONS \ + list(django_settings.JINJA2_EXTENSIONS) askbot_globals = { 'settings': askbot_settings, 'hasattr': hasattr, 'encode_jwt': encode_jwt } mother_of_all_loaders = options.pop('loader') skins = utils.get_available_skins() if askbot.is_multilingual() or HAS_ASKBOT_LOCALE_MIDDLEWARE: languages = list(dict(django_settings.LANGUAGES).keys()) else: languages = [django_settings.LANGUAGE_CODE] # create an environment for each skin and language we might serve # Jinja2 Environments know a concept called "overlays" which cries for # consideration here. It may greatly simplify loading templatetags ... all_combinations = [(name, lang) for name in skins for lang in languages] for name, lang in all_combinations: skin_basedir = utils.get_path_to_skin(name) options["skin"] = name options["language_code"] = lang options['loader'] = deepcopy(mother_of_all_loaders) options['loader'].searchpath = [f'{skin_basedir}/jinja2' ] + options['loader'].searchpath env = SkinEnvironment(**options) env.globals.update(askbot_globals) env.set_language(lang) load_templatetags() # give Django what it asked for default_sibling = SkinEnvironment.build_sibling_key( [askbot_settings.ASKBOT_DEFAULT_SKIN, get_language()]) return SkinEnvironment.siblings[default_sibling]
def save(self, *args, **kwargs): if self.question: self.language_code = self.question.language_code else: self.language_code = get_language() super(Repute, self).save(*args, **kwargs)
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['MULTILINGUAL'] = getattr(settings, 'ASKBOT_MULTILINGUAL', False) 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['ASKBOT_CSS_DEVEL'] = getattr( settings, 'ASKBOT_CSS_DEVEL', 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() my_settings['USE_ASKBOT_LOGIN_SYSTEM'] = 'askbot.deps.django_authopenid' \ in settings.INSTALLED_APPS 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(''), 'empty_search_state': SearchState.get_empty(), 'min_search_word_length': min_search_word_length, 'current_language_code': current_language, 'settings': my_settings, 'skin': get_skin(), 'moderation_items': api.get_info_on_moderation_items(request.user), 'need_scope_links': need_scope_links, 'noscript_url': const.DEPENDENCY_URLS['noscript'], } 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 show_users(request, by_group=False, group_id=None, group_slug=None): """Users view, including listing of users by group""" if askbot_settings.GROUPS_ENABLED and not by_group: default_group = models.Group.objects.get_global_group() group_slug = slugify(default_group.name) new_url = reverse('users_by_group', kwargs={'group_id': default_group.id, 'group_slug': group_slug}) return HttpResponseRedirect(new_url) users = models.User.objects.exclude( askbot_profile__status='b' ).exclude( is_active=False ).select_related('askbot_profile') if askbot.is_multilingual(): users = users.filter( localized_askbot_profiles__language_code=get_language(), localized_askbot_profiles__is_claimed=True ) group = None group_email_moderation_enabled = False user_acceptance_level = 'closed' user_membership_level = 'none' if by_group == True: if askbot_settings.GROUPS_ENABLED == False: raise Http404 if group_id: if all((group_id, group_slug)) == False: return HttpResponseRedirect('groups') else: try: group = models.Group.objects.get(id = group_id) group_email_moderation_enabled = ( askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED \ and askbot_settings.CONTENT_MODERATION_MODE == 'premoderation' ) user_acceptance_level = group.get_openness_level_for_user( request.user ) except models.Group.DoesNotExist: raise Http404 if group_slug == slugify(group.name): #filter users by full group memberships #todo: refactor as Group.get_full_members() full_level = models.GroupMembership.FULL memberships = models.GroupMembership.objects.filter( group=group, level=full_level ) user_ids = memberships.values_list('user__id', flat=True) users = users.filter(id__in=user_ids) if request.user.is_authenticated(): membership = request.user.get_group_membership(group) if membership: user_membership_level = membership.get_level_display() else: group_page_url = reverse( 'users_by_group', kwargs = { 'group_id': group.id, 'group_slug': slugify(group.name) } ) return HttpResponseRedirect(group_page_url) is_paginated = True form = forms.ShowUsersForm(request.REQUEST) form.full_clean()#always valid sort_method = form.cleaned_data['sort'] page = form.cleaned_data['page'] search_query = form.cleaned_data['query'] if search_query == '': if sort_method == 'newest': order_by_parameter = '-date_joined' elif sort_method == 'last': order_by_parameter = 'date_joined' elif sort_method == 'name': order_by_parameter = 'username' else: # default if askbot.is_multilingual(): order_by_parameter = '-localized_askbot_profiles__reputation' else: order_by_parameter = '-askbot_profile__reputation' objects_list = Paginator( users.order_by(order_by_parameter), askbot_settings.USERS_PAGE_SIZE ) base_url = request.path + '?sort=%s&' % sort_method else: sort_method = 'reputation' matching_users = models.get_users_by_text_query(search_query, users) objects_list = Paginator( matching_users.order_by('-askbot_profile__reputation'), askbot_settings.USERS_PAGE_SIZE ) base_url = request.path + '?name=%s&sort=%s&' % (search_query, sort_method) try: users_page = objects_list.page(page) except (EmptyPage, InvalidPage): users_page = objects_list.page(objects_list.num_pages) paginator_data = { 'is_paginated' : is_paginated, 'pages': objects_list.num_pages, 'current_page_number': page, 'page_object': users_page, 'base_url' : base_url } paginator_context = functions.setup_paginator(paginator_data) # #todo: move to contexts #extra context for the groups if askbot_settings.GROUPS_ENABLED: #todo: cleanup this branched code after groups are migrated to auth_group user_groups = models.Group.objects.exclude_personal() if len(user_groups) <= 1: assert(user_groups[0].name == askbot_settings.GLOBAL_GROUP_NAME) user_groups = None group_openness_choices = models.Group().get_openness_choices() else: user_groups = None group_openness_choices = None data = { 'active_tab': 'users', 'group': group, 'group_email_moderation_enabled': group_email_moderation_enabled, 'group_openness_choices': group_openness_choices, 'page_class': 'users-page', 'paginator_context' : paginator_context, 'search_query' : search_query, 'tab_id' : sort_method, 'user_acceptance_level': user_acceptance_level, 'user_count': objects_list.count, 'user_groups': user_groups, 'user_membership_level': user_membership_level, 'users' : users_page, } return render(request, 'users.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'] = [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
def user_stats(request, user, context): question_filter = {} if request.user != user: question_filter['is_anonymous'] = False if askbot_settings.CONTENT_MODERATION_MODE == 'premoderation': question_filter['approved'] = True # # Questions # questions_qs = user.posts.get_questions( user=request.user ).filter( **question_filter ).order_by( '-points', '-thread__last_activity_at' ).select_related( 'thread', 'thread__last_activity_by' ) q_paginator = Paginator(questions_qs, const.USER_POSTS_PAGE_SIZE) questions = q_paginator.page(1).object_list question_count = q_paginator.count q_paginator_context = functions.setup_paginator({ 'is_paginated' : (question_count > const.USER_POSTS_PAGE_SIZE), 'pages': q_paginator.num_pages, 'current_page_number': 1, 'page_object': q_paginator.page(1), 'base_url' : '?' #this paginator will be ajax }) # # Top answers # a_paginator = user.get_top_answers_paginator(request.user) top_answers = a_paginator.page(1).object_list top_answer_count = a_paginator.count a_paginator_context = functions.setup_paginator({ 'is_paginated' : (top_answer_count > const.USER_POSTS_PAGE_SIZE), 'pages': a_paginator.num_pages, 'current_page_number': 1, 'page_object': a_paginator.page(1), 'base_url' : '?' #this paginator will be ajax }) # # Votes # up_votes = models.Vote.objects.get_up_vote_count_from_user(user) down_votes = models.Vote.objects.get_down_vote_count_from_user(user) votes_today = models.Vote.objects.get_votes_count_today_from_user(user) votes_total = askbot_settings.MAX_VOTES_PER_USER_PER_DAY # # Tags # # INFO: There's bug in Django that makes the following query kind of broken (GROUP BY clause is problematic): # http://stackoverflow.com/questions/7973461/django-aggregation-does-excessive-group-by-clauses # Fortunately it looks like it returns correct results for the test data user_tags = models.Tag.objects.filter( threads__posts__author=user, language_code=get_language() ).distinct().\ annotate(user_tag_usage_count=Count('threads')).\ order_by('-user_tag_usage_count')[:const.USER_VIEW_DATA_SIZE] user_tags = list(user_tags) # evaluate when = askbot_settings.MARKED_TAGS_ARE_PUBLIC_WHEN if when == 'always' or \ (when == 'when-user-wants' and user.show_marked_tags == True): #refactor into: user.get_marked_tag_names('good'/'bad'/'subscribed') interesting_tag_names = user.get_marked_tag_names('good') ignored_tag_names = user.get_marked_tag_names('bad') subscribed_tag_names = user.get_marked_tag_names('subscribed') else: interesting_tag_names = None ignored_tag_names = None subscribed_tag_names = None # tags = models.Post.objects.filter(author=user).values('id', 'thread', 'thread__tags') # post_ids = set() # thread_ids = set() # tag_ids = set() # for t in tags: # post_ids.add(t['id']) # thread_ids.add(t['thread']) # tag_ids.add(t['thread__tags']) # if t['thread__tags'] == 11: # print t['thread'], t['id'] # import ipdb; ipdb.set_trace() # # Badges/Awards (TODO: refactor into Managers/QuerySets when a pattern emerges; Simplify when we get rid of Question&Answer models) # post_type = ContentType.objects.get_for_model(models.Post) user_awards = models.Award.objects.filter(user=user).select_related('badge') awarded_post_ids = [] for award in user_awards: if award.content_type_id == post_type.id: awarded_post_ids.append(award.object_id) awarded_posts = models.Post.objects.filter(id__in=awarded_post_ids)\ .select_related('thread') # select related to avoid additional queries in Post.get_absolute_url() awarded_posts_map = {} for post in awarded_posts: awarded_posts_map[post.id] = post badges_dict = collections.defaultdict(list) for award in user_awards: if award.badge.is_enabled() == False: continue # Fetch content object if award.content_type_id == post_type.id: #here we go around a possibility of awards #losing the content objects when the content #objects are deleted for some reason awarded_post = awarded_posts_map.get(award.object_id, None) if awarded_post is not None: #protect from awards that are associated with deleted posts award.content_object = awarded_post award.content_object_is_post = True else: award.content_object_is_post = False else: award.content_object_is_post = False # "Assign" to its Badge badges_dict[award.badge].append(award) badges = badges_dict.items() badges.sort(key=operator.itemgetter(1), reverse=True) user_groups = models.Group.objects.get_for_user(user = user) user_groups = user_groups.exclude_personal() global_group = models.Group.objects.get_global_group() user_groups = user_groups.exclude(name=global_group.name) if request.user.pk == user.pk: groups_membership_info = user.get_groups_membership_info(user_groups) else: groups_membership_info = collections.defaultdict() show_moderation_warning = (request.user.is_authenticated() and request.user.pk == user.pk and (user.is_watched() or user.is_blocked()) and (user.get_localized_profile().about or user.website) ) show_profile_info = ((not (user.is_watched() or user.is_blocked())) or (request.user.is_authenticated() and (request.user.is_administrator_or_moderator() or user.pk == request.user.pk ) ) ) data = { 'active_tab':'users', 'page_class': 'user-profile-page', 'support_custom_avatars': ('avatar' in django_settings.INSTALLED_APPS), 'show_moderation_warning': show_moderation_warning, 'show_profile_info': show_profile_info, 'tab_name' : 'stats', 'page_title' : _('user profile overview'), 'questions' : questions, 'question_count': question_count, 'q_paginator_context': q_paginator_context, 'top_answers': top_answers, 'top_answer_count': top_answer_count, 'a_paginator_context': a_paginator_context, 'page_size': const.USER_POSTS_PAGE_SIZE, 'up_votes' : up_votes, 'down_votes' : down_votes, 'total_votes': up_votes + down_votes, 'votes_today_left': votes_total - votes_today, 'votes_total_per_day': votes_total, 'user_tags' : user_tags, 'user_groups': user_groups, 'groups_membership_info': groups_membership_info, 'interesting_tag_names': interesting_tag_names, 'ignored_tag_names': ignored_tag_names, 'subscribed_tag_names': subscribed_tag_names, 'badges': badges, 'total_badges' : len(badges), } context.update(data) extra_context = view_context.get_extra( 'ASKBOT_USER_PROFILE_PAGE_EXTRA_CONTEXT', request, context ) context.update(extra_context) return render(request, 'user_profile/user_stats.html', context)
def user_stats(request, user, context): question_filter = {} if request.user != user: question_filter['is_anonymous'] = False if askbot_settings.CONTENT_MODERATION_MODE == 'premoderation': question_filter['approved'] = True # # Questions # questions_qs = user.posts.get_questions( user=request.user).filter(**question_filter).order_by( '-points', '-thread__last_activity_at').select_related( 'thread', 'thread__last_activity_by') q_paginator = Paginator(questions_qs, const.USER_POSTS_PAGE_SIZE) questions = q_paginator.page(1).object_list question_count = q_paginator.count q_paginator_context = functions.setup_paginator({ 'is_paginated': (question_count > const.USER_POSTS_PAGE_SIZE), 'pages': q_paginator.num_pages, 'current_page_number': 1, 'page_object': q_paginator.page(1), 'base_url': '?' #this paginator will be ajax }) # # Top answers # a_paginator = user.get_top_answers_paginator(request.user) top_answers = a_paginator.page(1).object_list top_answer_count = a_paginator.count a_paginator_context = functions.setup_paginator({ 'is_paginated': (top_answer_count > const.USER_POSTS_PAGE_SIZE), 'pages': a_paginator.num_pages, 'current_page_number': 1, 'page_object': a_paginator.page(1), 'base_url': '?' #this paginator will be ajax }) # # Votes # up_votes = models.Vote.objects.get_up_vote_count_from_user(user) down_votes = models.Vote.objects.get_down_vote_count_from_user(user) votes_today = models.Vote.objects.get_votes_count_today_from_user(user) votes_total = askbot_settings.MAX_VOTES_PER_USER_PER_DAY # # Tags # # INFO: There's bug in Django that makes the following query kind of broken (GROUP BY clause is problematic): # http://stackoverflow.com/questions/7973461/django-aggregation-does-excessive-group-by-clauses # Fortunately it looks like it returns correct results for the test data user_tags = models.Tag.objects.filter( threads__posts__author=user, language_code=get_language() ).distinct().\ annotate(user_tag_usage_count=Count('threads')).\ order_by('-user_tag_usage_count')[:const.USER_VIEW_DATA_SIZE] user_tags = list(user_tags) # evaluate when = askbot_settings.MARKED_TAGS_ARE_PUBLIC_WHEN if when == 'always' or \ (when == 'when-user-wants' and user.show_marked_tags == True): #refactor into: user.get_marked_tag_names('good'/'bad'/'subscribed') interesting_tag_names = user.get_marked_tag_names('good') ignored_tag_names = user.get_marked_tag_names('bad') subscribed_tag_names = user.get_marked_tag_names('subscribed') else: interesting_tag_names = None ignored_tag_names = None subscribed_tag_names = None # tags = models.Post.objects.filter(author=user).values('id', 'thread', 'thread__tags') # post_ids = set() # thread_ids = set() # tag_ids = set() # for t in tags: # post_ids.add(t['id']) # thread_ids.add(t['thread']) # tag_ids.add(t['thread__tags']) # if t['thread__tags'] == 11: # print t['thread'], t['id'] # import ipdb; ipdb.set_trace() # # Badges/Awards (TODO: refactor into Managers/QuerySets when a pattern emerges; Simplify when we get rid of Question&Answer models) # post_type = ContentType.objects.get_for_model(models.Post) user_awards = models.Award.objects.filter( user=user).select_related('badge') awarded_post_ids = [] for award in user_awards: if award.content_type_id == post_type.id: awarded_post_ids.append(award.object_id) awarded_posts = models.Post.objects.filter(id__in=awarded_post_ids)\ .select_related('thread') # select related to avoid additional queries in Post.get_absolute_url() awarded_posts_map = {} for post in awarded_posts: awarded_posts_map[post.id] = post badges_dict = collections.defaultdict(list) for award in user_awards: if award.badge.is_enabled() == False: continue # Fetch content object if award.content_type_id == post_type.id: #here we go around a possibility of awards #losing the content objects when the content #objects are deleted for some reason awarded_post = awarded_posts_map.get(award.object_id, None) if awarded_post is not None: #protect from awards that are associated with deleted posts award.content_object = awarded_post award.content_object_is_post = True else: award.content_object_is_post = False else: award.content_object_is_post = False # "Assign" to its Badge badges_dict[award.badge].append(award) badges = badges_dict.items() badges.sort(key=operator.itemgetter(1), reverse=True) user_groups = models.Group.objects.get_for_user(user=user) user_groups = user_groups.exclude_personal() global_group = models.Group.objects.get_global_group() user_groups = user_groups.exclude(name=global_group.name) if request.user.pk == user.pk: groups_membership_info = user.get_groups_membership_info(user_groups) else: groups_membership_info = collections.defaultdict() show_moderation_warning = (request.user.is_authenticated() and request.user.pk == user.pk and (user.is_watched() or user.is_blocked()) and (user.get_localized_profile().about or user.website)) show_profile_info = ((not (user.is_watched() or user.is_blocked())) or (request.user.is_authenticated() and (request.user.is_administrator_or_moderator() or user.pk == request.user.pk))) data = { 'active_tab': 'users', 'page_class': 'user-profile-page', 'support_custom_avatars': ('avatar' in django_settings.INSTALLED_APPS), 'show_moderation_warning': show_moderation_warning, 'show_profile_info': show_profile_info, 'tab_name': 'stats', 'page_title': _('user profile overview'), 'questions': questions, 'question_count': question_count, 'q_paginator_context': q_paginator_context, 'top_answers': top_answers, 'top_answer_count': top_answer_count, 'a_paginator_context': a_paginator_context, 'page_size': const.USER_POSTS_PAGE_SIZE, 'up_votes': up_votes, 'down_votes': down_votes, 'total_votes': up_votes + down_votes, 'votes_today_left': votes_total - votes_today, 'votes_total_per_day': votes_total, 'user_tags': user_tags, 'user_groups': user_groups, 'groups_membership_info': groups_membership_info, 'interesting_tag_names': interesting_tag_names, 'ignored_tag_names': ignored_tag_names, 'subscribed_tag_names': subscribed_tag_names, 'badges': badges, 'total_badges': len(badges), } context.update(data) extra_context = view_context.get_extra( 'ASKBOT_USER_PROFILE_PAGE_EXTRA_CONTEXT', request, context) context.update(extra_context) return render(request, 'user_profile/user_stats.html', context)
def show_users(request, by_group=False, group_id=None, group_slug=None): """Users view, including listing of users by group""" if askbot_settings.GROUPS_ENABLED and not by_group: default_group = models.Group.objects.get_global_group() group_slug = slugify(default_group.name) new_url = reverse('users_by_group', kwargs={ 'group_id': default_group.id, 'group_slug': group_slug }) return HttpResponseRedirect(new_url) users = models.User.objects.exclude(askbot_profile__status='b').exclude( is_active=False).select_related('askbot_profile') if askbot.is_multilingual(): users = users.filter( localized_askbot_profiles__language_code=get_language(), localized_askbot_profiles__is_claimed=True) group = None group_email_moderation_enabled = False user_acceptance_level = 'closed' user_membership_level = 'none' if by_group == True: if askbot_settings.GROUPS_ENABLED == False: raise Http404 if group_id: if all((group_id, group_slug)) == False: return HttpResponseRedirect('groups') else: try: group = models.Group.objects.get(id=group_id) group_email_moderation_enabled = ( askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED \ and askbot_settings.CONTENT_MODERATION_MODE == 'premoderation' ) user_acceptance_level = group.get_openness_level_for_user( request.user) except models.Group.DoesNotExist: raise Http404 if group_slug == slugify(group.name): #filter users by full group memberships #todo: refactor as Group.get_full_members() full_level = models.GroupMembership.FULL memberships = models.GroupMembership.objects.filter( group=group, level=full_level) user_ids = memberships.values_list('user__id', flat=True) users = users.filter(id__in=user_ids) if request.user.is_authenticated(): membership = request.user.get_group_membership(group) if membership: user_membership_level = membership.get_level_display( ) else: group_page_url = reverse('users_by_group', kwargs={ 'group_id': group.id, 'group_slug': slugify(group.name) }) return HttpResponseRedirect(group_page_url) is_paginated = True form = forms.ShowUsersForm(request.REQUEST) form.full_clean() #always valid sort_method = form.cleaned_data['sort'] page = form.cleaned_data['page'] search_query = form.cleaned_data['query'] if search_query == '': if sort_method == 'newest': order_by_parameter = '-date_joined' elif sort_method == 'last': order_by_parameter = 'date_joined' elif sort_method == 'name': order_by_parameter = 'username' else: # default if askbot.is_multilingual(): order_by_parameter = '-localized_askbot_profiles__reputation' else: order_by_parameter = '-askbot_profile__reputation' objects_list = Paginator(users.order_by(order_by_parameter), askbot_settings.USERS_PAGE_SIZE) base_url = request.path + '?sort=%s&' % sort_method else: sort_method = 'reputation' matching_users = models.get_users_by_text_query(search_query, users) objects_list = Paginator( matching_users.order_by('-askbot_profile__reputation'), askbot_settings.USERS_PAGE_SIZE) base_url = request.path + '?name=%s&sort=%s&' % (search_query, sort_method) try: users_page = objects_list.page(page) except (EmptyPage, InvalidPage): users_page = objects_list.page(objects_list.num_pages) paginator_data = { 'is_paginated': is_paginated, 'pages': objects_list.num_pages, 'current_page_number': page, 'page_object': users_page, 'base_url': base_url } paginator_context = functions.setup_paginator(paginator_data) # #todo: move to contexts #extra context for the groups if askbot_settings.GROUPS_ENABLED: #todo: cleanup this branched code after groups are migrated to auth_group user_groups = models.Group.objects.exclude_personal() if len(user_groups) <= 1: assert (user_groups[0].name == askbot_settings.GLOBAL_GROUP_NAME) user_groups = None group_openness_choices = models.Group().get_openness_choices() else: user_groups = None group_openness_choices = None data = { 'active_tab': 'users', 'group': group, 'group_email_moderation_enabled': group_email_moderation_enabled, 'group_openness_choices': group_openness_choices, 'page_class': 'users-page', 'paginator_context': paginator_context, 'search_query': search_query, 'tab_id': sort_method, 'user_acceptance_level': user_acceptance_level, 'user_count': objects_list.count, 'user_groups': user_groups, 'user_membership_level': user_membership_level, 'users': users_page, } return render(request, 'users.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["MULTILINGUAL"] = getattr(settings, "ASKBOT_MULTILINGUAL", False) 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["ASKBOT_CSS_DEVEL"] = getattr(settings, "ASKBOT_CSS_DEVEL", 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() my_settings["USE_ASKBOT_LOGIN_SYSTEM"] = "askbot.deps.django_authopenid" in settings.INSTALLED_APPS 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"] context = { "base_url": site_url(""), "min_search_word_length": min_search_word_length, "current_language_code": current_language, "settings": my_settings, "skin": get_skin(), "moderation_items": api.get_info_on_moderation_items(request.user), "noscript_url": const.DEPENDENCY_URLS["noscript"], } 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 get_bulk_cache_key(): from askbot.utils.translation import get_language return 'askbot-settings-' + get_language()