diff options
-rw-r--r-- | INSTALL | 26 | ||||
-rw-r--r-- | cron/send_email_alerts | 4 | ||||
-rw-r--r-- | forum/feed.py | 4 | ||||
-rw-r--r-- | forum/views.py | 51 | ||||
-rw-r--r-- | templates/content/js/com.cnprog.post.js | 2 | ||||
-rw-r--r-- | templates/content/style/style.css | 5 | ||||
-rw-r--r-- | templates/question.html | 26 | ||||
-rw-r--r-- | templates/user_reputation.html | 3 | ||||
-rw-r--r-- | templates/user_votes.html | 5 |
9 files changed, 81 insertions, 45 deletions
@@ -7,8 +7,10 @@ B. INSTALLATION 3. Running CNPROG in the development server 4. Installation under Apache/WSGI 5. Full text search - 6. Miscellaneous + 6. Email subscriptions + 7. Miscellaneous C. CONFIGURATION PARAMETERS (settings_local.py) +D. CUSTOMIZATION A. PREREQUISITES @@ -201,7 +203,16 @@ WSGIPythonEggs /var/python/eggs #must be readable and writable by apache remember that there must be trailing comma in parentheses for SHPINX_SEARCH_INDICES tuple - particlarly with just one item! -6. Miscellaneous +6. Email subscriptions + + This function at the moment requires Django 1.1 + + edit paths in the file cron/send_email_alerts + set up a cron job to call cron/send_email_alerts once or twice a day + subscription sender may be tested manually in shell + by calling cron/send_email_alerts + +7. Miscellaneous There are some demo scripts under sql_scripts folder, including badges and test accounts for CNProg.com. You @@ -265,3 +276,14 @@ LOGIN_URL = '/%s%s%s' % (FORUM_SCRIPT_ALIAS,'account/','signin/') DJANGO_VERSION = 1.1 #must be either 1.0 or 1.1 RESOURCE_REVISION=4 #increment when you update media files - clients will be forced to load new version + +D. Customization + +Other than settings_local.py the following will most likely need customization: +* locale/*/django.po - language files that may also contain your site-specific messages + if you want to start with english messages file - look for words like "forum" and + "CNPROG" in the msgstr lines +* templates/header.html and templates/footer.html may contain extra links +* templates/about.html - a place to explain for is your forum for +* templates/faq.html - put answers to users frequent questions +* templates/content/style/style.css - modify style sheet to add disctinctive look to your forum diff --git a/cron/send_email_alerts b/cron/send_email_alerts new file mode 100644 index 00000000..e9e433be --- /dev/null +++ b/cron/send_email_alerts @@ -0,0 +1,4 @@ +PYTHONPATH=/dir/just/above_forum +export PYTHONPATH +APP_ROOT=$PYTHONPATH/CNPROG +/usr/local/bin/python $APP_ROOT/manage.py send_email_alerts >> $APP_ROOT/log/django.lanai.log diff --git a/forum/feed.py b/forum/feed.py index 373f8a87..ad1d5cbd 100644 --- a/forum/feed.py +++ b/forum/feed.py @@ -16,7 +16,7 @@ from models import Question import settings class RssLastestQuestionsFeed(Feed): title = settings.APP_TITLE + _(' - ')+ _('latest questions') - link = settings.APP_URL + '/' + _('questions/') + link = settings.APP_URL + '/' + _('question/') description = settings.APP_DESCRIPTION #ttl = 10 copyright = settings.APP_COPYRIGHT @@ -34,7 +34,7 @@ class RssLastestQuestionsFeed(Feed): return item.added_at def items(self, item): - return Question.objects.filter(deleted=False).order_by('-added_at')[:30] + return Question.objects.filter(deleted=False).order_by('-last_activity_at')[:30] def main(): pass diff --git a/forum/views.py b/forum/views.py index 8f7d07fd..a1b37717 100644 --- a/forum/views.py +++ b/forum/views.py @@ -1739,32 +1739,43 @@ def user_votes(request, user_id, user_view): def user_reputation(request, user_id, user_view): user = get_object_or_404(User, id=user_id) - reputation = Repute.objects.extra( - select={'positive': 'sum(positive)', 'negative': 'sum(negative)', 'question_id':'question_id', - 'title': 'question.title'}, - tables=['repute', 'question'], - order_by=['-reputed_at'], - where=['user_id=%s AND question_id=question.id'], - params=[user.id] - ).values('positive', 'negative', 'question_id', 'title', 'reputed_at', 'reputation') - - reputation.query.group_by = ['question_id'] - + try: + from django.db.models import Sum + reputation = Repute.objects.extra( + select={'question_id':'question_id', + 'title': 'question.title'}, + tables=['repute', 'question'], + order_by=['-reputed_at'], + where=['user_id=%s AND question_id=question.id'], + params=[user.id] + ).values('question_id', 'title', 'reputed_at', 'reputation') + reputation = reputation.annotate(positive=Sum("positive"), negative=Sum("negative")) + except ImportError: + reputation = Repute.objects.extra( + select={'positive':'sum(positive)', 'negative':'sum(negative)', 'question_id':'question_id', + 'title': 'question.title'}, + tables=['repute', 'question'], + order_by=['-reputed_at'], + where=['user_id=%s AND question_id=question.id'], + params=[user.id] + ).values('positive', 'negative', 'question_id', 'title', 'reputed_at', 'reputation') + reputation.query.group_by = ['question_id'] + rep_list = [] for rep in Repute.objects.filter(user=user).order_by('reputed_at'): dic = '[%s,%s]' % (calendar.timegm(rep.reputed_at.timetuple()) * 1000, rep.reputation) rep_list.append(dic) reps = ','.join(rep_list) reps = '[%s]' % reps - - return render_to_response(user_view.template_file,{ - "tab_name" : user_view.id, - "tab_description" : user_view.tab_description, - "page_title" : user_view.page_title, - "view_user" : user, - "reputation" : reputation, - "reps" : reps - }, context_instance=RequestContext(request)) + + return render_to_response(user_view.template_file, { + "tab_name": user_view.id, + "tab_description": user_view.tab_description, + "page_title": user_view.page_title, + "view_user": user, + "reputation": reputation, + "reps": reps + }, context_instance=RequestContext(request)) def user_favorites(request, user_id, user_view): user = get_object_or_404(User, id=user_id) diff --git a/templates/content/js/com.cnprog.post.js b/templates/content/js/com.cnprog.post.js index 58db9b33..0e604b8f 100644 --- a/templates/content/js/com.cnprog.post.js +++ b/templates/content/js/com.cnprog.post.js @@ -290,7 +290,7 @@ var Vote = function(){ fav.text(data.count); } else if(data.success == "1"){ - object.attr("src", $.i18n._("/") + "/content/images/vote-favorite-on.png"); + object.attr("src", $.i18n._("/") + "content/images/vote-favorite-on.png"); var fav = getFavoriteNumber(); fav.text(data.count); fav.addClass("my-favorite-number"); diff --git a/templates/content/style/style.css b/templates/content/style/style.css index 65a323db..6c1d6a3f 100644 --- a/templates/content/style/style.css +++ b/templates/content/style/style.css @@ -163,7 +163,7 @@ blockquote border-right:1px solid #b4b48e; border-bottom:1px solid #b4b48e;*/ background: white;/* #f9f7ed;*/ - margin:10px 0 0 0; + margin:10px 0 10px 0; /*background:url(../images/quest-bg.gif) repeat-x top;*/ } #listA .qstA thumb {float:left; } @@ -1144,9 +1144,6 @@ ul.bulleta li {background:url(../images/bullet_green.gif) no-repeat 0px 2px; pad .message p { margin-bottom:0px; } -.message p.space-above { - margin-top:10px; -} .warning{color:red;} .darkred{color:darkred;} diff --git a/templates/question.html b/templates/question.html index 6929b762..9183767f 100644 --- a/templates/question.html +++ b/templates/question.html @@ -140,10 +140,6 @@ <span class="action-link"><a href="{% url edit_question question.id %}">{% trans 'edit' %}</a></span> {% endif %} {% separator %} - {% if request.user|can_delete_post:question %} - <span class="action-link"><a id="question-delete-link-{{question.id}}">{% trans "delete" %}</a></span> - {% endif %} - {% separator %} {% if question.closed %} {% if request.user|can_reopen_question:question %} <span class="action-link"><a href="{% url reopen question.id %}">{% trans "reopen" %}</a></span> @@ -163,6 +159,10 @@ {% endif %} </span> {% endif %} + {% separator %} + {% if request.user|can_delete_post:question %} + <span class="action-link"><a id="question-delete-link-{{question.id}}">{% trans "delete" %}</a></span> + {% endif %} {% endjoinitems %} </div> <div class="post-update-info-container"> @@ -294,15 +294,6 @@ <span class="action-link"><a href="{% url edit_answer answer.id %}">{% trans 'edit' %}</a></span> {% endif %} {% separator %} - {% if request.user|can_delete_post:answer %} - {% spaceless %} - <span class="action-link"> - <a id="answer-delete-link-{{answer.id}}"> - {% if answer.deleted %}{% trans "undelete" %}{% else %}{% trans "delete" %}{% endif %}</a> - </span> - {% endspaceless %} - {% endif %} - {% separator %} {% if request.user|can_flag_offensive %} <span id="answer-offensive-flag-{{ answer.id }}" class="offensive-flag" title="{% trans "report as offensive (i.e containing spam, advertising, malicious text, etc.)" %}"> @@ -312,6 +303,15 @@ {% endif %} </span> {% endif %} + {% separator %} + {% if request.user|can_delete_post:answer %} + {% spaceless %} + <span class="action-link"> + <a id="answer-delete-link-{{answer.id}}"> + {% if answer.deleted %}{% trans "undelete" %}{% else %}{% trans "delete" %}{% endif %}</a> + </span> + {% endspaceless %} + {% endif %} {% endjoinitems %} </div> <div class="post-update-info-container"> diff --git a/templates/user_reputation.html b/templates/user_reputation.html index 29d642fe..16127140 100644 --- a/templates/user_reputation.html +++ b/templates/user_reputation.html @@ -1,6 +1,7 @@ {% extends "user.html" %} <!-- user_reputation.html --> {% load extra_tags %} +{% load extra_filters %} {% load humanize %} {% block userjs %} <script type='text/javascript' src='{% href "/content/js/excanvas.pack.js" %}'></script> @@ -33,7 +34,7 @@ <div style="float:left;width:20px;color:red">{{ rep.negative }}</div> </div> - <a href="{% url questions %}{{ rep.question_id }}/{{ rep.title }}">{{ rep.title }}</a> <span class="small">({{ rep.reputed_at }})</span> + <a href="{% url question rep.question_id %}{{ rep.title|slugify }}">{{ rep.title }}</a> <span class="small">({{ rep.reputed_at }})</span> </p> {% endfor %} </div> diff --git a/templates/user_votes.html b/templates/user_votes.html index 4abbf46d..b72b3ef6 100644 --- a/templates/user_votes.html +++ b/templates/user_votes.html @@ -1,6 +1,7 @@ {% extends "user.html" %} <!-- user_votes.html --> {% load extra_tags %} +{% load extra_filters %} {% load humanize %} {% load i18n %} @@ -18,9 +19,9 @@ </div> <div style="float:left;overflow:hidden;width:750px"> {% ifequal vote.answer_id 0 %} - <span class="question-title-link"><a href="{% url questions %}{{ vote.question_id }}/{{ vote.title }}">{{ vote.title }}</a></span> + <span class="question-title-link"><a href="{% url question vote.question_id %}/{{ vote.title|slugify }}">{{ vote.title }}</a></span> {% else %} - <span class="answer-title-link" ><a href="{% url questions %}{{ vote.question_id }}/{{ vote.title }}#{{ vote.answer_id }}">{{ vote.title }}</a></span> + <span class="answer-title-link" ><a href="{% url question vote.question_id %}/{{ vote.title|slugify }}#{{ vote.answer_id }}">{{ vote.title }}</a></span> {% endifequal %} <div style="height:5px"></div> </div> |