diff options
-rw-r--r-- | askbot/doc/source/changelog.rst | 1 | ||||
-rw-r--r-- | askbot/doc/source/management-commands.rst | 2 | ||||
-rw-r--r-- | askbot/forms.py | 64 | ||||
-rw-r--r-- | askbot/management/commands/askbot_add_test_content.py | 228 | ||||
-rw-r--r-- | askbot/skins/common/templates/authopenid/signup_with_password.html | 2 | ||||
-rw-r--r-- | askbot/skins/default/media/style/style.css | 22 | ||||
-rw-r--r-- | askbot/skins/default/media/style/style.less | 4 | ||||
-rw-r--r-- | askbot/skins/default/templates/feedback.html | 24 | ||||
-rw-r--r-- | askbot/skins/default/templates/macros.html | 2 | ||||
-rw-r--r-- | askbot/skins/default/templates/user_profile/user_stats.html | 2 | ||||
-rw-r--r-- | askbot/views/meta.py | 18 | ||||
-rw-r--r-- | askbot/views/users.py | 58 |
12 files changed, 375 insertions, 52 deletions
diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index 0ba88155..31b21813 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -21,6 +21,7 @@ Development version (not yet published) * Added support for LOGIN_REDIRECT_URL to the login app (hjwp, Evgeny) * Updated Italian localization (Luca Ferroni) * Added Catalan localization (Jordi Bofill) +* Added management command ``askbot_add_test_content`` (Dejan Noveski) 0.7.26 (Current Version) ------------------------ diff --git a/askbot/doc/source/management-commands.rst b/askbot/doc/source/management-commands.rst index d69c8673..b1ee5bc5 100644 --- a/askbot/doc/source/management-commands.rst +++ b/askbot/doc/source/management-commands.rst @@ -175,3 +175,5 @@ the developers of the Askbot project: | | remaining commands that are expected to be run from the | | | site root directory. | +--------------------------------+-------------------------------------------------------------+ +| `askbot_add_test_content` | Creates content with dummy data for testing | ++--------------------------------+-------------------------------------------------------------+ diff --git a/askbot/forms.py b/askbot/forms.py index 0769f180..241a52f9 100644 --- a/askbot/forms.py +++ b/askbot/forms.py @@ -43,7 +43,7 @@ def clean_marked_tagnames(tagnames): wildcards.append(tagname) else: pure_tags.append(tagname) - + return pure_tags, wildcards def filter_choices(remove_choices = None, from_choices = None): @@ -75,7 +75,7 @@ COUNTRY_CHOICES = (('unknown',_('select country')),) + countries.COUNTRIES class CountryField(forms.ChoiceField): """this is better placed into the django_coutries app""" - + def __init__(self, *args, **kwargs): """sets label and the country choices """ @@ -253,7 +253,7 @@ class SummaryField(forms.CharField): class DumpUploadForm(forms.Form): """This form handles importing - data into the forum. At the moment it only + data into the forum. At the moment it only supports stackexchange import. """ dump_file = forms.FileField() @@ -397,7 +397,7 @@ class ChangeUserStatusForm(forms.Form): self.fields['user_status'].choices = user_status_choices #set prompt option as default - self.fields['user_status'].default = 'select' + self.fields['user_status'].default = 'select' self.moderator = moderator self.subject = subject @@ -539,11 +539,41 @@ class NotARobotForm(forms.Form): ) class FeedbackForm(forms.Form): - name = forms.CharField(label=_('Your name:'), required=False) - email = forms.EmailField(label=_('Email (not shared with anyone):'), required=False) - message = forms.CharField(label=_('Your message:'), max_length=800,widget=forms.Textarea(attrs={'cols':60})) + name = forms.CharField(label=_('Your name (optional):'), required=False) + email = forms.EmailField(label=_('Email:'), required=False) + message = forms.CharField( + label=_('Your message:'), + max_length=800, + widget=forms.Textarea(attrs={'cols':60}) + ) + no_email = forms.BooleanField( + label=_("I don't want to give my email or receive a response:"), + required=False + ) next = NextUrlField() + def __init__(self, is_auth=False, *args, **kwargs): + super(FeedbackForm, self).__init__(*args, **kwargs) + self.is_auth = is_auth + if not is_auth: + if askbot_settings.USE_RECAPTCHA: + self._add_recaptcha_field() + + def _add_recaptcha_field(self): + self.fields['recaptcha'] = RecaptchaField( + private_key = askbot_settings.RECAPTCHA_SECRET, + public_key = askbot_settings.RECAPTCHA_KEY + ) + + def clean(self): + super(FeedbackForm, self).clean() + if not self.is_auth: + if not self.cleaned_data['no_email'] and not self.cleaned_data['email']: + msg = _('Please mark "I dont want to give my mail" field.') + self._errors['email'] = self.error_class([msg]) + + return self.cleaned_data + class FormWithHideableFields(object): """allows to swap a field widget to HiddenInput() and back""" @@ -567,7 +597,7 @@ class FormWithHideableFields(object): class AskForm(forms.Form, FormWithHideableFields): """the form used to askbot questions - field ask_anonymously is shown to the user if the + field ask_anonymously is shown to the user if the if ALLOW_ASK_ANONYMOUSLY live setting is True however, for simplicity, the value will always be present in the cleaned data, and will evaluate to False if the @@ -600,7 +630,7 @@ class AskForm(forms.Form, FormWithHideableFields): """ if askbot_settings.ALLOW_ASK_ANONYMOUSLY == False: self.cleaned_data['ask_anonymously'] = False - return self.cleaned_data['ask_anonymously'] + return self.cleaned_data['ask_anonymously'] class AskByEmailForm(forms.Form): @@ -860,16 +890,16 @@ class EditUserForm(forms.Form): ) realname = forms.CharField( - label=_('Real name'), - required=False, - max_length=255, + label=_('Real name'), + required=False, + max_length=255, widget=forms.TextInput(attrs={'size' : 35}) ) website = forms.URLField( - label=_('Website'), - required=False, - max_length=255, + label=_('Website'), + required=False, + max_length=255, widget=forms.TextInput(attrs={'size' : 35}) ) @@ -957,7 +987,7 @@ class TagFilterSelectionForm(forms.ModelForm): if before != after: return True return False - + class EmailFeedSettingField(forms.ChoiceField): def __init__(self, *arg, **kwarg): @@ -1086,7 +1116,7 @@ class SimpleEmailSubscribeForm(forms.Form): ('n',_('no community email please, thanks')) ) subscribe = forms.ChoiceField( - widget=forms.widgets.RadioSelect, + widget=forms.widgets.RadioSelect, error_messages={'required':_('please choose one of the options above')}, choices=SIMPLE_SUBSCRIBE_CHOICES ) diff --git a/askbot/management/commands/askbot_add_test_content.py b/askbot/management/commands/askbot_add_test_content.py new file mode 100644 index 00000000..eb29d1c5 --- /dev/null +++ b/askbot/management/commands/askbot_add_test_content.py @@ -0,0 +1,228 @@ +from django.core.management.base import NoArgsCommand +from askbot.models import User + + +NUM_USERS = 40 +# KEEP NEXT 3 SETTINGS LESS THAN OR EQUAL TO NUM_USERS! +NUM_QUESTIONS = 40 +NUM_ANSWERS = 20 +NUM_COMMENTS = 20 + +# To ensure that all the actions can be made, repute each user high positive +# karma. This can be calculated dynamically - max of MIN_REP_TO_... settings +INITIAL_REPUTATION = 500 + +# Defining template inputs. +USERNAME_TEMPLATE = "test_user_%s" +PASSWORD_TEMPLATE = "test_password_%s" +EMAIL_TEMPLATE = "test_user_%s@askbot.org" +TITLE_TEMPLATE = "Test question title No.%s" +TAGS_TEMPLATE = ["tag-%s-0", "tag-%s-1"] # len(TAGS_TEMPLATE) tags per question + +CONTENT_TEMPLATE = """Lorem lean startup ipsum product market fit customer + development acquihire technical cofounder. User engagement + **A/B** testing *shrink* a market venture capital pitch.""" + +ANSWER_TEMPLATE = """Accelerator photo sharing business school drop out ramen + hustle crush it revenue traction platforms.""" + +COMMENT_TEMPLATE = """Main differentiators business model micro economics + marketplace equity augmented reality human computer""" + + +class Command(NoArgsCommand): + + def print_if_verbose(self, text): + "Only print if user chooses verbose output" + if self.verbosity > 0: + print text + + def create_users(self): + "Create the users and return an array of created users" + users = [] + + # 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) + user = User.objects.create_user(USERNAME_TEMPLATE % s_idx, + EMAIL_TEMPLATE % s_idx) + user.set_password(PASSWORD_TEMPLATE % s_idx) + user.reputation = INITIAL_REPUTATION + user.save() + self.print_if_verbose("Created User '%s'" % user.username) + users.append(user) + return users + + + def create_questions(self, users): + "Create the questions and return the last one as active question" + + # Keeping the last active question entry for later use. Questions API + # might change, so we rely solely on User data entry API. + active_question = None + last_vote = False + # Each user posts a question + for user in users[:NUM_QUESTIONS]: + # Downvote/upvote the questions - It's reproducible, yet + # gives good randomized data + if not active_question is None: + if last_vote: + user.downvote(active_question) + self.print_if_verbose("%s downvoted a question"%( + user.username + )) + else: + user.upvote(active_question) + self.print_if_verbose("%s upvoted a question"%( + user.username + )) + last_vote = ~last_vote + + # len(TAGS_TEMPLATE) tags per question - each tag is different + tags = " ".join([t%user.id for t in TAGS_TEMPLATE]) + active_question = user.post_question( + title = TITLE_TEMPLATE % user.id, + body_text = CONTENT_TEMPLATE, + tags = tags, + ) + self.print_if_verbose("Created Question '%s' with tags: '%s'" % ( + active_question.title, tags,) + ) + return active_question + + + def create_answers(self, users, active_question): + "Create the answers for the active question, return the active answer" + active_answer = None + last_vote = False + # Now, fill the last added question with answers + for user in users[:NUM_ANSWERS]: + # We don't need to test for data validation, so ONLY users + # that aren't authors can post answer to the question + if not active_question.author is user: + # Downvote/upvote the answers - It's reproducible, yet + # gives good randomized data + if not active_answer is None: + if last_vote: + user.downvote(active_answer) + self.print_if_verbose("%s downvoted an answer"%( + user.username + )) + else: + user.upvote(active_answer) + self.print_if_verbose("%s upvoted an answer"%( + user.username + )) + last_vote = ~last_vote + + active_answer = user.post_answer( + question = active_question, + body_text = ANSWER_TEMPLATE, + follow = True + ) + self.print_if_verbose("%s posted an answer to the active question"%( + user.username + )) + # Upvote the active question + user.upvote(active_question) + # Follow the active question + user.follow_question(active_question) + self.print_if_verbose("%s followed the active question"%( + user.username) + ) + # Subscribe to the active question + user.subscribe_for_followed_question_alerts() + self.print_if_verbose("%s subscribed to followed questions"%( + user.username) + ) + return active_answer + + + def create_comments(self, users, active_question, active_answer): + """Create the comments for the active question and the active answer, + return 2 active comments - 1 question comment and 1 answer comment""" + + active_question_comment = None + active_answer_comment = None + + for user in users[:NUM_COMMENTS]: + active_question_comment = user.post_comment( + parent_post = active_question, + body_text = COMMENT_TEMPLATE + ) + self.print_if_verbose("%s posted a question comment"%user.username) + active_answer_comment = user.post_comment( + parent_post = active_answer, + body_text = COMMENT_TEMPLATE + ) + self.print_if_verbose("%s posted an answer comment"%user.username) + + # Upvote the active answer + user.upvote(active_answer) + + # Upvote active comments + if active_question_comment and active_answer_comment: + num_upvotees = NUM_COMMENTS - 1 + for user in users[:num_upvotees]: + user.upvote(active_question_comment) + user.upvote(active_answer_comment) + + return active_question_comment, active_answer_comment + + + def handle_noargs(self, **options): + + self.verbosity = int(options.get("verbosity", 1)) + + # Create Users + users = self.create_users() + + # Create Questions, vote for questions + active_question = self.create_questions(users) + + # Create Answers, vote for the answers, vote for the active question + # vote for the active answer + active_answer = self.create_answers(users, active_question) + + # Create Comments, vote for the active answer + active_question_comment, active_answer_comment = self.create_comments( + users, active_question, active_answer) + + # Edit the active question, answer and comments + active_question.author.edit_question( + question = active_question, + title = TITLE_TEMPLATE % "EDITED", + body_text = CONTENT_TEMPLATE, + revision_comment = "EDITED", + force = True + ) + self.print_if_verbose("User has edited the active question") + + active_answer.author.edit_answer( + answer = active_answer, + body_text = COMMENT_TEMPLATE, + force = True + ) + self.print_if_verbose("User has edited the active answer") + + active_answer_comment.user.edit_comment( + comment = active_answer_comment, + body_text = ANSWER_TEMPLATE + ) + self.print_if_verbose("User has edited the active answer comment") + + active_question_comment.user.edit_comment( + comment = active_question_comment, + body_text = ANSWER_TEMPLATE + ) + self.print_if_verbose("User has edited the active question comment") + + # Accept best answer + active_question.author.accept_best_answer( + answer = active_answer, + force = True, + ) + self.print_if_verbose("User has accepted a best answer") + + self.print_if_verbose("DONE") diff --git a/askbot/skins/common/templates/authopenid/signup_with_password.html b/askbot/skins/common/templates/authopenid/signup_with_password.html index 43571c20..9911facf 100644 --- a/askbot/skins/common/templates/authopenid/signup_with_password.html +++ b/askbot/skins/common/templates/authopenid/signup_with_password.html @@ -7,7 +7,7 @@ {% endblock %} {% block content %} {% if settings.PASSWORD_REGISTER_SHOW_PROVIDER_BUTTONS == True %} - <h1>{% trans %}Please register by clicking on any of the icons below{% endtrans %}</h1> + <h1 class="section-title">{% trans %}Please register by clicking on any of the icons below{% endtrans %}</h1> <form id="signin-form" method="post" action="{{ settings.LOGIN_URL }}">{% csrf_token %} {# hide_local_login == True because it is password reg form #} {{ diff --git a/askbot/skins/default/media/style/style.css b/askbot/skins/default/media/style/style.css index ba5875ad..a1ac17d8 100644 --- a/askbot/skins/default/media/style/style.css +++ b/askbot/skins/default/media/style/style.css @@ -142,6 +142,10 @@ h1 { font-size: 24px; padding: 10px 0 5px 0px; } +/* ----- Extra space above for messages ----- */ +body.user-messages { + margin-top: 2.4em; +} /* ----- Custom positions ----- */ .left { float: left; @@ -453,6 +457,8 @@ h1 { width: 200px; /* widgets for question template */ + /* notify by email box */ + } .box p { margin-bottom: 4px; @@ -596,6 +602,9 @@ h1 { color: #777; text-align: center; } +.box .notify-sidebar #question-subscribe-sidebar { + margin: 7px 0 0 3px; +} .statsWidget p { color: #707070; font-size: 16px; @@ -1875,7 +1884,16 @@ span.delete-icon:hover { .users-page #id_email, .openid-signin #id_name, .meta #id_name, -.users-page #id_name { +.users-page #id_name, +.openid-signin #id_username, +.meta #id_username, +.users-page #id_username, +.openid-signin #id_password1, +.meta #id_password1, +.users-page #id_password1, +.openid-signin #id_password2, +.meta #id_password2, +.users-page #id_password2 { border: #cce6ec 3px solid; height: 25px; padding-left: 5px; @@ -1894,7 +1912,7 @@ span.delete-icon:hover { border: 0; color: #4a757f; font-weight: bold; - font-size: 12px; + font-size: 16px; height: 24px; margin-top: -2px; cursor: pointer; diff --git a/askbot/skins/default/media/style/style.less b/askbot/skins/default/media/style/style.less index 543b6157..71e2fc36 100644 --- a/askbot/skins/default/media/style/style.less +++ b/askbot/skins/default/media/style/style.less @@ -2055,7 +2055,7 @@ span.delete-icon:hover { padding-left:0px; font-size:16px; } - #id_email,#id_name{ + #id_email,#id_name,#id_username,#id_password1,#id_password2{ border:#cce6ec 3px solid; height:25px; padding-left:5px; @@ -2074,7 +2074,7 @@ span.delete-icon:hover { border:0; color:@button-label; font-weight:bold; - font-size:12px; + font-size:16px; height:24px; margin-top:-2px; cursor:pointer; diff --git a/askbot/skins/default/templates/feedback.html b/askbot/skins/default/templates/feedback.html index 60ea2fca..85b5d00a 100644 --- a/askbot/skins/default/templates/feedback.html +++ b/askbot/skins/default/templates/feedback.html @@ -3,6 +3,11 @@ {% block title %}{% spaceless %}{% trans %}Feedback{% endtrans %}{% endspaceless %}{% endblock %} {% block content %} <h1 class="section-title">{% trans %}Give us your feedback!{% endtrans %}</h1> +{% if form.errors %} +<span class="error"> + {{form.errors.__all__}} +</span> +{%endif%} <form method="post" action="{% url feedback %}" accept-charset="utf-8">{% csrf_token %} {% if user.is_authenticated() %} <p class="message"> @@ -22,10 +27,18 @@ <div class="form-row"> <label>{{form.email.label}} {% if form.errors.email %} - <span class='error'>{% trans %}(please enter a valid email){% endtrans %}</span> + <span class='error'>{% trans %}(to hear from us please enter a valid email or check the box below){% endtrans %}</span> {% endif %} </label><br/>{{form.email}} </div> + <div class="form-row"> + <label>{{form.no_email.label}} + {% if form.errors.no_email %} + <span class="error">{% trans %}(this field is required){% endtrans %}</span> + {% endif %} + {{form.no_email}} + </label> + </div> {% endif %} <div class="form-row"> <label>{{form.message.label}} @@ -36,6 +49,15 @@ <br/> {{form.message}} </div> + {% if form.recaptcha %} + <div class="form-row"> + {% if form.errors.recaptcha%} + <span class="error">{% trans %}(Please solve the captcha){% endtrans %}</span> + </label> + {% endif %} + {{form.recaptcha}} + </div> + {% endif %} {{form.next}} <div class="submit-row"> <input type="submit" class="submit" value="{% trans %}Send Feedback{% endtrans %}"/> diff --git a/askbot/skins/default/templates/macros.html b/askbot/skins/default/templates/macros.html index 680b9d7b..22272e9f 100644 --- a/askbot/skins/default/templates/macros.html +++ b/askbot/skins/default/templates/macros.html @@ -221,7 +221,7 @@ poor design of the data or methods on data objects #} title="{% trans %}see questions tagged '{{ tag }}'{% endtrans %}" {% endif %} rel="tag" - >{{ tag|replace('*', '✽') }}</{% if not is_link or tag[-1] == '*' %}span{% else %}a{% endif %}> + >{{ tag|replace('*', '✽')|truncate(20,True)}}</{% if not is_link or tag[-1] == '*' %}span{% else %}a{% endif %}> {% if deletable %} <span class="delete-icon" {% if delete_link_title %} diff --git a/askbot/skins/default/templates/user_profile/user_stats.html b/askbot/skins/default/templates/user_profile/user_stats.html index d9002d30..2551015c 100644 --- a/askbot/skins/default/templates/user_profile/user_stats.html +++ b/askbot/skins/default/templates/user_profile/user_stats.html @@ -8,7 +8,7 @@ {% include "user_profile/user_info.html" %} <a name="questions"></a> {% spaceless %} - <h2>{% trans counter=questions|length %}<span class="count">{{counter}}</span> Question{% pluralize %}<span class="count">{{counter}}</span> Questions{% endtrans %}</h2> + <h2>{% trans counter=question_count %}<span class="count">{{counter}}</span> Question{% pluralize %}<span class="count">{{counter}}</span> Questions{% endtrans %}</h2> {% endspaceless %} {% include "user_profile/users_questions.html" %} <a name="answers"></a> diff --git a/askbot/views/meta.py b/askbot/views/meta.py index 301a0925..493ab8ec 100644 --- a/askbot/views/meta.py +++ b/askbot/views/meta.py @@ -33,13 +33,13 @@ def config_variable(request, variable_name = None, mimetype = None): return HttpResponse(output, mimetype = mimetype) def about(request, template='about.html'): - return generic_view(request, template = template, page_class = 'meta') + return generic_view(request, template = template, page_class = 'meta') def page_not_found(request, template='404.html'): - return generic_view(request, template) + return generic_view(request, template) def server_error(request, template='500.html'): - return generic_view(request, template) + return generic_view(request, template) def faq(request): if getattr(askbot_settings, 'FORUM_FAQ',''): @@ -64,7 +64,7 @@ def faq(request): #'send_email_key_url': reverse('send_email_key'), 'ask_question_url': reverse('ask'), 'page_class': 'meta', - } + } return render_into_skin('faq_static.html', data, request) @csrf.csrf_protect @@ -72,9 +72,10 @@ def feedback(request): data = {'page_class': 'meta'} form = None if request.method == "POST": - form = FeedbackForm(request.POST) + form = FeedbackForm(is_auth = request.user.is_authenticated(), + data = request.POST) if form.is_valid(): - if not request.user.is_authenticated: + 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) @@ -85,7 +86,8 @@ def feedback(request): request.user.message_set.create(message=msg) return HttpResponseRedirect(get_next_url(request)) else: - form = FeedbackForm(initial={'next':get_next_url(request)}) + form = FeedbackForm(is_auth = request.user.is_authenticated(), + initial={'next':get_next_url(request)}) data['form'] = form return render_into_skin('feedback.html', data, request) @@ -96,7 +98,7 @@ def privacy(request): def badges(request):#user status/reputation system #todo: supplement database data with the stuff from badges.py - known_badges = badge_data.BADGES.keys() + known_badges = badge_data.BADGES.keys() badges = BadgeData.objects.filter(slug__in = known_badges).order_by('slug') my_badges = [] if request.user.is_authenticated(): diff --git a/askbot/views/users.py b/askbot/views/users.py index f17bde28..52e05842 100644 --- a/askbot/views/users.py +++ b/askbot/views/users.py @@ -1,7 +1,7 @@ """ :synopsis: user-centric views for askbot -This module includes all views that are specific to a given user - his or her profile, +This module includes all views that are specific to a given user - his or her profile, and other views showing profile-related information. Also this module includes the view listing all forum users. @@ -59,7 +59,7 @@ def owner_or_moderator_required(f): params = '?next=%s' % request.path return HttpResponseRedirect(reverse('user_signin') + params) return f(request, profile_owner, context) - return wrapped_func + return wrapped_func def users(request): is_paginated = True @@ -84,7 +84,7 @@ def users(request): objects_list = Paginator( models.User.objects.all().order_by( order_by_parameter - ), + ), const.USERS_PAGE_SIZE ) base_url = reverse('users') + '?sort=%s&' % sortby @@ -95,7 +95,7 @@ def users(request): username__icontains = suser ).order_by( '-reputation' - ), + ), const.USERS_PAGE_SIZE ) base_url = reverse('users') + '?name=%s&sort=%s&' % (suser, sortby) @@ -129,7 +129,7 @@ def users(request): @csrf.csrf_protect def user_moderate(request, subject, context): - """user subview for moderation + """user subview for moderation """ moderator = request.user @@ -158,7 +158,7 @@ def user_moderate(request, subject, context): if send_message_form.is_valid(): subject_line = send_message_form.cleaned_data['subject_line'] body_text = send_message_form.cleaned_data['body_text'] - + try: send_mail( subject_line = subject_line, @@ -228,7 +228,7 @@ def set_new_email(user, new_email, nomessage=False): user.email_isvalid = False user.save() #if askbot_settings.EMAIL_VALIDATION == True: - # send_new_email_key(user,nomessage=nomessage) + # send_new_email_key(user,nomessage=nomessage) @login_required @csrf.csrf_protect @@ -293,7 +293,26 @@ def user_stats(request, user, context): 'last_activity_by__silver', 'last_activity_by__bronze' )[:100] + questions = list(questions) + + #added this if to avoid another query if questions is less than 100 + if len(questions) < 100: + question_count = len(questions) + else: + question_count = models.Question.objects.filter( + **question_filter + ).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' + ).count() + favorited_myself = models.FavoriteQuestion.objects.filter( question__in = questions, user = user @@ -368,6 +387,7 @@ def user_stats(request, user, context): 'page_title' : _('user profile overview'), 'user_status_for_display': user.get_status_display(soft = True), 'questions' : questions, + 'question_count': question_count, 'question_type' : ContentType.objects.get_for_model(models.Question), 'answer_type' : ContentType.objects.get_for_model(models.Answer), 'favorited_myself': favorited_myself, @@ -401,7 +421,7 @@ def user_recent(request, user, context): self.summary = summary slug_title = slugify(title) self.title_link = reverse( - 'question', + 'question', kwargs={'id':question_id} ) + u'%s' % slug_title if int(answer_id) > 0: @@ -443,11 +463,11 @@ def user_recent(request, user, context): for q in questions: q_event = Event( - q['active_at'], - q['activity_type'], - q['title'], - '', - '0', + q['active_at'], + q['activity_type'], + q['title'], + '', + '0', q['question_id'] ) activities.append(q_event) @@ -463,8 +483,8 @@ def user_recent(request, user, context): 'activity_type' : 'activity.activity_type' }, tables=['activity', 'answer', 'question'], - where=['activity.content_type_id = %s AND activity.object_id = answer.id AND ' + - 'answer.question_id=question.id AND NOT answer.deleted AND activity.user_id=%s AND '+ + where=['activity.content_type_id = %s AND activity.object_id = answer.id AND ' + + 'answer.question_id=question.id AND NOT answer.deleted AND activity.user_id=%s AND '+ 'activity.activity_type=%s AND NOT question.deleted'], params=[ContentType.objects.get_for_model(models.Answer).id, user.id, const.TYPE_ACTIVITY_ANSWER], order_by=['-activity.active_at'] @@ -685,7 +705,7 @@ def user_recent(request, user, context): @owner_or_moderator_required def user_responses(request, user, context): """ - We list answers for question, comments, and + We list answers for question, comments, and answer accepted by others for this user. as well as mentions of the user @@ -746,7 +766,7 @@ def user_responses(request, user, context): #todo: agrupate users if response['response_id'] == last_response_id: original_response = dict.copy(filtered_response_list[len(filtered_response_list)-1]) - original_response['nested_responses'].append(response) + original_response['nested_responses'].append(response) filtered_response_list[len(filtered_response_list)-1] = original_response else: filtered_response_list.append(response) @@ -848,8 +868,8 @@ def user_reputation(request, user, context): 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', + 'question__title', + 'question__id', 'user__username' ) #prepare data for the graph |