summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2009-07-26 22:33:56 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2009-07-26 22:33:56 -0400
commitfaf167aed99ac4e28927f729b7c7bc94a47ef139 (patch)
treedb94fc2e3af7c23fdced6b48768283b9ca8f1019
parenta7a5d993c680a2fa2a541951d99742090a716807 (diff)
downloadaskbot-faf167aed99ac4e28927f729b7c7bc94a47ef139.tar.gz
askbot-faf167aed99ac4e28927f729b7c7bc94a47ef139.tar.bz2
askbot-faf167aed99ac4e28927f729b7c7bc94a47ef139.zip
merged in latest Mikes changes
-rw-r--r--INSTALL33
-rw-r--r--LICENSE20
-rw-r--r--context.py9
-rw-r--r--development.log30
-rw-r--r--django_authopenid/models.py4
-rw-r--r--django_authopenid/util.py4
-rw-r--r--forum/management/commands/once_award_badges.py37
-rw-r--r--forum/managers.py55
-rw-r--r--forum/models.py3
-rw-r--r--forum/templatetags/extra_tags.py20
-rw-r--r--forum/user.py1
-rw-r--r--forum/views.py132
-rw-r--r--locale/zh_CN/LC_MESSAGES/django.po629
-rw-r--r--middleware/pagesize.py29
-rw-r--r--mikes.patch2862
-rw-r--r--settings.py95
-rw-r--r--settings_local.py.dist25
-rw-r--r--templates/base.html2
-rw-r--r--templates/base_content.html6
-rw-r--r--templates/content/js/com.cnprog.post.js2
-rw-r--r--templates/content/js/com.cnprog.utils.js2
-rw-r--r--templates/content/style/openid.css2
-rw-r--r--templates/pagesize.html4
-rw-r--r--templates/question_retag.html109
-rw-r--r--templates/user_preferences.html15
-rw-r--r--urls.py1
26 files changed, 3946 insertions, 185 deletions
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 00000000..59f2dd0b
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,33 @@
+PRE-REQUIREMENTS:
+-----------------------------------------------
+1. Python2.5, MySQL, Django v1.0+
+
+2. Python-openid v2.2
+http://openidenabled.com/python-openid/
+
+3. django-authopenid(Included in project already)
+http://code.google.com/p/django-authopenid/
+
+4. html5lib
+http://code.google.com/p/html5lib/
+Used for HTML sanitizer
+
+5. Markdown2
+http://code.google.com/p/python-markdown2/
+
+
+INSTALL STEPS:
+-----------------------------------------------
+1. Copy settings_local.py.dist to settings_local.py and
+update all your settings. Check settings.py and update
+it as well if necessory.
+
+2. Prepare your database by using the same database/account
+configuration from above.
+
+3. Run "python manager.py runserver" to startup django
+development environment.
+
+4. There are some demo scripts under sql_scripts folder,
+including badges and test accounts for CNProg.com. You
+don't need them to run your sample.
diff --git a/LICENSE b/LICENSE
index e23e4b67..cb24f678 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,12 +1,14 @@
-版权所有(c) 2008 CNProg.com
+Copyright (C) 2009. Chen Gang
-根据2.0版本Apache许可证("许可证")授权;
-根据本许可证,用户可以不使用此文件。
-用户可从下列网址获得许可证副本:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
-http://www.apache.org/licenses/LICENSE-2.0
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
-除非因适用法律需要或书面同意,
-根据许可证分发的软件是基于"按原样"基础提供,
-无任何明示的或暗示的保证或条件。
-详见根据许可证许可下,特定语言的管辖权限和限制。 \ No newline at end of file
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
diff --git a/context.py b/context.py
new file mode 100644
index 00000000..f420b154
--- /dev/null
+++ b/context.py
@@ -0,0 +1,9 @@
+from django.conf import settings
+def application_settings(context):
+ return {
+ 'APP_TITLE' : settings.APP_TITLE,
+ 'APP_URL' : settings.APP_URL,
+ 'APP_KEYWORDS' : settings.APP_KEYWORDS,
+ 'APP_DESCRIPTION' : settings.APP_DESCRIPTION,
+ 'APP_INTRO' : settings.APP_INTRO
+ }
diff --git a/development.log b/development.log
new file mode 100644
index 00000000..7ad467e0
--- /dev/null
+++ b/development.log
@@ -0,0 +1,30 @@
+# development
+
+==July 26 2009, Evgeny==
+
+django_authopenid:
+considerably changed user interface
+
+log/forum/forms.py:
+- added tag input validation using regex
+- fixed bug with date type mismatch near self.fields['birthday'] =
+ in EditUserForm.__init__()
+
+/forum/templatetags/extra_tags.py:
+- fixed date type mismatch in get_age()
+
+/templates/content/js/com.cnprog.post.js:
+- fixed bug with post deletion/recovery
+
+javascript:
+- changed to use of non-minified code - better for editing
+and debugging
+
+/templates/question.html:
+- fixed display of delete/undelete links
+
+templates:
+added comments in the beginning/end of each template
+for the debugging purposes - so that you know which template outputs what html
+<!-- user_favorites.html -->
+<!-- end user_favorites.html -->
diff --git a/django_authopenid/models.py b/django_authopenid/models.py
index 9826c452..e6fb8111 100644
--- a/django_authopenid/models.py
+++ b/django_authopenid/models.py
@@ -3,7 +3,7 @@ from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
-import md5, random, sys, os, time
+import hashlib, random, sys, os, time
__all__ = ['Nonce', 'Association', 'UserAssociation',
'UserPasswordQueueManager', 'UserPasswordQueue']
@@ -47,7 +47,7 @@ class UserPasswordQueueManager(models.Manager):
# The random module is seeded when this Apache child is created.
# Use SECRET_KEY as added salt.
while 1:
- confirm_key = md5.new("%s%s%s%s" % (
+ confirm_key = hashlib.md5("%s%s%s%s" % (
random.randint(0, sys.maxint - 1), os.getpid(),
time.time(), settings.SECRET_KEY)).hexdigest()
try:
diff --git a/django_authopenid/util.py b/django_authopenid/util.py
index 841a81c7..54c1246b 100644
--- a/django_authopenid/util.py
+++ b/django_authopenid/util.py
@@ -15,7 +15,7 @@ try:
except:
from yadis import xri
-import time, base64, md5, operator
+import time, base64, hashlib, operator
import urllib
from models import Association, Nonce
@@ -128,7 +128,7 @@ class DjangoOpenIDStore(OpenIDStore):
def getAuthKey(self):
# Use first AUTH_KEY_LEN characters of md5 hash of SECRET_KEY
- return md5.new(settings.SECRET_KEY).hexdigest()[:self.AUTH_KEY_LEN]
+ return hashlib.md5(settings.SECRET_KEY).hexdigest()[:self.AUTH_KEY_LEN]
def isDumb(self):
return False
diff --git a/forum/management/commands/once_award_badges.py b/forum/management/commands/once_award_badges.py
index 011c28fd..c26251d7 100644
--- a/forum/management/commands/once_award_badges.py
+++ b/forum/management/commands/once_award_badges.py
@@ -157,7 +157,8 @@ class Command(BaseCommand):
"""
activity_types = ','.join('%s' % item for item in BADGE_AWARD_TYPE_FIRST.keys())
# ORDER BY user_id, activity_type
- query = "SELECT id, user_id, activity_type, content_type_id, object_id FROM activity WHERE is_auditted = 0 AND activity_type IN (%s) ORDER BY user_id, activity_type" % activity_types
+ query = "SELECT id, user_id, activity_type, content_type_id, object_id "+
+ "FROM activity WHERE is_auditted = 0 AND activity_type IN (%s) ORDER BY user_id, activity_type" % activity_types
cursor = connection.cursor()
try:
@@ -205,7 +206,10 @@ class Command(BaseCommand):
(13, '瀛︾敓', 3, '瀛︾敓', '绗竴娆℃彁闂苟涓旀湁涓娆′互涓婅禐鎴愮エ', 0, 0),
"""
- query = "SELECT act.user_id, q.vote_up_count, act.object_id FROM activity act, question q WHERE act.activity_type = %s AND act.object_id = q.id AND act.user_id NOT IN (SELECT distinct user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ASK_QUESTION, 13)
+ query = "SELECT act.user_id, q.vote_up_count, act.object_id FROM "+
+ "activity act, question q WHERE act.activity_type = %s AND "+
+ "act.object_id = q.id AND "+
+ "act.user_id NOT IN (SELECT distinct user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ASK_QUESTION, 13)
cursor = connection.cursor()
try:
cursor.execute(query)
@@ -232,7 +236,10 @@ class Command(BaseCommand):
(15, '鏁欏笀', 3, '鏁欏笀', '绗竴娆″洖绛旈棶棰樺苟涓斿緱鍒颁竴涓互涓婅禐鎴愮エ', 0, 0),
"""
- query = "SELECT act.user_id, a.vote_up_count, act.object_id FROM activity act, answer a WHERE act.activity_type = %s AND act.object_id = a.id AND act.user_id NOT IN (SELECT distinct user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 15)
+ query = "SELECT act.user_id, a.vote_up_count, act.object_id FROM "+
+ "activity act, answer a WHERE act.activity_type = %s AND "+
+ "act.object_id = a.id AND "+
+ "act.user_id NOT IN (SELECT distinct user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 15)
cursor = connection.cursor()
try:
cursor.execute(query)
@@ -257,7 +264,11 @@ class Command(BaseCommand):
"""
(32, '瀛﹂棶瀹', 2, '瀛﹂棶瀹', '绗竴娆″洖绛旇鎶曡禐鎴愮エ10娆′互涓', 0, 0)
"""
- query = "SELECT act.user_id, act.object_id FROM activity act, answer a WHERE act.object_id = a.id AND act.activity_type = %s AND a.vote_up_count >= 10 AND act.user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 32)
+ query = "SELECT act.user_id, act.object_id FROM "+
+ "activity act, answer a WHERE act.object_id = a.id AND "+
+ "act.activity_type = %s AND "+
+ "a.vote_up_count >= 10 AND "+
+ "act.user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 32)
cursor = connection.cursor()
try:
cursor.execute(query)
@@ -281,7 +292,11 @@ class Command(BaseCommand):
"""
(26, '浼樼甯傛皯', 2, '浼樼甯傛皯', '鎶曠エ300娆′互涓', 0, 0)
"""
- query = "SELECT count(*) vote_count, user_id FROM activity WHERE activity_type = %s OR activity_type = %s AND user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) GROUP BY user_id HAVING vote_count >= 300" % (TYPE_ACTIVITY_VOTE_UP, TYPE_ACTIVITY_VOTE_DOWN, 26)
+ query = "SELECT count(*) vote_count, user_id FROM activity WHERE "+
+ "activity_type = %s OR "+
+ "activity_type = %s AND "+
+ "user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) "+
+ "GROUP BY user_id HAVING vote_count >= 300" % (TYPE_ACTIVITY_VOTE_UP, TYPE_ACTIVITY_VOTE_DOWN, 26)
self.__award_for_count_num(query, 26)
@@ -289,7 +304,11 @@ class Command(BaseCommand):
"""
(27, '缂栬緫涓讳换', 2, '缂栬緫涓讳换', '缂栬緫浜100涓笘瀛', 0, 0)
"""
- query = "SELECT count(*) vote_count, user_id FROM activity WHERE activity_type = %s OR activity_type = %s AND user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) GROUP BY user_id HAVING vote_count >= 100" % (TYPE_ACTIVITY_UPDATE_QUESTION, TYPE_ACTIVITY_UPDATE_ANSWER, 27)
+ query = "SELECT count(*) vote_count, user_id FROM activity WHERE "+
+ "activity_type = %s OR "+
+ "activity_type = %s AND "+
+ "user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) "+
+ "GROUP BY user_id HAVING vote_count >= 100" % (TYPE_ACTIVITY_UPDATE_QUESTION, TYPE_ACTIVITY_UPDATE_ANSWER, 27)
self.__award_for_count_num(query, 27)
@@ -297,7 +316,11 @@ class Command(BaseCommand):
"""
(5, '璇勮瀹', 3, '璇勮瀹', '璇勮10娆′互涓', 0, 0),
"""
- query = "SELECT count(*) vote_count, user_id FROM activity WHERE activity_type = %s OR activity_type = %s AND user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) GROUP BY user_id HAVING vote_count >= 10" % (TYPE_ACTIVITY_COMMENT_QUESTION, TYPE_ACTIVITY_COMMENT_ANSWER, 5)
+ query = "SELECT count(*) vote_count, user_id FROM activity WHERE "+
+ "activity_type = %s OR "+
+ "activity_type = %s AND "+
+ "user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) "+
+ "GROUP BY user_id HAVING vote_count >= 10" % (TYPE_ACTIVITY_COMMENT_QUESTION, TYPE_ACTIVITY_COMMENT_ANSWER, 5)
self.__award_for_count_num(query, 5)
def __award_for_count_num(self, query, badge):
diff --git a/forum/managers.py b/forum/managers.py
index 94f58ea7..0f22c59c 100644
--- a/forum/managers.py
+++ b/forum/managers.py
@@ -4,8 +4,29 @@ from django.contrib.auth.models import User, UserManager
from django.db import connection, models, transaction
from django.db.models import Q
from forum.models import *
+from urllib import quote, unquote
class QuestionManager(models.Manager):
+ def get_translation_questions(self, orderby, page_size):
+ questions = self.filter(deleted=False, author__id__in=[28,29]).order_by(orderby)[:page_size]
+ return questions
+
+ def get_questions_by_pagesize(self, orderby, page_size):
+ questions = self.filter(deleted=False).order_by(orderby)[:page_size]
+ return questions
+
+ def get_questions_by_tag(self, tagname, orderby):
+ questions = self.filter(deleted=False, tags__name = unquote(tagname)).order_by(orderby)
+ return questions
+
+ def get_unanswered_questions(self, orderby):
+ questions = self.filter(deleted=False, answer_count=0).order_by(orderby)
+ return questions
+
+ def get_questions(self, orderby):
+ questions = self.filter(deleted=False).order_by(orderby)
+ return questions
+
def update_tags(self, question, tagnames, user):
"""
Updates Tag associations for a question to match the given
@@ -92,7 +113,12 @@ class TagManager(models.Manager):
'WHERE tag_id = tag.id'
') '
'WHERE id IN (%s)')
-
+
+ def get_valid_tags(self, page_size):
+ from forum.models import Tag
+ tags = Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-id")[:page_size]
+ return tags
+
def get_or_create_multiple(self, names, user):
"""
Fetches a list of Tags with the given names, creating any Tags
@@ -123,6 +149,19 @@ class TagManager(models.Manager):
query = self.UPDATE_USED_COUNTS_QUERY % ','.join(['%s'] * len(tags))
cursor.execute(query, [tag.id for tag in tags])
transaction.commit_unless_managed()
+
+ def get_tags_by_questions(self, questions):
+ question_ids = []
+ for question in questions:
+ question_ids.append(question.id)
+
+ question_ids_str = ','.join([str(id) for id in question_ids])
+ related_tags = self.extra(
+ tables=['tag', 'question_tags'],
+ where=["tag.id = question_tags.tag_id AND question_tags.question_id IN (" + question_ids_str + ")"]
+ ).distinct()
+
+ return related_tags
class AnswerManager(models.Manager):
GET_ANSWERS_FROM_USER_QUESTIONS = u'SELECT answer.* FROM answer INNER JOIN question ON answer.question_id = question.id WHERE question.author_id =%s AND answer.author_id <> %s'
@@ -205,4 +244,16 @@ class ReputeManager(models.Manager):
return row[0]
else:
- return 0 \ No newline at end of file
+ return 0
+class AwardManager(models.Manager):
+ def get_recent_awards(self):
+ awards = super(AwardManager, self).extra(
+ select={'badge_id': 'badge.id', 'badge_name':'badge.name',
+ 'badge_description': 'badge.description', 'badge_type': 'badge.type',
+ 'user_id': 'auth_user.id', 'user_name': 'auth_user.username'
+ },
+ tables=['award', 'badge', 'auth_user'],
+ order_by=['-awarded_at'],
+ where=['auth_user.id=award.user_id AND badge_id=badge.id'],
+ ).values('badge_id', 'badge_name', 'badge_description', 'badge_type', 'user_id', 'user_name')
+ return awards
diff --git a/forum/models.py b/forum/models.py
index aba2bf0b..570db274 100644
--- a/forum/models.py
+++ b/forum/models.py
@@ -351,7 +351,8 @@ class Award(models.Model):
content_object = generic.GenericForeignKey('content_type', 'object_id')
awarded_at = models.DateTimeField(default=datetime.datetime.now)
notified = models.BooleanField(default=False)
-
+ objects = AwardManager()
+
def __unicode__(self):
return u'[%s] is awarded a badge [%s] at %s' % (self.user.username, self.badge.name, self.awarded_at)
diff --git a/forum/templatetags/extra_tags.py b/forum/templatetags/extra_tags.py
index de853135..1a4d3641 100644
--- a/forum/templatetags/extra_tags.py
+++ b/forum/templatetags/extra_tags.py
@@ -1,4 +1,4 @@
-import time
+锘縤mport time
import datetime
import math
import re
@@ -50,10 +50,10 @@ def tag_font_size(max_size, min_size, current_size):
weight = 0
return MIN_FONTSIZE + round((MAX_FONTSIZE - MIN_FONTSIZE) * weight)
-
+
LEADING_PAGE_RANGE_DISPLAYED = TRAILING_PAGE_RANGE_DISPLAYED = 5
LEADING_PAGE_RANGE = TRAILING_PAGE_RANGE = 4
-NUM_PAGES_OUTSIDE_RANGE = 1
+NUM_PAGES_OUTSIDE_RANGE = 1
ADJACENT_PAGES = 2
@register.inclusion_tag("paginator.html")
def cnprog_paginator(context):
@@ -65,10 +65,10 @@ def cnprog_paginator(context):
" Initialize variables "
in_leading_range = in_trailing_range = False
pages_outside_leading_range = pages_outside_trailing_range = range(0)
-
+
if (context["pages"] <= LEADING_PAGE_RANGE_DISPLAYED):
in_leading_range = in_trailing_range = True
- page_numbers = [n for n in range(1, context["pages"] + 1) if n > 0 and n <= context["pages"]]
+ page_numbers = [n for n in range(1, context["pages"] + 1) if n > 0 and n <= context["pages"]]
elif (context["page"] <= LEADING_PAGE_RANGE):
in_leading_range = True
page_numbers = [n for n in range(1, LEADING_PAGE_RANGE_DISPLAYED + 1) if n > 0 and n <= context["pages"]]
@@ -77,11 +77,11 @@ def cnprog_paginator(context):
in_trailing_range = True
page_numbers = [n for n in range(context["pages"] - TRAILING_PAGE_RANGE_DISPLAYED + 1, context["pages"] + 1) if n > 0 and n <= context["pages"]]
pages_outside_trailing_range = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)]
- else:
+ else:
page_numbers = [n for n in range(context["page"] - ADJACENT_PAGES, context["page"] + ADJACENT_PAGES + 1) if n > 0 and n <= context["pages"]]
pages_outside_leading_range = [n + context["pages"] for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)]
pages_outside_trailing_range = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)]
-
+
extend_url = context.get('extend_url', '')
return {
"base_url": context["base_url"],
@@ -205,12 +205,12 @@ def format_number(value):
m = re.match(pattern, strValue)
return first + result
-@register.simple_tag
+@register.simple_tag
def convert2tagname_list(question):
question['tagnames'] = [name for name in question['tagnames'].split(u' ')]
return ''
-@register.simple_tag
+@register.simple_tag
def diff_date(date, limen=2):
current_time = datetime.datetime(*time.localtime()[0:6])
diff = current_time - date
@@ -237,4 +237,4 @@ def get_latest_changed_timestamp():
timestr = strftime("%H:%M %b-%d-%Y %Z", localtime(latest))
except:
timestr = ''
- return timestr
+ return timestr \ No newline at end of file
diff --git a/forum/user.py b/forum/user.py
index 13e9be30..233baf0c 100644
--- a/forum/user.py
+++ b/forum/user.py
@@ -1,3 +1,4 @@
+锘# coding=utf-8
from django.utils.translation import ugettext as _
class UserView:
def __init__(self, id, tab_title, tab_description, page_title, view_name, template_file, data_size=0):
diff --git a/forum/views.py b/forum/views.py
index 25574e0b..08a0e958 100644
--- a/forum/views.py
+++ b/forum/views.py
@@ -77,29 +77,17 @@ def index(request):
orderby = "-last_activity_at"
# group questions by author_id of 28,29
if view_id == 'trans':
- questions = Question.objects.filter(deleted=False, author__id__in=[28,29]).order_by(orderby)[:INDEX_PAGE_SIZE]
+ questions = Question.objects.get_translation_questions(orderby, INDEX_PAGE_SIZE)
else:
- questions = Question.objects.filter(deleted=False).order_by(orderby)[:INDEX_PAGE_SIZE]
+ questions = Question.objects.get_questions_by_pagesize(orderby, INDEX_PAGE_SIZE)
# RISK - inner join queries
- questions = questions.select_related();
- tags = Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-id")[:INDEX_TAGS_SIZE]
+ questions = questions.select_related()
+ tags = Tag.objects.get_valid_tags(INDEX_TAGS_SIZE)
- awards = Award.objects.extra(
- select={'badge_id': 'badge.id', 'badge_name':'badge.name',
- 'badge_description': 'badge.description', 'badge_type': 'badge.type',
- 'user_id': 'auth_user.id', 'user_name': 'auth_user.username'
- },
- tables=['award', 'badge', 'auth_user'],
- order_by=['-awarded_at'],
- where=['auth_user.id=award.user_id AND badge_id=badge.id'],
- ).values('badge_id', 'badge_name', 'badge_description', 'badge_type', 'user_id', 'user_name')
-
- class testvar:
- content = 'haha'
+ awards = Award.objects.get_recent_awards()
return render_to_response('index.html', {
"questions" : questions,
- 'testvar':testvar,
"tab_id" : view_id,
"tags" : tags,
"awards" : awards[:INDEX_AWARD_SIZE],
@@ -127,29 +115,11 @@ def questions(request, tagname=None, unanswered=False):
# Set flag to False by default. If it is equal to True, then need to be saved.
pagesize_changed = False
# get pagesize from session, if failed then get default value
- user_page_size = request.session.get("pagesize", QUESTIONS_PAGE_SIZE)
- # set pagesize equal to logon user specified value in database
- if request.user.is_authenticated() and request.user.questions_per_page > 0:
- user_page_size = request.user.questions_per_page
-
+ pagesize = request.session.get("pagesize")
try:
page = int(request.GET.get('page', '1'))
- # get new pagesize from UI selection
- pagesize = int(request.GET.get('pagesize', user_page_size))
- if pagesize <> user_page_size:
- pagesize_changed = True
-
except ValueError:
page = 1
- pagesize = user_page_size
-
- # save this pagesize to user database
- if pagesize_changed:
- request.session["pagesize"] = pagesize
- if request.user.is_authenticated():
- user = request.user
- user.questions_per_page = pagesize
- user.save()
view_id = request.GET.get('sort', None)
view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" }
@@ -161,29 +131,24 @@ def questions(request, tagname=None, unanswered=False):
# check if request is from tagged questions
if tagname is not None:
- #print datetime.datetime.now()
- objects = Question.objects.filter(deleted=False, tags__name = unquote(tagname)).order_by(orderby)
- #print datetime.datetime.now()
+ objects = Question.objects.get_questions_by_tag(tagname, orderby)
elif unanswered:
#check if request is from unanswered questions
template_file = "unanswered.html"
- objects = Question.objects.filter(deleted=False, answer_count=0).order_by(orderby)
+ objects = Question.objects.get_unanswered_questions(orderby)
else:
- objects = Question.objects.filter(deleted=False).order_by(orderby)
+ objects = Question.objects.get_questions(orderby)
# RISK - inner join queries
- objects = objects.select_related();
+ objects = objects.select_related(depth=1);
objects_list = Paginator(objects, pagesize)
questions = objects_list.page(page)
# Get related tags from this page objects
- related_tags = []
- for question in questions.object_list:
- tags = list(question.tags.all())
- for tag in tags:
- if tag not in related_tags:
- related_tags.append(tag)
-
+ if questions.object_list.count() > 0:
+ related_tags = Tag.objects.get_tags_by_questions(questions.object_list)
+ else:
+ related_tags = None
return render_to_response(template_file, {
"questions" : questions,
"tab_id" : view_id,
@@ -1022,6 +987,7 @@ def user_stats(request, user_id, user_view):
'title',
'author_id',
'accepted',
+ 'vote_count',
'answer_count',
'vote_up_count',
'vote_down_count')[:100]
@@ -1090,7 +1056,8 @@ def user_recent(request, user_id, user_view):
'activity_type' : 'activity.activity_type'
},
tables=['activity', 'question'],
- where=['activity.content_type_id = %s AND activity.object_id = question.id AND activity.user_id = %s AND activity.activity_type = %s'],
+ where=['activity.content_type_id = %s AND activity.object_id = ' +
+ 'question.id AND activity.user_id = %s AND activity.activity_type = %s'],
params=[question_type_id, user_id, TYPE_ACTIVITY_ASK_QUESTION],
order_by=['-activity.active_at']
).values(
@@ -1114,8 +1081,8 @@ def user_recent(request, user_id, user_view):
'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 activity.user_id=%s AND activity.activity_type=%s'],
+ where=['activity.content_type_id = %s AND activity.object_id = answer.id AND ' +
+ 'answer.question_id=question.id AND activity.user_id=%s AND activity.activity_type=%s'],
params=[answer_type_id, user_id, TYPE_ACTIVITY_ANSWER],
order_by=['-activity.active_at']
).values(
@@ -1140,7 +1107,9 @@ def user_recent(request, user_id, user_view):
},
tables=['activity', 'question', 'comment'],
- where=['activity.content_type_id = %s AND activity.object_id = comment.id AND activity.user_id = comment.user_id AND comment.object_id=question.id AND comment.content_type_id=%s AND activity.user_id = %s AND activity.activity_type=%s'],
+ where=['activity.content_type_id = %s AND activity.object_id = comment.id AND '+
+ 'activity.user_id = comment.user_id AND comment.object_id=question.id AND '+
+ 'comment.content_type_id=%s AND activity.user_id = %s AND activity.activity_type=%s'],
params=[comment_type_id, question_type_id, user_id, TYPE_ACTIVITY_COMMENT_QUESTION],
order_by=['-comment.added_at']
).values(
@@ -1166,7 +1135,10 @@ def user_recent(request, user_id, user_view):
},
tables=['activity', 'question', 'answer', 'comment'],
- where=['activity.content_type_id = %s AND activity.object_id = comment.id AND activity.user_id = comment.user_id AND comment.object_id=answer.id AND comment.content_type_id=%s AND question.id = answer.question_id AND activity.user_id = %s AND activity.activity_type=%s'],
+ where=['activity.content_type_id = %s AND activity.object_id = comment.id AND '+
+ 'activity.user_id = comment.user_id AND comment.object_id=answer.id AND '+
+ 'comment.content_type_id=%s AND question.id = answer.question_id AND '+
+ 'activity.user_id = %s AND activity.activity_type=%s'],
params=[comment_type_id, answer_type_id, user_id, TYPE_ACTIVITY_COMMENT_ANSWER],
order_by=['-comment.added_at']
).values(
@@ -1192,7 +1164,9 @@ def user_recent(request, user_id, user_view):
'summary' : 'question_revision.summary'
},
tables=['activity', 'question_revision'],
- where=['activity.content_type_id = %s AND activity.object_id = question_revision.id AND activity.user_id = question_revision.author_id AND activity.user_id = %s AND activity.activity_type=%s'],
+ where=['activity.content_type_id = %s AND activity.object_id = question_revision.id AND '+
+ 'activity.user_id = question_revision.author_id AND activity.user_id = %s AND '+
+ 'activity.activity_type=%s'],
params=[question_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_QUESTION],
order_by=['-activity.active_at']
).values(
@@ -1220,7 +1194,10 @@ def user_recent(request, user_id, user_view):
},
tables=['activity', 'answer_revision', 'question', 'answer'],
- where=['activity.content_type_id = %s AND activity.object_id = answer_revision.id AND activity.user_id = answer_revision.author_id AND activity.user_id = %s AND answer_revision.answer_id=answer.id AND answer.question_id = question.id AND activity.activity_type=%s'],
+ where=['activity.content_type_id = %s AND activity.object_id = answer_revision.id AND '+
+ 'activity.user_id = answer_revision.author_id AND activity.user_id = %s AND '+
+ 'answer_revision.answer_id=answer.id AND answer.question_id = question.id AND '+
+ 'activity.activity_type=%s'],
params=[answer_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_ANSWER],
order_by=['-activity.active_at']
).values(
@@ -1246,7 +1223,9 @@ def user_recent(request, user_id, user_view):
'activity_type' : 'activity.activity_type',
},
tables=['activity', 'answer', 'question'],
- where=['activity.content_type_id = %s AND activity.object_id = answer.id AND activity.user_id = question.author_id AND activity.user_id = %s AND answer.question_id=question.id AND activity.activity_type=%s'],
+ where=['activity.content_type_id = %s AND activity.object_id = answer.id AND '+
+ 'activity.user_id = question.author_id AND activity.user_id = %s AND '+
+ 'answer.question_id=question.id AND activity.activity_type=%s'],
params=[answer_type_id, user_id, TYPE_ACTIVITY_MARK_ANSWER],
order_by=['-activity.active_at']
).values(
@@ -1267,7 +1246,8 @@ def user_recent(request, user_id, user_view):
'activity_type' : 'activity.activity_type'
},
tables=['activity', 'award', 'badge'],
- where=['activity.user_id = award.user_id AND activity.user_id = %s AND award.badge_id=badge.id AND activity.object_id=award.id AND activity.activity_type=%s'],
+ where=['activity.user_id = award.user_id AND activity.user_id = %s AND '+
+ 'award.badge_id=badge.id AND activity.object_id=award.id AND activity.activity_type=%s'],
params=[user_id, TYPE_ACTIVITY_PRIZE],
order_by=['-activity.active_at']
).values(
@@ -1320,7 +1300,8 @@ def user_responses(request, user_id, user_view):
},
select_params=[user_id],
tables=['answer', 'question', 'auth_user'],
- where=['answer.question_id = question.id AND answer.deleted=0 AND question.deleted = 0 AND question.author_id = %s AND answer.author_id <> %s AND answer.author_id=auth_user.id'],
+ where=['answer.question_id = question.id AND answer.deleted=0 AND question.deleted = 0 AND '+
+ 'question.author_id = %s AND answer.author_id <> %s AND answer.author_id=auth_user.id'],
params=[user_id, user_id],
order_by=['-answer.id']
).values(
@@ -1349,7 +1330,8 @@ def user_responses(request, user_id, user_view):
'user_id' : 'auth_user.id'
},
tables=['question', 'auth_user', 'comment'],
- where=['question.deleted = 0 AND question.author_id = %s AND comment.object_id=question.id AND comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id'],
+ where=['question.deleted = 0 AND question.author_id = %s AND comment.object_id=question.id AND '+
+ 'comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id'],
params=[user_id, question_type_id, user_id],
order_by=['-comment.added_at']
).values(
@@ -1378,7 +1360,9 @@ def user_responses(request, user_id, user_view):
'user_id' : 'auth_user.id'
},
tables=['answer', 'auth_user', 'comment', 'question'],
- where=['answer.deleted = 0 AND answer.author_id = %s AND comment.object_id=answer.id AND comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id AND question.id = answer.question_id'],
+ where=['answer.deleted = 0 AND answer.author_id = %s AND comment.object_id=answer.id AND '+
+ 'comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id '+
+ 'AND question.id = answer.question_id'],
params=[user_id, answer_type_id, user_id],
order_by=['-comment.added_at']
).values(
@@ -1409,7 +1393,8 @@ def user_responses(request, user_id, user_view):
},
select_params=[user_id],
tables=['answer', 'question', 'auth_user'],
- where=['answer.question_id = question.id AND answer.deleted=0 AND question.deleted = 0 AND answer.author_id = %s AND answer.accepted=1 AND question.author_id=auth_user.id'],
+ where=['answer.question_id = question.id AND answer.deleted=0 AND question.deleted = 0 AND '+
+ 'answer.author_id = %s AND answer.accepted=1 AND question.author_id=auth_user.id'],
params=[user_id],
order_by=['-answer.id']
).values(
@@ -1453,7 +1438,8 @@ def user_votes(request, user_id, user_view):
},
select_params=[user_id],
tables=['vote', 'question', 'auth_user'],
- where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = question.id AND vote.user_id=auth_user.id'],
+ where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = question.id '+
+ 'AND vote.user_id=auth_user.id'],
params=[question_type_id, user_id],
order_by=['-vote.id']
).values(
@@ -1476,7 +1462,8 @@ def user_votes(request, user_id, user_view):
},
select_params=[user_id],
tables=['vote', 'answer', 'question', 'auth_user'],
- where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = answer.id AND answer.question_id = question.id AND vote.user_id=auth_user.id'],
+ where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = answer.id '+
+ 'AND answer.question_id = question.id AND vote.user_id=auth_user.id'],
params=[answer_type_id, user_id],
order_by=['-vote.id']
).values(
@@ -1501,7 +1488,8 @@ 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'},
+ 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'],
@@ -1510,6 +1498,7 @@ def user_reputation(request, user_id, user_view):
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)
@@ -1531,7 +1520,8 @@ def user_favorites(request, user_id, user_view):
questions = Question.objects.extra(
select={
'vote_count' : 'question.vote_up_count + question.vote_down_count',
- 'favorited_myself' : 'SELECT count(*) FROM favorite_question f WHERE f.user_id = %s AND f.question_id = question.id',
+ 'favorited_myself' : 'SELECT count(*) FROM favorite_question f WHERE f.user_id = %s '+
+ 'AND f.question_id = question.id',
'la_user_id' : 'auth_user.id',
'la_username' : 'auth_user.username',
'la_user_gold' : 'auth_user.gold',
@@ -1541,7 +1531,8 @@ def user_favorites(request, user_id, user_view):
},
select_params=[user_id],
tables=['question', 'auth_user', 'favorite_question'],
- where=['question.deleted = 0 AND question.last_activity_by_id = auth_user.id AND favorite_question.question_id = question.id AND favorite_question.user_id = %s'],
+ where=['question.deleted = 0 AND question.last_activity_by_id = auth_user.id '+
+ 'AND favorite_question.question_id = question.id AND favorite_question.user_id = %s'],
params=[user_id],
order_by=['-vote_count', '-question.id']
).values('vote_count',
@@ -1672,7 +1663,12 @@ def badges(request):
def badge(request, id):
badge = get_object_or_404(Badge, id=id)
awards = Award.objects.extra(
- select={'id': 'auth_user.id', 'name': 'auth_user.username', 'rep':'auth_user.reputation', 'gold': 'auth_user.gold', 'silver': 'auth_user.silver', 'bronze': 'auth_user.bronze'},
+ select={'id': 'auth_user.id',
+ 'name': 'auth_user.username',
+ 'rep':'auth_user.reputation',
+ 'gold': 'auth_user.gold',
+ 'silver': 'auth_user.silver',
+ 'bronze': 'auth_user.bronze'},
tables=['award', 'auth_user'],
where=['badge_id=%s AND user_id=auth_user.id'],
params=[id]
diff --git a/locale/zh_CN/LC_MESSAGES/django.po b/locale/zh_CN/LC_MESSAGES/django.po
new file mode 100644
index 00000000..176e41dc
--- /dev/null
+++ b/locale/zh_CN/LC_MESSAGES/django.po
@@ -0,0 +1,629 @@
+# Chinese translations for CNProg.com
+# Copyright (C) 2009
+# This file is distributed under the same license as the CNPROG package.
+# Mike Chen <chagel@gmail.com>, 2009.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-07-15 13:53+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: settings.py:12
+msgid "account/"
+msgstr ""
+
+#: settings.py:12 django_authopenid/urls.py:9 django_authopenid/urls.py:11
+msgid "signin/"
+msgstr ""
+
+#: django_authopenid/forms.py:67 django_authopenid/views.py:93
+msgid "i-names are not supported"
+msgstr "i-names涓嶆敮鎸併"
+
+#: django_authopenid/forms.py:102 django_authopenid/forms.py:207
+msgid ""
+"Usernames can only contain letters, numbers and "
+"underscores"
+msgstr "鐢ㄦ埛鍚嶆牸寮忔湁璇傚彧鏈夊瓧姣嶏紝鏁板瓧鍜屼笅鍒掔嚎鏄厑璁哥殑銆"
+
+#: django_authopenid/forms.py:109
+msgid ""
+"This username does not exist in our database. Please "
+"choose another."
+msgstr "鐢ㄦ埛鍚嶄笉瀛樺湪銆傝閲嶆柊杈撳叆銆"
+
+#: django_authopenid/forms.py:126 django_authopenid/forms.py:231
+msgid ""
+"Please enter a valid username and password. Note that "
+"both fields are case-sensitive."
+msgstr "璇疯緭鍏ョ敤鎴峰悕鍜屽瘑鐮併傛敞鎰忓尯鍒嗗ぇ灏忓啓銆"
+
+#: django_authopenid/forms.py:130 django_authopenid/forms.py:235
+msgid "This account is inactive."
+msgstr "鐢ㄦ埛宸插喕缁撱"
+
+#: django_authopenid/forms.py:184
+msgid ""
+"This email is already registered in our database. Please "
+"choose another."
+msgstr "鐢靛瓙閭欢宸茶娉ㄥ唽銆傝浣跨敤涓涓柊鐨勯偖浠跺湴鍧銆"
+
+#: django_authopenid/forms.py:214
+msgid ""
+"This username don't exist. Please choose another."
+msgstr "鐢ㄦ埛鍚嶄笉瀛樺湪"
+
+#: django_authopenid/forms.py:330
+msgid ""
+"Old password is incorrect. Please enter the correct "
+"password."
+msgstr "鏃у瘑鐮侀敊璇"
+
+#: django_authopenid/forms.py:342
+msgid "new passwords do not match"
+msgstr "鏂板瘑鐮佷笉鍖归厤"
+
+#: django_authopenid/forms.py:434
+msgid "Incorrect username."
+msgstr "鐢ㄦ埛鍚嶄笉姝g‘"
+
+#: django_authopenid/urls.py:10
+msgid "signout/"
+msgstr ""
+
+#: django_authopenid/urls.py:11
+msgid "complete/"
+msgstr ""
+
+#: django_authopenid/urls.py:13
+msgid "register/"
+msgstr ""
+
+#: django_authopenid/urls.py:14
+msgid "signup/"
+msgstr ""
+
+#: django_authopenid/urls.py:16
+msgid "sendpw/"
+msgstr ""
+
+#: django_authopenid/urls.py:26
+msgid "delete/"
+msgstr ""
+
+#: django_authopenid/views.py:99
+#, python-format
+msgid "闈炴硶OpenID鍦板潃锛 %s"
+msgstr ""
+
+#: django_authopenid/views.py:366 templates/index.html:78
+msgid "Welcome"
+msgstr "娆㈣繋"
+
+#: django_authopenid/views.py:456
+msgid "Password changed."
+msgstr "瀵嗙爜宸叉洿鏂般"
+
+#: django_authopenid/views.py:488
+msgid "Email changed."
+msgstr "閭欢鍦板潃宸叉洿鏂般"
+
+#: django_authopenid/views.py:519 django_authopenid/views.py:671
+#, python-format
+msgid "No OpenID %s found associated in our database"
+msgstr "璇penID %s 涓嶅湪绯荤粺涓"
+
+#: django_authopenid/views.py:523 django_authopenid/views.py:678
+#, python-format
+msgid "The OpenID %s isn't associated to current user logged in"
+msgstr "OpenID %s 娌℃湁鍜屽綋鍓嶇櫥褰曠敤鎴风粦瀹氥"
+
+#: django_authopenid/views.py:531
+msgid "Email Changed."
+msgstr "閭欢鍦板潃宸叉洿鏂般"
+
+#: django_authopenid/views.py:606
+msgid "This OpenID is already associated with another account."
+msgstr "杩欎釜OpenID宸茬粡缁戝畾鍒板彟澶栦竴涓笎鍙枫"
+
+#: django_authopenid/views.py:611
+#, python-format
+msgid "OpenID %s is now associated with your account."
+msgstr "OpenID %s 宸茬粡缁戝畾鍒版偍鐨勫笎鍙枫"
+
+#: django_authopenid/views.py:681
+msgid "Account deleted."
+msgstr "甯愬彿宸插垹闄ゃ"
+
+#: django_authopenid/views.py:721
+msgid "Request for new password"
+msgstr "鎵惧洖瀵嗙爜"
+
+#: django_authopenid/views.py:734
+msgid "A new password has been sent to your email address."
+msgstr "鏂扮殑瀵嗙爜宸茬粡鍙戦佸埌鎮ㄧ殑閭欢甯愬彿銆"
+
+#: django_authopenid/views.py:764
+#, python-format
+msgid ""
+"Could not change password. Confirmation key '%s' is not "
+"registered."
+msgstr "涓嶈兘淇敼瀵嗙爜銆傜‘璁や俊鎭 '%s' 鏈夎銆"
+
+#: django_authopenid/views.py:773
+msgid ""
+"Can not change password. User don't exist anymore in our "
+"database."
+msgstr "涓嶈兘淇敼瀵嗙爜銆傜敤鎴峰笎鍙蜂笉瀛樺湪銆"
+
+#: django_authopenid/views.py:782
+#, python-format
+msgid "Password changed for %s. You may now sign in."
+msgstr "甯愬彿 %s 鐨勫瘑鐮佸凡缁忎慨鏀广傛偍鐜板湪鍙互鐢ㄥ畠鏉ョ櫥褰曘"
+
+#: forum/user.py:17
+msgid "Overview"
+msgstr "姒傝"
+
+#: forum/user.py:18
+msgid "User overview"
+msgstr "鐢ㄦ埛姒傝"
+
+#: forum/user.py:19
+msgid "Overview - User Profile"
+msgstr "姒傝-鐢ㄦ埛璧勬枡"
+
+#: forum/user.py:25
+msgid "Recent"
+msgstr "鏈杩戞椿鍔"
+
+#: forum/user.py:26
+msgid "Recent activities"
+msgstr "鐢ㄦ埛鏈杩戞椿鍔ㄦ儏鍐"
+
+#: forum/user.py:27
+msgid "Recent - User Profile"
+msgstr "鏈杩戞椿鍔-鐢ㄦ埛璧勬枡"
+
+#: forum/user.py:34
+msgid "Response"
+msgstr "鍥炲簲"
+
+#: forum/user.py:35
+msgid "Responses from others"
+msgstr "鍏朵粬鐢ㄦ埛鐨勫洖绛斿拰璇勮"
+
+#: forum/user.py:36
+msgid "Response - User Profile"
+msgstr "鍥炲簲-鐢ㄦ埛璧勬枡"
+
+#: forum/user.py:43
+msgid "Reputation"
+msgstr "绉垎"
+
+#: forum/user.py:44
+msgid "Community reputation"
+msgstr "绀惧尯绉垎"
+
+#: forum/user.py:45
+msgid "Reputation - User Profile"
+msgstr "绉垎-鐢ㄦ埛璧勬枡"
+
+#: forum/user.py:51
+msgid "Favorites"
+msgstr "鏀惰棌"
+
+#: forum/user.py:52
+msgid "User's favorite questions"
+msgstr "鐢ㄦ埛鏀惰棌鐨勯棶棰"
+
+#: forum/user.py:53
+msgid "Favorites - User Profile"
+msgstr "鏀惰棌-鐢ㄦ埛璧勬枡"
+
+#: forum/user.py:60 templates/index.html:46 templates/questions.html:45
+msgid "Votes"
+msgstr "鎶曠エ"
+
+#: forum/user.py:61
+msgid "Votes history"
+msgstr "鐢ㄦ埛鎶曠エ鍘嗗彶"
+
+#: forum/user.py:62
+msgid "Votes - User Profile"
+msgstr "鎶曠エ-鐢ㄦ埛璧勬枡"
+
+#: forum/user.py:69
+msgid "Preferences"
+msgstr "璁剧疆"
+
+#: forum/user.py:70
+msgid "User preferences"
+msgstr "鐢ㄦ埛鍙傛暟璁剧疆"
+
+#: forum/user.py:71
+msgid "Preferences - User Profile"
+msgstr "璁剧疆-鐢ㄦ埛璧勬枡"
+
+#: templates/badges.html:5 templates/badges.html.py:16
+#: templates/header.html:31
+msgid "Badges"
+msgstr "濂栫墝姒"
+
+#: templates/base.html:53 templates/base_content.html:52
+msgid "Congratulations! You have new badges: "
+msgstr "鎭枩鎮ㄨ鎺堜簣濂栫墝锛"
+
+#: templates/base.html:54 templates/base_content.html:53
+msgid "go to see"
+msgstr "鏌ョ湅"
+
+#: templates/base.html:55 templates/base_content.html:54
+#: templates/header.html:35
+msgid "Profile"
+msgstr "鎴戠殑璧勬枡"
+
+#: templates/footer.html:5 templates/header.html:10 templates/index.html:81
+msgid "About us"
+msgstr "鍏充簬鎴戜滑"
+
+#: templates/footer.html:6 templates/header.html:11
+msgid "faq"
+msgstr "甯歌闂"
+
+#: templates/footer.html:8
+msgid "Contact"
+msgstr "鑱旂郴鎴戜滑"
+
+#: templates/footer.html:9
+msgid "Privacy"
+msgstr "闅愮鏀跨瓥"
+
+#: templates/footer.html:10
+msgid "Feedback"
+msgstr "鐢ㄦ埛鍙嶉"
+
+#: templates/header.html:6 templates/logout.html:5 templates/logout.html.py:16
+msgid "Logout"
+msgstr "閫鍑虹櫥褰"
+
+#: templates/header.html:8
+msgid "Login"
+msgstr "鐧诲綍"
+
+#: templates/header.html:21
+msgid "link to homepage"
+msgstr "杩斿洖棣栭〉"
+
+#: templates/header.html:27 templates/header.html.py:56
+#: templates/index.html:21
+msgid "Questions"
+msgstr "闂"
+
+#: templates/header.html:28 templates/header.html.py:57
+msgid "Tags"
+msgstr "鏍囩"
+
+#: templates/header.html:29 templates/header.html.py:58
+msgid "Users"
+msgstr "鐢ㄦ埛"
+
+#: templates/header.html:30
+msgid "Books"
+msgstr "璇讳功"
+
+#: templates/header.html:32
+msgid "Unanswered"
+msgstr "娌℃湁鍥炵瓟鐨勯棶棰"
+
+#: templates/header.html:38
+msgid "Ask a question"
+msgstr "鎴戣鎻愰棶"
+
+#: templates/header.html:53
+msgid "Search"
+msgstr "鎼滅储"
+
+#: templates/index.html:6
+msgid "Home"
+msgstr "棣栭〉"
+
+#: templates/index.html:23 templates/questions.html:25
+msgid "Newest updated questions"
+msgstr "鏈鏂版洿鏂扮殑闂"
+
+#: templates/index.html:23 templates/questions.html:24
+msgid "Newest"
+msgstr "鏈鏂伴棶棰"
+
+#: templates/index.html:24 templates/questions.html:26
+msgid "Questions with most answers"
+msgstr "琚洖澶嶆渶澶氱殑闂"
+
+#: templates/index.html:24 templates/questions.html:26
+msgid "Hottest"
+msgstr "鏈鐑棶棰"
+
+#: templates/index.html:25 templates/questions.html:27
+msgid "Questions with most votes"
+msgstr "琚姇绁ㄦ渶澶氱殑闂"
+
+#: templates/index.html:25 templates/questions.html:27
+msgid "Best"
+msgstr "鏈鏈変环鍊奸棶棰"
+
+#: templates/index.html:26 templates/index.html.py:118
+#: templates/questions.html:22
+msgid "All questions"
+msgstr "鎵鏈夐棶棰"
+
+#: templates/index.html:26
+msgid "All"
+msgstr "鎵鏈夐棶棰"
+
+#: templates/index.html:45 templates/questions.html:44
+msgid "Answers"
+msgstr "鍥炵瓟"
+
+#: templates/index.html:47 templates/questions.html:46
+msgid "Visits"
+msgstr "璁块棶"
+
+#: templates/index.html:55 templates/questions.html:57
+#: templates/questions.html.py:69
+msgid "Community wiki"
+msgstr "绀惧尯wiki"
+
+#: templates/index.html:67 templates/index.html.py:91
+#: templates/questions.html:83
+msgid "Browse questions with tag of "
+msgstr "鏌ョ湅鎵鏈変互涓嬩富棰橀棶棰橈細"
+
+#: templates/index.html:87
+msgid "Recent tags"
+msgstr "鏈鏂版爣绛"
+
+#: templates/index.html:94 templates/index.html.py:118
+msgid "Popular tags"
+msgstr "鍙楁杩庣殑鏍囩"
+
+#: templates/index.html:98
+msgid "Recent badges"
+msgstr "鏈鏂板鐗"
+
+#: templates/index.html:109
+msgid "All badges"
+msgstr "鎵鏈夊鐗"
+
+#: templates/index.html:113
+msgid "RSS feed of recent 30 questions"
+msgstr "RSS璁㈤槄鏈鏂30涓棶棰"
+
+#: templates/index.html:113
+msgid "Subscribe"
+msgstr "璁㈤槄鏈鏂伴棶棰"
+
+#: templates/index.html:118
+msgid "Are you looking for more questions? Try to browse"
+msgstr "鍦ㄥ鎵炬洿澶氶棶棰樺悧锛熻鏌ラ槄"
+
+#: templates/index.html:118
+msgid " or "
+msgstr " 鎴栬 "
+
+#: templates/index.html:118
+msgid ". Please help us answer "
+msgstr "銆傝甯姪鎴戜滑鍥炵瓟"
+
+#: templates/index.html:118
+msgid "Unanswered questions"
+msgstr "娌℃湁鍥炵瓟鐨勯棶棰"
+
+#: templates/pagesize.html:5
+msgid "Size per page:"
+msgstr "姣忛〉鏄剧ず锛"
+
+#: templates/paginator.html:5
+msgid "Previous"
+msgstr "涓婁竴椤"
+
+#: templates/questions.html:6
+msgid "Question list"
+msgstr "闂鍒楄〃"
+
+#: templates/questions.html:22
+msgid "Tagged questions"
+msgstr "鏍囩闂"
+
+#: templates/questions.html:22
+msgid "Query result"
+msgstr "鏌ヨ缁撴灉"
+
+#: templates/questions.html:24
+msgid "New questions"
+msgstr "鏈鏂伴棶棰"
+
+#: templates/questions.html:25
+msgid "Active"
+msgstr "娲昏穬闂"
+
+#: templates/questions.html:125
+msgid "Related tags"
+msgstr "鐩稿叧鏍囩"
+
+#: templates/authopenid/changeemail.html:10
+msgid "Account: change email"
+msgstr "淇敼鐢靛瓙閭欢"
+
+#: templates/authopenid/changeemail.html:13
+msgid ""
+"This is where you can change the email address associated with your account. "
+"Please keep this email address up to date so we can send you a password-"
+"reset email if you request one."
+msgstr ""
+"鎮ㄥ彲浠ュ湪杩欓噷淇敼鎮ㄧ殑鐢靛瓙閭欢锛岃纭繚杩欎釜閭欢鍦板潃鏈夋晥-鎵惧洖瀵嗙爜灏嗗彂閫佹柊瀵嗙爜鍒版偍"
+"鐨勯偖浠跺湴鍧銆"
+
+#: templates/authopenid/changeemail.html:15
+#: templates/authopenid/changeopenid.html:13
+#: templates/authopenid/changepw.html:18 templates/authopenid/delete.html:14
+#: templates/authopenid/delete.html:24
+msgid "Please correct errors below:"
+msgstr "璇锋敼姝d互涓嬮敊璇細"
+
+#: templates/authopenid/changeemail.html:32
+msgid "Email"
+msgstr "鐢靛瓙閭欢"
+
+#: templates/authopenid/changeemail.html:33
+msgid "Password"
+msgstr "瀵嗙爜"
+
+#: templates/authopenid/changeemail.html:35
+msgid "Change email"
+msgstr "淇敼鐢靛瓙閭欢"
+
+#: templates/authopenid/changeopenid.html:7
+msgid "Account: change OpenID URL"
+msgstr "淇敼OpenID鍦板潃"
+
+#: templates/authopenid/changeopenid.html:11
+msgid ""
+"This is where you can change your OpenID URL. Make sure you remember it!"
+msgstr "璇蜂慨鏀规偍鐨凮penID鍦板潃锛岃涓嶈蹇樿杩欎釜鍦板潃锛"
+
+#: templates/authopenid/changeopenid.html:28
+msgid "OpenID URL:"
+msgstr "OpenID鍦板潃锛"
+
+#: templates/authopenid/changeopenid.html:29
+msgid "Change OpenID"
+msgstr "淇敼OpenID"
+
+#: templates/authopenid/changepw.html:13
+msgid "Account: change password"
+msgstr "淇敼瀵嗙爜"
+
+#: templates/authopenid/changepw.html:16
+msgid "This is where you can change your password. Make sure you remember it!"
+msgstr "璇蜂慨鏀规偍鐨勫瘑鐮侊紝鍒囪涓嶈蹇樿锛"
+
+#: templates/authopenid/changepw.html:26
+msgid "Current password"
+msgstr "鏃у瘑鐮"
+
+#: templates/authopenid/changepw.html:27
+msgid "New password"
+msgstr "鏂板瘑鐮"
+
+#: templates/authopenid/changepw.html:28
+msgid "New password again"
+msgstr "閲嶅瀵嗙爜"
+
+#: templates/authopenid/changepw.html:29
+msgid "Change password"
+msgstr "淇敼瀵嗙爜"
+
+#: templates/authopenid/delete.html:8
+msgid "Account: delete account"
+msgstr "鍒犻櫎甯愬彿"
+
+#: templates/authopenid/delete.html:12
+msgid ""
+"Note: After deleting your account, anyone will be able to register this "
+"username."
+msgstr "娉ㄦ剰锛氬垹闄ゆ偍鐨勫笎鍙峰悗锛屼换浣曞叾浠栦汉鍙互鍐嶆敞鍐岃繖涓笎鍙枫"
+
+#: templates/authopenid/delete.html:16
+msgid "Check confirm box, if you want delete your account."
+msgstr "濡傛灉纭畾鍒犻櫎锛岃閫変腑澶氶夋銆"
+
+#: templates/authopenid/delete.html:19
+msgid "Password:"
+msgstr "瀵嗙爜锛"
+
+#: templates/authopenid/delete.html:31
+msgid "I am sure I want to delete my account."
+msgstr "鎴戠‘璁よ鍒犻櫎杩欎釜甯愬彿銆"
+
+#: templates/authopenid/delete.html:32
+msgid "Password/OpenID URL"
+msgstr "瀵嗙爜/OpenID鍦板潃"
+
+#: templates/authopenid/delete.html:32
+msgid "(required for your security)"
+msgstr "锛堝繀闇锛"
+
+#: templates/authopenid/delete.html:34
+msgid "Delete account permanently"
+msgstr "姘镐箙鍒犻櫎甯愬彿"
+
+#: templates/authopenid/settings.html:29
+msgid "Give your account a new password."
+msgstr "淇敼瀵嗙爜"
+
+#: templates/authopenid/settings.html:31
+msgid "Add or update the email address associated with your account."
+msgstr "娣诲姞鎴栬呮洿鏂版偍鐨勯偖浠跺湴鍧銆"
+
+#: templates/authopenid/settings.html:34
+msgid "Change openid associated to your account"
+msgstr "淇敼鍜屼綘甯愬彿缁戝畾鐨凮penID鍦板潃"
+
+#: templates/authopenid/settings.html:38
+msgid "Erase your username and all your data from website"
+msgstr "鍒犻櫎鎮ㄧ殑甯愬彿鍜屾墍鏈夊唴瀹"
+
+#, fuzzy
+#~ msgid "Badges "
+#~ msgstr "濂栫墝鍒楄〃"
+
+#~ msgid ""
+#~ "This username is already taken. Please choose another."
+#~ msgstr "鐢ㄦ埛鍚嶅凡缁忚娉ㄥ唽锛岃閫夌敤涓涓柊鐨勫笎鍙枫"
+
+#~ msgid "Your OpenID is verified! "
+#~ msgstr "鎮ㄧ殑OpenID甯愬彿宸茬粡楠岃瘉閫氳繃"
+
+#~ msgid "Associate your OpenID"
+#~ msgstr "缁戝畾鎮ㄧ殑OpenID"
+
+#~ msgid ""
+#~ "\n"
+#~ "\t<p>If you're joining <strong>Sitename</strong>, associate your OpenID "
+#~ "with a new account. If you're already a member, associate with your "
+#~ "existing account.</p>\n"
+#~ "\t"
+#~ msgstr ""
+#~ "\n"
+#~ "\t<p>杈撳叆鎮ㄧ殑鏂板笎鍙锋垨鑰呮寚瀹氬凡缁忓瓨鍦ㄧ殑甯愬彿銆</p>\n"
+#~ "\t"
+
+#~ msgid "A new account"
+#~ msgstr "鏂板笎鍙"
+
+#~ msgid "An exisiting account"
+#~ msgstr "宸茬粡瀛樺湪鐨勫笎鍙"
+
+#~ msgid "Account: Send a new password"
+#~ msgstr "鍙戦佷竴涓柊鐨勫瘑鐮"
+
+#~ msgid ""
+#~ "Lost your password ? Here you can ask to reset your password. Enter the "
+#~ "username you use and you will get a confirmation email with your new "
+#~ "password. This new password will be activated only after you have clicked "
+#~ "on the link in the email."
+#~ msgstr ""
+#~ "涓㈠け浜嗘偍鐨勫瘑鐮侊紵浣犲彲浠ュ湪杩欓噷閲嶈瀵嗙爜銆傝緭鍏ョ敤鎴峰悕浣犱細鏀跺埌鏂扮殑瀵嗙爜鐨勯偖浠躲傚瘑"
+#~ "鐮佸彧鏈夋偍鍦ㄦ縺娲婚偖浠朵腑鐨勯摼鎺ユ墠浼氳婵娲汇"
+
+#~ msgid "Send new password"
+#~ msgstr "鍙戦佹柊瀵嗙爜"
diff --git a/middleware/pagesize.py b/middleware/pagesize.py
new file mode 100644
index 00000000..bb6c7aa3
--- /dev/null
+++ b/middleware/pagesize.py
@@ -0,0 +1,29 @@
+# used in questions
+QUESTIONS_PAGE_SIZE = 10
+class QuestionsPageSizeMiddleware(object):
+ def process_request(self, request):
+ # Set flag to False by default. If it is equal to True, then need to be saved.
+ pagesize_changed = False
+ # get pagesize from session, if failed then get default value
+ user_page_size = request.session.get("pagesize", QUESTIONS_PAGE_SIZE)
+ # set pagesize equal to logon user specified value in database
+ if request.user.is_authenticated() and request.user.questions_per_page > 0:
+ user_page_size = request.user.questions_per_page
+
+ try:
+ # get new pagesize from UI selection
+ pagesize = int(request.GET.get('pagesize', user_page_size))
+ if pagesize <> user_page_size:
+ pagesize_changed = True
+
+ except ValueError:
+ pagesize = user_page_size
+
+ # save this pagesize to user database
+ if pagesize_changed:
+ if request.user.is_authenticated():
+ user = request.user
+ user.questions_per_page = pagesize
+ user.save()
+ # put pagesize into session
+ request.session["pagesize"] = pagesize \ No newline at end of file
diff --git a/mikes.patch b/mikes.patch
new file mode 100644
index 00000000..58437fb1
--- /dev/null
+++ b/mikes.patch
@@ -0,0 +1,2862 @@
+diff -ruN CNPROG/context.py mikes/context.py
+--- CNPROG/context.py 1969-12-31 19:00:00.000000000 -0500
++++ mikes/context.py 2009-07-25 19:09:58.098151134 -0400
+@@ -0,0 +1,9 @@
++from django.conf import settings
++def application_settings(context):
++ return {
++ 'APP_TITLE' : settings.APP_TITLE,
++ 'APP_URL' : settings.APP_URL,
++ 'APP_KEYWORDS' : settings.APP_KEYWORDS,
++ 'APP_DESCRIPTION' : settings.APP_DESCRIPTION,
++ 'APP_INTRO' : settings.APP_INTRO
++ }
+diff -ruN CNPROG/development.log mikes/development.log
+--- CNPROG/development.log 1969-12-31 19:00:00.000000000 -0500
++++ mikes/development.log 2009-07-25 19:09:58.098151134 -0400
+@@ -0,0 +1 @@
++# development log
+\ No newline at end of file
+diff -ruN CNPROG/django_authopenid/models.py mikes/django_authopenid/models.py
+--- CNPROG/django_authopenid/models.py 2009-06-22 21:42:50.000000000 -0400
++++ mikes/django_authopenid/models.py 2009-07-25 19:09:58.098151134 -0400
+@@ -3,7 +3,7 @@
+ from django.contrib.auth.models import User
+ from django.db import models
+
+-import md5, random, sys, os, time
++import hashlib, random, sys, os, time
+
+ __all__ = ['Nonce', 'Association', 'UserAssociation',
+ 'UserPasswordQueueManager', 'UserPasswordQueue']
+@@ -47,7 +47,7 @@
+ # The random module is seeded when this Apache child is created.
+ # Use SECRET_KEY as added salt.
+ while 1:
+- confirm_key = md5.new("%s%s%s%s" % (
++ confirm_key = hashlib.md5("%s%s%s%s" % (
+ random.randint(0, sys.maxint - 1), os.getpid(),
+ time.time(), settings.SECRET_KEY)).hexdigest()
+ try:
+diff -ruN CNPROG/django_authopenid/util.py mikes/django_authopenid/util.py
+--- CNPROG/django_authopenid/util.py 2009-06-22 21:42:50.000000000 -0400
++++ mikes/django_authopenid/util.py 2009-07-25 19:09:58.098151134 -0400
+@@ -15,7 +15,7 @@
+ except:
+ from yadis import xri
+
+-import time, base64, md5, operator
++import time, base64, hashlib, operator
+ import urllib
+
+ from models import Association, Nonce
+@@ -128,7 +128,7 @@
+
+ def getAuthKey(self):
+ # Use first AUTH_KEY_LEN characters of md5 hash of SECRET_KEY
+- return md5.new(settings.SECRET_KEY).hexdigest()[:self.AUTH_KEY_LEN]
++ return hashlib.md5(settings.SECRET_KEY).hexdigest()[:self.AUTH_KEY_LEN]
+
+ def isDumb(self):
+ return False
+diff -ruN CNPROG/forum/const.py mikes/forum/const.py
+--- CNPROG/forum/const.py 2009-07-26 16:01:31.559063617 -0400
++++ mikes/forum/const.py 2009-07-25 19:09:58.098151134 -0400
+@@ -53,22 +52,24 @@
+ #TYPE_ACTIVITY_EDIT_ANSWER=18
+
+ TYPE_ACTIVITY = (
+ (TYPE_ACTIVITY_ASK_QUESTION, _('question')),
+ (TYPE_ACTIVITY_ANSWER, _('answer')),
+ (TYPE_ACTIVITY_COMMENT_QUESTION, _('commented question')),
+ (TYPE_ACTIVITY_COMMENT_ANSWER, _('commented answer')),
+ (TYPE_ACTIVITY_UPDATE_QUESTION, _('edited question')),
+ (TYPE_ACTIVITY_UPDATE_ANSWER, _('edited answer')),
+ (TYPE_ACTIVITY_PRIZE, _('received award')),
+ (TYPE_ACTIVITY_MARK_ANSWER, _('marked best answer')),
+ (TYPE_ACTIVITY_VOTE_UP, _('upvoted')),
+ (TYPE_ACTIVITY_VOTE_DOWN, _('downvoted')),
+ (TYPE_ACTIVITY_CANCEL_VOTE, _('canceled vote')),
+ (TYPE_ACTIVITY_DELETE_QUESTION, _('deleted question')),
+ (TYPE_ACTIVITY_DELETE_ANSWER, _('deleted answer')),
+ (TYPE_ACTIVITY_MARK_OFFENSIVE, _('marked offensive')),
+ (TYPE_ACTIVITY_UPDATE_TAGS, _('updated tags')),
+ (TYPE_ACTIVITY_FAVORITE, _('selected favorite')),
+ (TYPE_ACTIVITY_USER_FULL_UPDATED, _('completed user profile')),
++ #(TYPE_ACTIVITY_EDIT_QUESTION, u'缂栬緫闂'),
++ #(TYPE_ACTIVITY_EDIT_ANSWER, u'缂栬緫绛旀'),
+ )
+
+diff -ruN CNPROG/forum/management/commands/once_award_badges.py mikes/forum/management/commands/once_award_badges.py
+--- CNPROG/forum/management/commands/once_award_badges.py 2009-06-22 21:42:50.000000000 -0400
++++ mikes/forum/management/commands/once_award_badges.py 2009-07-25 19:09:58.098151134 -0400
+@@ -157,7 +157,8 @@
+ """
+ activity_types = ','.join('%s' % item for item in BADGE_AWARD_TYPE_FIRST.keys())
+ # ORDER BY user_id, activity_type
+- query = "SELECT id, user_id, activity_type, content_type_id, object_id FROM activity WHERE is_auditted = 0 AND activity_type IN (%s) ORDER BY user_id, activity_type" % activity_types
++ query = "SELECT id, user_id, activity_type, content_type_id, object_id "+
++ "FROM activity WHERE is_auditted = 0 AND activity_type IN (%s) ORDER BY user_id, activity_type" % activity_types
+
+ cursor = connection.cursor()
+ try:
+@@ -205,7 +206,10 @@
+
+ (13, '瀛︾敓', 3, '瀛︾敓', '绗竴娆℃彁闂苟涓旀湁涓娆′互涓婅禐鎴愮エ', 0, 0),
+ """
+- query = "SELECT act.user_id, q.vote_up_count, act.object_id FROM activity act, question q WHERE act.activity_type = %s AND act.object_id = q.id AND act.user_id NOT IN (SELECT distinct user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ASK_QUESTION, 13)
++ query = "SELECT act.user_id, q.vote_up_count, act.object_id FROM "+
++ "activity act, question q WHERE act.activity_type = %s AND "+
++ "act.object_id = q.id AND "+
++ "act.user_id NOT IN (SELECT distinct user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ASK_QUESTION, 13)
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+@@ -232,7 +236,10 @@
+
+ (15, '鏁欏笀', 3, '鏁欏笀', '绗竴娆″洖绛旈棶棰樺苟涓斿緱鍒颁竴涓互涓婅禐鎴愮エ', 0, 0),
+ """
+- query = "SELECT act.user_id, a.vote_up_count, act.object_id FROM activity act, answer a WHERE act.activity_type = %s AND act.object_id = a.id AND act.user_id NOT IN (SELECT distinct user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 15)
++ query = "SELECT act.user_id, a.vote_up_count, act.object_id FROM "+
++ "activity act, answer a WHERE act.activity_type = %s AND "+
++ "act.object_id = a.id AND "+
++ "act.user_id NOT IN (SELECT distinct user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 15)
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+@@ -257,7 +264,11 @@
+ """
+ (32, '瀛﹂棶瀹', 2, '瀛﹂棶瀹', '绗竴娆″洖绛旇鎶曡禐鎴愮エ10娆′互涓', 0, 0)
+ """
+- query = "SELECT act.user_id, act.object_id FROM activity act, answer a WHERE act.object_id = a.id AND act.activity_type = %s AND a.vote_up_count >= 10 AND act.user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 32)
++ query = "SELECT act.user_id, act.object_id FROM "+
++ "activity act, answer a WHERE act.object_id = a.id AND "+
++ "act.activity_type = %s AND "+
++ "a.vote_up_count >= 10 AND "+
++ "act.user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 32)
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+@@ -281,7 +292,11 @@
+ """
+ (26, '浼樼甯傛皯', 2, '浼樼甯傛皯', '鎶曠エ300娆′互涓', 0, 0)
+ """
+- query = "SELECT count(*) vote_count, user_id FROM activity WHERE activity_type = %s OR activity_type = %s AND user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) GROUP BY user_id HAVING vote_count >= 300" % (TYPE_ACTIVITY_VOTE_UP, TYPE_ACTIVITY_VOTE_DOWN, 26)
++ query = "SELECT count(*) vote_count, user_id FROM activity WHERE "+
++ "activity_type = %s OR "+
++ "activity_type = %s AND "+
++ "user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) "+
++ "GROUP BY user_id HAVING vote_count >= 300" % (TYPE_ACTIVITY_VOTE_UP, TYPE_ACTIVITY_VOTE_DOWN, 26)
+
+ self.__award_for_count_num(query, 26)
+
+@@ -289,7 +304,11 @@
+ """
+ (27, '缂栬緫涓讳换', 2, '缂栬緫涓讳换', '缂栬緫浜100涓笘瀛', 0, 0)
+ """
+- query = "SELECT count(*) vote_count, user_id FROM activity WHERE activity_type = %s OR activity_type = %s AND user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) GROUP BY user_id HAVING vote_count >= 100" % (TYPE_ACTIVITY_UPDATE_QUESTION, TYPE_ACTIVITY_UPDATE_ANSWER, 27)
++ query = "SELECT count(*) vote_count, user_id FROM activity WHERE "+
++ "activity_type = %s OR "+
++ "activity_type = %s AND "+
++ "user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) "+
++ "GROUP BY user_id HAVING vote_count >= 100" % (TYPE_ACTIVITY_UPDATE_QUESTION, TYPE_ACTIVITY_UPDATE_ANSWER, 27)
+
+ self.__award_for_count_num(query, 27)
+
+@@ -297,7 +316,11 @@
+ """
+ (5, '璇勮瀹', 3, '璇勮瀹', '璇勮10娆′互涓', 0, 0),
+ """
+- query = "SELECT count(*) vote_count, user_id FROM activity WHERE activity_type = %s OR activity_type = %s AND user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) GROUP BY user_id HAVING vote_count >= 10" % (TYPE_ACTIVITY_COMMENT_QUESTION, TYPE_ACTIVITY_COMMENT_ANSWER, 5)
++ query = "SELECT count(*) vote_count, user_id FROM activity WHERE "+
++ "activity_type = %s OR "+
++ "activity_type = %s AND "+
++ "user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) "+
++ "GROUP BY user_id HAVING vote_count >= 10" % (TYPE_ACTIVITY_COMMENT_QUESTION, TYPE_ACTIVITY_COMMENT_ANSWER, 5)
+ self.__award_for_count_num(query, 5)
+
+ def __award_for_count_num(self, query, badge):
+diff -ruN CNPROG/forum/managers.py mikes/forum/managers.py
+--- CNPROG/forum/managers.py 2009-06-22 21:42:50.000000000 -0400
++++ mikes/forum/managers.py 2009-07-25 19:09:58.098151134 -0400
+@@ -4,8 +4,29 @@
+ from django.db import connection, models, transaction
+ from django.db.models import Q
+ from forum.models import *
++from urllib import quote, unquote
+
+ class QuestionManager(models.Manager):
++ def get_translation_questions(self, orderby, page_size):
++ questions = self.filter(deleted=False, author__id__in=[28,29]).order_by(orderby)[:page_size]
++ return questions
++
++ def get_questions_by_pagesize(self, orderby, page_size):
++ questions = self.filter(deleted=False).order_by(orderby)[:page_size]
++ return questions
++
++ def get_questions_by_tag(self, tagname, orderby):
++ questions = self.filter(deleted=False, tags__name = unquote(tagname)).order_by(orderby)
++ return questions
++
++ def get_unanswered_questions(self, orderby):
++ questions = self.filter(deleted=False, answer_count=0).order_by(orderby)
++ return questions
++
++ def get_questions(self, orderby):
++ questions = self.filter(deleted=False).order_by(orderby)
++ return questions
++
+ def update_tags(self, question, tagnames, user):
+ """
+ Updates Tag associations for a question to match the given
+@@ -92,7 +113,12 @@
+ 'WHERE tag_id = tag.id'
+ ') '
+ 'WHERE id IN (%s)')
+-
++
++ def get_valid_tags(self, page_size):
++ from forum.models import Tag
++ tags = Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-id")[:page_size]
++ return tags
++
+ def get_or_create_multiple(self, names, user):
+ """
+ Fetches a list of Tags with the given names, creating any Tags
+@@ -123,6 +149,19 @@
+ query = self.UPDATE_USED_COUNTS_QUERY % ','.join(['%s'] * len(tags))
+ cursor.execute(query, [tag.id for tag in tags])
+ transaction.commit_unless_managed()
++
++ def get_tags_by_questions(self, questions):
++ question_ids = []
++ for question in questions:
++ question_ids.append(question.id)
++
++ question_ids_str = ','.join([str(id) for id in question_ids])
++ related_tags = self.extra(
++ tables=['tag', 'question_tags'],
++ where=["tag.id = question_tags.tag_id AND question_tags.question_id IN (" + question_ids_str + ")"]
++ ).distinct()
++
++ return related_tags
+
+ class AnswerManager(models.Manager):
+ GET_ANSWERS_FROM_USER_QUESTIONS = u'SELECT answer.* FROM answer INNER JOIN question ON answer.question_id = question.id WHERE question.author_id =%s AND answer.author_id <> %s'
+@@ -205,4 +244,16 @@
+ return row[0]
+
+ else:
+- return 0
+\ No newline at end of file
++ return 0
++class AwardManager(models.Manager):
++ def get_recent_awards(self):
++ awards = super(AwardManager, self).extra(
++ select={'badge_id': 'badge.id', 'badge_name':'badge.name',
++ 'badge_description': 'badge.description', 'badge_type': 'badge.type',
++ 'user_id': 'auth_user.id', 'user_name': 'auth_user.username'
++ },
++ tables=['award', 'badge', 'auth_user'],
++ order_by=['-awarded_at'],
++ where=['auth_user.id=award.user_id AND badge_id=badge.id'],
++ ).values('badge_id', 'badge_name', 'badge_description', 'badge_type', 'user_id', 'user_name')
++ return awards
+diff -ruN CNPROG/forum/models.py mikes/forum/models.py
+--- CNPROG/forum/models.py 2009-06-22 21:42:50.000000000 -0400
++++ mikes/forum/models.py 2009-07-25 19:09:58.108151006 -0400
+@@ -351,7 +350,8 @@
+ content_object = generic.GenericForeignKey('content_type', 'object_id')
+ awarded_at = models.DateTimeField(default=datetime.datetime.now)
+ notified = models.BooleanField(default=False)
+-
++ objects = AwardManager()
++
+ def __unicode__(self):
+ return u'[%s] is awarded a badge [%s] at %s' % (self.user.username, self.badge.name, self.awarded_at)
+
+diff -ruN CNPROG/forum/templatetags/extra_tags.py mikes/forum/templatetags/extra_tags.py
+--- CNPROG/forum/templatetags/extra_tags.py 2009-06-22 21:42:50.000000000 -0400
++++ mikes/forum/templatetags/extra_tags.py 2009-07-25 19:09:58.108151006 -0400
+@@ -1,4 +1,4 @@
+-import time
++锘縤mport time
+ import datetime
+ import math
+ import re
+@@ -50,10 +49,10 @@
+ weight = 0
+ return MIN_FONTSIZE + round((MAX_FONTSIZE - MIN_FONTSIZE) * weight)
+
+-
++
+ LEADING_PAGE_RANGE_DISPLAYED = TRAILING_PAGE_RANGE_DISPLAYED = 5
+ LEADING_PAGE_RANGE = TRAILING_PAGE_RANGE = 4
+-NUM_PAGES_OUTSIDE_RANGE = 1
++NUM_PAGES_OUTSIDE_RANGE = 1
+ ADJACENT_PAGES = 2
+ @register.inclusion_tag("paginator.html")
+ def cnprog_paginator(context):
+@@ -65,10 +64,10 @@
+ " Initialize variables "
+ in_leading_range = in_trailing_range = False
+ pages_outside_leading_range = pages_outside_trailing_range = range(0)
+-
++
+ if (context["pages"] <= LEADING_PAGE_RANGE_DISPLAYED):
+ in_leading_range = in_trailing_range = True
+- page_numbers = [n for n in range(1, context["pages"] + 1) if n > 0 and n <= context["pages"]]
++ page_numbers = [n for n in range(1, context["pages"] + 1) if n > 0 and n <= context["pages"]]
+ elif (context["page"] <= LEADING_PAGE_RANGE):
+ in_leading_range = True
+ page_numbers = [n for n in range(1, LEADING_PAGE_RANGE_DISPLAYED + 1) if n > 0 and n <= context["pages"]]
+@@ -77,11 +76,11 @@
+ in_trailing_range = True
+ page_numbers = [n for n in range(context["pages"] - TRAILING_PAGE_RANGE_DISPLAYED + 1, context["pages"] + 1) if n > 0 and n <= context["pages"]]
+ pages_outside_trailing_range = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)]
+- else:
++ else:
+ page_numbers = [n for n in range(context["page"] - ADJACENT_PAGES, context["page"] + ADJACENT_PAGES + 1) if n > 0 and n <= context["pages"]]
+ pages_outside_leading_range = [n + context["pages"] for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)]
+ pages_outside_trailing_range = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)]
+-
++
+ extend_url = context.get('extend_url', '')
+ return {
+ "base_url": context["base_url"],
+@@ -205,12 +197,12 @@
+ m = re.match(pattern, strValue)
+ return first + result
+
+-@register.simple_tag
++@register.simple_tag
+ def convert2tagname_list(question):
+ question['tagnames'] = [name for name in question['tagnames'].split(u' ')]
+ return ''
+
+-@register.simple_tag
++@register.simple_tag
+ def diff_date(date, limen=2):
+ current_time = datetime.datetime(*time.localtime()[0:6])
+ diff = current_time - date
+@@ -237,4 +229,4 @@
+ timestr = strftime("%H:%M %b-%d-%Y %Z", localtime(latest))
+ except:
+ timestr = ''
+- return timestr
++ return timestr
+\ No newline at end of file
+diff -ruN CNPROG/forum/user.py mikes/forum/user.py
+--- CNPROG/forum/user.py 2009-06-22 21:42:50.000000000 -0400
++++ mikes/forum/user.py 2009-07-25 19:09:58.108151006 -0400
+@@ -1,3 +1,4 @@
++锘# coding=utf-8
+ from django.utils.translation import ugettext as _
+ class UserView:
+ def __init__(self, id, tab_title, tab_description, page_title, view_name, template_file, data_size=0):
+diff -ruN CNPROG/forum/views.py mikes/forum/views.py
+--- CNPROG/forum/views.py 2009-06-22 21:42:50.000000000 -0400
++++ mikes/forum/views.py 2009-07-25 19:09:58.108151006 -0400
+@@ -77,29 +76,17 @@
+ orderby = "-last_activity_at"
+ # group questions by author_id of 28,29
+ if view_id == 'trans':
+- questions = Question.objects.filter(deleted=False, author__id__in=[28,29]).order_by(orderby)[:INDEX_PAGE_SIZE]
++ questions = Question.objects.get_translation_questions(orderby, INDEX_PAGE_SIZE)
+ else:
+- questions = Question.objects.filter(deleted=False).order_by(orderby)[:INDEX_PAGE_SIZE]
++ questions = Question.objects.get_questions_by_pagesize(orderby, INDEX_PAGE_SIZE)
+ # RISK - inner join queries
+- questions = questions.select_related();
+- tags = Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-id")[:INDEX_TAGS_SIZE]
++ questions = questions.select_related()
++ tags = Tag.objects.get_valid_tags(INDEX_TAGS_SIZE)
+
+- awards = Award.objects.extra(
+- select={'badge_id': 'badge.id', 'badge_name':'badge.name',
+- 'badge_description': 'badge.description', 'badge_type': 'badge.type',
+- 'user_id': 'auth_user.id', 'user_name': 'auth_user.username'
+- },
+- tables=['award', 'badge', 'auth_user'],
+- order_by=['-awarded_at'],
+- where=['auth_user.id=award.user_id AND badge_id=badge.id'],
+- ).values('badge_id', 'badge_name', 'badge_description', 'badge_type', 'user_id', 'user_name')
+-
+- class testvar:
+- content = 'haha'
++ awards = Award.objects.get_recent_awards()
+
+ return render_to_response('index.html', {
+ "questions" : questions,
+- 'testvar':testvar,
+ "tab_id" : view_id,
+ "tags" : tags,
+ "awards" : awards[:INDEX_AWARD_SIZE],
+@@ -127,29 +114,11 @@
+ # Set flag to False by default. If it is equal to True, then need to be saved.
+ pagesize_changed = False
+ # get pagesize from session, if failed then get default value
+- user_page_size = request.session.get("pagesize", QUESTIONS_PAGE_SIZE)
+- # set pagesize equal to logon user specified value in database
+- if request.user.is_authenticated() and request.user.questions_per_page > 0:
+- user_page_size = request.user.questions_per_page
+-
++ pagesize = request.session.get("pagesize")
+ try:
+ page = int(request.GET.get('page', '1'))
+- # get new pagesize from UI selection
+- pagesize = int(request.GET.get('pagesize', user_page_size))
+- if pagesize <> user_page_size:
+- pagesize_changed = True
+-
+ except ValueError:
+ page = 1
+- pagesize = user_page_size
+-
+- # save this pagesize to user database
+- if pagesize_changed:
+- request.session["pagesize"] = pagesize
+- if request.user.is_authenticated():
+- user = request.user
+- user.questions_per_page = pagesize
+- user.save()
+
+ view_id = request.GET.get('sort', None)
+ view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" }
+@@ -161,29 +130,24 @@
+
+ # check if request is from tagged questions
+ if tagname is not None:
+- #print datetime.datetime.now()
+- objects = Question.objects.filter(deleted=False, tags__name = unquote(tagname)).order_by(orderby)
+- #print datetime.datetime.now()
++ objects = Question.objects.get_questions_by_tag(tagname, orderby)
+ elif unanswered:
+ #check if request is from unanswered questions
+ template_file = "unanswered.html"
+- objects = Question.objects.filter(deleted=False, answer_count=0).order_by(orderby)
++ objects = Question.objects.get_unanswered_questions(orderby)
+ else:
+- objects = Question.objects.filter(deleted=False).order_by(orderby)
++ objects = Question.objects.get_questions(orderby)
+
+ # RISK - inner join queries
+- objects = objects.select_related();
++ objects = objects.select_related(depth=1);
+ objects_list = Paginator(objects, pagesize)
+ questions = objects_list.page(page)
+
+ # Get related tags from this page objects
+- related_tags = []
+- for question in questions.object_list:
+- tags = list(question.tags.all())
+- for tag in tags:
+- if tag not in related_tags:
+- related_tags.append(tag)
+-
++ if questions.object_list.count() > 0:
++ related_tags = Tag.objects.get_tags_by_questions(questions.object_list)
++ else:
++ related_tags = None
+ return render_to_response(template_file, {
+ "questions" : questions,
+ "tab_id" : view_id,
+@@ -1022,6 +986,7 @@
+ 'title',
+ 'author_id',
+ 'accepted',
++ 'vote_count',
+ 'answer_count',
+ 'vote_up_count',
+ 'vote_down_count')[:100]
+@@ -1090,7 +1055,8 @@
+ 'activity_type' : 'activity.activity_type'
+ },
+ tables=['activity', 'question'],
+- where=['activity.content_type_id = %s AND activity.object_id = question.id AND activity.user_id = %s AND activity.activity_type = %s'],
++ where=['activity.content_type_id = %s AND activity.object_id = ' +
++ 'question.id AND activity.user_id = %s AND activity.activity_type = %s'],
+ params=[question_type_id, user_id, TYPE_ACTIVITY_ASK_QUESTION],
+ order_by=['-activity.active_at']
+ ).values(
+@@ -1114,8 +1080,8 @@
+ '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 activity.user_id=%s AND activity.activity_type=%s'],
++ where=['activity.content_type_id = %s AND activity.object_id = answer.id AND ' +
++ 'answer.question_id=question.id AND activity.user_id=%s AND activity.activity_type=%s'],
+ params=[answer_type_id, user_id, TYPE_ACTIVITY_ANSWER],
+ order_by=['-activity.active_at']
+ ).values(
+@@ -1140,7 +1106,9 @@
+ },
+ tables=['activity', 'question', 'comment'],
+
+- where=['activity.content_type_id = %s AND activity.object_id = comment.id AND activity.user_id = comment.user_id AND comment.object_id=question.id AND comment.content_type_id=%s AND activity.user_id = %s AND activity.activity_type=%s'],
++ where=['activity.content_type_id = %s AND activity.object_id = comment.id AND '+
++ 'activity.user_id = comment.user_id AND comment.object_id=question.id AND '+
++ 'comment.content_type_id=%s AND activity.user_id = %s AND activity.activity_type=%s'],
+ params=[comment_type_id, question_type_id, user_id, TYPE_ACTIVITY_COMMENT_QUESTION],
+ order_by=['-comment.added_at']
+ ).values(
+@@ -1166,7 +1134,10 @@
+ },
+ tables=['activity', 'question', 'answer', 'comment'],
+
+- where=['activity.content_type_id = %s AND activity.object_id = comment.id AND activity.user_id = comment.user_id AND comment.object_id=answer.id AND comment.content_type_id=%s AND question.id = answer.question_id AND activity.user_id = %s AND activity.activity_type=%s'],
++ where=['activity.content_type_id = %s AND activity.object_id = comment.id AND '+
++ 'activity.user_id = comment.user_id AND comment.object_id=answer.id AND '+
++ 'comment.content_type_id=%s AND question.id = answer.question_id AND '+
++ 'activity.user_id = %s AND activity.activity_type=%s'],
+ params=[comment_type_id, answer_type_id, user_id, TYPE_ACTIVITY_COMMENT_ANSWER],
+ order_by=['-comment.added_at']
+ ).values(
+@@ -1192,7 +1163,9 @@
+ 'summary' : 'question_revision.summary'
+ },
+ tables=['activity', 'question_revision'],
+- where=['activity.content_type_id = %s AND activity.object_id = question_revision.id AND activity.user_id = question_revision.author_id AND activity.user_id = %s AND activity.activity_type=%s'],
++ where=['activity.content_type_id = %s AND activity.object_id = question_revision.id AND '+
++ 'activity.user_id = question_revision.author_id AND activity.user_id = %s AND '+
++ 'activity.activity_type=%s'],
+ params=[question_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_QUESTION],
+ order_by=['-activity.active_at']
+ ).values(
+@@ -1220,7 +1193,10 @@
+ },
+ tables=['activity', 'answer_revision', 'question', 'answer'],
+
+- where=['activity.content_type_id = %s AND activity.object_id = answer_revision.id AND activity.user_id = answer_revision.author_id AND activity.user_id = %s AND answer_revision.answer_id=answer.id AND answer.question_id = question.id AND activity.activity_type=%s'],
++ where=['activity.content_type_id = %s AND activity.object_id = answer_revision.id AND '+
++ 'activity.user_id = answer_revision.author_id AND activity.user_id = %s AND '+
++ 'answer_revision.answer_id=answer.id AND answer.question_id = question.id AND '+
++ 'activity.activity_type=%s'],
+ params=[answer_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_ANSWER],
+ order_by=['-activity.active_at']
+ ).values(
+@@ -1246,7 +1222,9 @@
+ 'activity_type' : 'activity.activity_type',
+ },
+ tables=['activity', 'answer', 'question'],
+- where=['activity.content_type_id = %s AND activity.object_id = answer.id AND activity.user_id = question.author_id AND activity.user_id = %s AND answer.question_id=question.id AND activity.activity_type=%s'],
++ where=['activity.content_type_id = %s AND activity.object_id = answer.id AND '+
++ 'activity.user_id = question.author_id AND activity.user_id = %s AND '+
++ 'answer.question_id=question.id AND activity.activity_type=%s'],
+ params=[answer_type_id, user_id, TYPE_ACTIVITY_MARK_ANSWER],
+ order_by=['-activity.active_at']
+ ).values(
+@@ -1267,7 +1245,8 @@
+ 'activity_type' : 'activity.activity_type'
+ },
+ tables=['activity', 'award', 'badge'],
+- where=['activity.user_id = award.user_id AND activity.user_id = %s AND award.badge_id=badge.id AND activity.object_id=award.id AND activity.activity_type=%s'],
++ where=['activity.user_id = award.user_id AND activity.user_id = %s AND '+
++ 'award.badge_id=badge.id AND activity.object_id=award.id AND activity.activity_type=%s'],
+ params=[user_id, TYPE_ACTIVITY_PRIZE],
+ order_by=['-activity.active_at']
+ ).values(
+@@ -1320,7 +1299,8 @@
+ },
+ select_params=[user_id],
+ tables=['answer', 'question', 'auth_user'],
+- where=['answer.question_id = question.id AND answer.deleted=0 AND question.deleted = 0 AND question.author_id = %s AND answer.author_id <> %s AND answer.author_id=auth_user.id'],
++ where=['answer.question_id = question.id AND answer.deleted=0 AND question.deleted = 0 AND '+
++ 'question.author_id = %s AND answer.author_id <> %s AND answer.author_id=auth_user.id'],
+ params=[user_id, user_id],
+ order_by=['-answer.id']
+ ).values(
+@@ -1349,7 +1329,8 @@
+ 'user_id' : 'auth_user.id'
+ },
+ tables=['question', 'auth_user', 'comment'],
+- where=['question.deleted = 0 AND question.author_id = %s AND comment.object_id=question.id AND comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id'],
++ where=['question.deleted = 0 AND question.author_id = %s AND comment.object_id=question.id AND '+
++ 'comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id'],
+ params=[user_id, question_type_id, user_id],
+ order_by=['-comment.added_at']
+ ).values(
+@@ -1378,7 +1359,9 @@
+ 'user_id' : 'auth_user.id'
+ },
+ tables=['answer', 'auth_user', 'comment', 'question'],
+- where=['answer.deleted = 0 AND answer.author_id = %s AND comment.object_id=answer.id AND comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id AND question.id = answer.question_id'],
++ where=['answer.deleted = 0 AND answer.author_id = %s AND comment.object_id=answer.id AND '+
++ 'comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id '+
++ 'AND question.id = answer.question_id'],
+ params=[user_id, answer_type_id, user_id],
+ order_by=['-comment.added_at']
+ ).values(
+@@ -1409,7 +1392,8 @@
+ },
+ select_params=[user_id],
+ tables=['answer', 'question', 'auth_user'],
+- where=['answer.question_id = question.id AND answer.deleted=0 AND question.deleted = 0 AND answer.author_id = %s AND answer.accepted=1 AND question.author_id=auth_user.id'],
++ where=['answer.question_id = question.id AND answer.deleted=0 AND question.deleted = 0 AND '+
++ 'answer.author_id = %s AND answer.accepted=1 AND question.author_id=auth_user.id'],
+ params=[user_id],
+ order_by=['-answer.id']
+ ).values(
+@@ -1453,7 +1437,8 @@
+ },
+ select_params=[user_id],
+ tables=['vote', 'question', 'auth_user'],
+- where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = question.id AND vote.user_id=auth_user.id'],
++ where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = question.id '+
++ 'AND vote.user_id=auth_user.id'],
+ params=[question_type_id, user_id],
+ order_by=['-vote.id']
+ ).values(
+@@ -1476,7 +1461,8 @@
+ },
+ select_params=[user_id],
+ tables=['vote', 'answer', 'question', 'auth_user'],
+- where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = answer.id AND answer.question_id = question.id AND vote.user_id=auth_user.id'],
++ where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = answer.id '+
++ 'AND answer.question_id = question.id AND vote.user_id=auth_user.id'],
+ params=[answer_type_id, user_id],
+ order_by=['-vote.id']
+ ).values(
+@@ -1501,7 +1487,8 @@
+ 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'},
++ 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'],
+@@ -1510,6 +1497,7 @@
+
+ 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)
+@@ -1531,7 +1519,8 @@
+ questions = Question.objects.extra(
+ select={
+ 'vote_count' : 'question.vote_up_count + question.vote_down_count',
+- 'favorited_myself' : 'SELECT count(*) FROM favorite_question f WHERE f.user_id = %s AND f.question_id = question.id',
++ 'favorited_myself' : 'SELECT count(*) FROM favorite_question f WHERE f.user_id = %s '+
++ 'AND f.question_id = question.id',
+ 'la_user_id' : 'auth_user.id',
+ 'la_username' : 'auth_user.username',
+ 'la_user_gold' : 'auth_user.gold',
+@@ -1541,7 +1530,8 @@
+ },
+ select_params=[user_id],
+ tables=['question', 'auth_user', 'favorite_question'],
+- where=['question.deleted = 0 AND question.last_activity_by_id = auth_user.id AND favorite_question.question_id = question.id AND favorite_question.user_id = %s'],
++ where=['question.deleted = 0 AND question.last_activity_by_id = auth_user.id '+
++ 'AND favorite_question.question_id = question.id AND favorite_question.user_id = %s'],
+ params=[user_id],
+ order_by=['-vote_count', '-question.id']
+ ).values('vote_count',
+@@ -1672,7 +1662,12 @@
+ def badge(request, id):
+ badge = get_object_or_404(Badge, id=id)
+ awards = Award.objects.extra(
+- select={'id': 'auth_user.id', 'name': 'auth_user.username', 'rep':'auth_user.reputation', 'gold': 'auth_user.gold', 'silver': 'auth_user.silver', 'bronze': 'auth_user.bronze'},
++ select={'id': 'auth_user.id',
++ 'name': 'auth_user.username',
++ 'rep':'auth_user.reputation',
++ 'gold': 'auth_user.gold',
++ 'silver': 'auth_user.silver',
++ 'bronze': 'auth_user.bronze'},
+ tables=['award', 'auth_user'],
+ where=['badge_id=%s AND user_id=auth_user.id'],
+ params=[id]
+diff -ruN CNPROG/INSTALL mikes/INSTALL
+--- CNPROG/INSTALL 1969-12-31 19:00:00.000000000 -0500
++++ mikes/INSTALL 2009-07-25 19:09:58.068150962 -0400
+@@ -0,0 +1,33 @@
++PRE-REQUIREMENTS:
++-----------------------------------------------
++1. Python2.5, MySQL, Django v1.0+
++
++2. Python-openid v2.2
++http://openidenabled.com/python-openid/
++
++3. django-authopenid(Included in project already)
++http://code.google.com/p/django-authopenid/
++
++4. html5lib
++http://code.google.com/p/html5lib/
++Used for HTML sanitizer
++
++5. Markdown2
++http://code.google.com/p/python-markdown2/
++
++
++INSTALL STEPS:
++-----------------------------------------------
++1. Copy settings_local.py.dist to settings_local.py and
++update all your settings. Check settings.py and update
++it as well if necessory.
++
++2. Prepare your database by using the same database/account
++configuration from above.
++
++3. Run "python manager.py runserver" to startup django
++development environment.
++
++4. There are some demo scripts under sql_scripts folder,
++including badges and test accounts for CNProg.com. You
++don't need them to run your sample.
+diff -ruN CNPROG/junk mikes/junk
+--- CNPROG/junk 2009-06-22 21:42:52.000000000 -0400
++++ mikes/junk 1969-12-31 19:00:00.000000000 -0500
+@@ -1,7 +0,0 @@
+-/branches/beta2/forum/feed.py r110 line 17:
+-/branches/beta2/forum/feed.py r110 line 20:
+-/branches/beta2/forum/forms.py r110 line 63:
+-/branches/beta2/templates/question.html r120 line 237:
+-/branches/beta2/templates/question.html r120 line 57:
+-/branches/beta2/templates/question.html r120 line 456:
+-/branches/beta2/forum/views.py r127 line 1088:
+diff -ruN CNPROG/lanai.psproj mikes/lanai.psproj
+--- CNPROG/lanai.psproj 2009-06-22 21:42:52.000000000 -0400
++++ mikes/lanai.psproj 1969-12-31 19:00:00.000000000 -0500
+@@ -1,557 +0,0 @@
+-[PyScripter]
+-Version=1.9.9.3
+-
+-[Project]
+-ClassName=TProjectRootNode
+-StoreRelativePaths=FALSE
+-ShowFileExtensions=FALSE
+-
+-[Project\ChildNodes]
+-Count=2
+-
+-[Project\ChildNodes\Node0]
+-ClassName=TProjectFilesNode
+-
+-[Project\ChildNodes\Node0\ChildNodes]
+-Count=1
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0]
+-ClassName=TProjectFolderNode
+-Name=src
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes]
+-Count=10
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0]
+-ClassName=TProjectFolderNode
+-Name=django_authopenid
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0\ChildNodes]
+-Count=9
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\django_authopenid\__init__.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\django_authopenid\admin.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\django_authopenid\forms.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\django_authopenid\middleware.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node4]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\django_authopenid\mimeparse.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node5]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\django_authopenid\models.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node6]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\django_authopenid\urls.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node7]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\django_authopenid\util.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node8]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\django_authopenid\views.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1]
+-ClassName=TProjectFolderNode
+-Name=forum
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes]
+-Count=12
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node0]
+-ClassName=TProjectFolderNode
+-Name=management
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node0\ChildNodes]
+-Count=2
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node0]
+-ClassName=TProjectFolderNode
+-Name=commands
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node0\ChildNodes]
+-Count=3
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\management\commands\__init__.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\management\commands\mark_offensive_cron.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\management\commands\sample_command.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node1]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\management\__init__.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node1]
+-ClassName=TProjectFolderNode
+-Name=templatetags
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node1\ChildNodes]
+-Count=3
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node1\ChildNodes\Node0]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\templatetags\__init__.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node1\ChildNodes\Node1]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\templatetags\extra_filters.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node1\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\templatetags\extra_tags.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\__init__.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node3]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\admin.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node4]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\auth.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node5]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\const.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node6]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\diff.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node7]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\forms.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node8]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\managers.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node9]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\models.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node10]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\user.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1\ChildNodes\Node11]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\forum\views.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2]
+-ClassName=TProjectFolderNode
+-Name=sql_scripts
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2\ChildNodes]
+-Count=6
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2\ChildNodes\Node0]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\sql_scripts\cnprog_new_install.sql
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2\ChildNodes\Node1]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\sql_scripts\update_2009_01_13_001.sql
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\sql_scripts\update_2009_01_13_002.sql
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2\ChildNodes\Node3]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\sql_scripts\update_2009_12_24_001.sql
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2\ChildNodes\Node4]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\sql_scripts\update_2009_12_27_001.sql
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2\ChildNodes\Node5]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\sql_scripts\update_2009_12_27_002.sql
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3]
+-ClassName=TProjectFolderNode
+-Name=templates
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes]
+-Count=44
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0]
+-ClassName=TProjectFolderNode
+-Name=authopenid
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes]
+-Count=10
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes\Node0]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\authopenid\changeemail.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes\Node1]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\authopenid\changeopenid.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\authopenid\changepw.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes\Node3]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\authopenid\complete.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes\Node4]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\authopenid\delete.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes\Node5]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\authopenid\failure.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes\Node6]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\authopenid\sendpw.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes\Node7]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\authopenid\settings.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes\Node8]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\authopenid\signin.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node0\ChildNodes\Node9]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\authopenid\signup.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1]
+-ClassName=TProjectFolderNode
+-Name=content
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes]
+-Count=2
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0]
+-ClassName=TProjectFolderNode
+-Name=js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes]
+-Count=10
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node0]
+-ClassName=TProjectFolderNode
+-Name=wmd
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node0\ChildNodes]
+-Count=3
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node0]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\wmd\showdown.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node1]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\wmd\wmd-base.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\wmd\wmd-plus.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node1]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\com.cnprog.editor.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\com.cnprog.post.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node3]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\com.cnprog.utils.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node4]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\excanvas.pack.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node5]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\jquery.flot.pack.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node6]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\jquery.openid.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node7]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\jquery.validate.pack.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node8]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\jquery-1.2.6.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node0\ChildNodes\Node9]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\js\jquery-1.2.6.min.js
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node1]
+-ClassName=TProjectFolderNode
+-Name=style
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node1\ChildNodes]
+-Count=4
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node1\ChildNodes\Node0]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\style\default.css
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node1\ChildNodes\Node1]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\style\jquery.autocomplete.css
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node1\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\style\openid.css
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node1\ChildNodes\Node1\ChildNodes\Node3]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\content\style\prettify.css
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\404.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node3]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\500.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node4]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\about.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node5]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\answer_edit.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node6]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\ask.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node7]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\badge.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node8]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\badges.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node9]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\base.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node10]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\base_content.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node11]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\close.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node12]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\faq.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node13]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\footer.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node14]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\header.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node15]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\index.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node16]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\logout.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node17]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\pagesize.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node18]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\paginator.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node19]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\privacy.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node20]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\question.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node21]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\question_edit.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node22]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\question_retag.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node23]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\questions.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node24]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\reopen.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node25]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\revisions_answer.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node26]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\revisions_question.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node27]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\sidebar.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node28]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\tags.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node29]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\unanswered.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node30]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node31]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_edit.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node32]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_favorites.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node33]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_footer.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node34]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_info.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node35]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_preferences.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node36]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_recent.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node37]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_reputation.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node38]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_responses.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node39]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_stats.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node40]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_tabs.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node41]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\user_votes.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node42]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\users.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node3\ChildNodes\Node43]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\templates\users_questions.html
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node4]
+-ClassName=TProjectFolderNode
+-Name=utils
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node4\ChildNodes]
+-Count=4
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node4\ChildNodes\Node0]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\utils\__init__.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node4\ChildNodes\Node1]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\utils\cache.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node4\ChildNodes\Node2]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\utils\html.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node4\ChildNodes\Node3]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\utils\lists.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node5]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\__init__.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node6]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\manage.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node7]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\settings.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node8]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\test.py
+-
+-[Project\ChildNodes\Node0\ChildNodes\Node0\ChildNodes\Node9]
+-ClassName=TProjectFileNode
+-FileName=C:\Projects\Lanai\src\urls.py
+-
+-[Project\ChildNodes\Node1]
+-ClassName=TProjectRunConfiguationsNode
+-
+-[Project\ExtraPythonPath]
+-Count=0
+-
+diff -ruN CNPROG/LICENSE mikes/LICENSE
+--- CNPROG/LICENSE 2009-06-22 21:42:52.000000000 -0400
++++ mikes/LICENSE 2009-07-25 19:09:58.088150984 -0400
+@@ -1,12 +1,14 @@
+-版权所有(c) 2008 CNProg.com
++Copyright (C) 2009. Chen Gang
+
+-根据2.0版本Apache许可证("许可证")授权;
+-根据本许可证,用户可以不使用此文件。
+-用户可从下列网址获得许可证副本:
++This program is free software: you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation, either version 3 of the License, or
++(at your option) any later version.
+
+-http://www.apache.org/licenses/LICENSE-2.0
++This program is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++GNU General Public License for more details.
+
+-除非因适用法律需要或书面同意,
+-根据许可证分发的软件是基于"按原样"基础提供,
+-无任何明示的或暗示的保证或条件。
+-详见根据许可证许可下,特定语言的管辖权限和限制。
+\ No newline at end of file
++You should have received a copy of the GNU General Public License
++along with this program. If not, see <http://www.gnu.org/licenses/>.
+diff -ruN CNPROG/locale/zh_CN/LC_MESSAGES/django.po mikes/locale/zh_CN/LC_MESSAGES/django.po
+--- CNPROG/locale/zh_CN/LC_MESSAGES/django.po 1969-12-31 19:00:00.000000000 -0500
++++ mikes/locale/zh_CN/LC_MESSAGES/django.po 2009-07-25 19:09:58.108151006 -0400
+@@ -0,0 +1,629 @@
++# Chinese translations for CNProg.com
++# Copyright (C) 2009
++# This file is distributed under the same license as the CNPROG package.
++# Mike Chen <chagel@gmail.com>, 2009.
++#
++#, fuzzy
++msgid ""
++msgstr ""
++"Project-Id-Version: PACKAGE VERSION\n"
++"Report-Msgid-Bugs-To: \n"
++"POT-Creation-Date: 2009-07-15 13:53+0000\n"
++"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
++"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
++"Language-Team: LANGUAGE <LL@li.org>\n"
++"MIME-Version: 1.0\n"
++"Content-Type: text/plain; charset=UTF-8\n"
++"Content-Transfer-Encoding: 8bit\n"
++
++#: settings.py:12
++msgid "account/"
++msgstr ""
++
++#: settings.py:12 django_authopenid/urls.py:9 django_authopenid/urls.py:11
++msgid "signin/"
++msgstr ""
++
++#: django_authopenid/forms.py:67 django_authopenid/views.py:93
++msgid "i-names are not supported"
++msgstr "i-names涓嶆敮鎸併"
++
++#: django_authopenid/forms.py:102 django_authopenid/forms.py:207
++msgid ""
++"Usernames can only contain letters, numbers and "
++"underscores"
++msgstr "鐢ㄦ埛鍚嶆牸寮忔湁璇傚彧鏈夊瓧姣嶏紝鏁板瓧鍜屼笅鍒掔嚎鏄厑璁哥殑銆"
++
++#: django_authopenid/forms.py:109
++msgid ""
++"This username does not exist in our database. Please "
++"choose another."
++msgstr "鐢ㄦ埛鍚嶄笉瀛樺湪銆傝閲嶆柊杈撳叆銆"
++
++#: django_authopenid/forms.py:126 django_authopenid/forms.py:231
++msgid ""
++"Please enter a valid username and password. Note that "
++"both fields are case-sensitive."
++msgstr "璇疯緭鍏ョ敤鎴峰悕鍜屽瘑鐮併傛敞鎰忓尯鍒嗗ぇ灏忓啓銆"
++
++#: django_authopenid/forms.py:130 django_authopenid/forms.py:235
++msgid "This account is inactive."
++msgstr "鐢ㄦ埛宸插喕缁撱"
++
++#: django_authopenid/forms.py:184
++msgid ""
++"This email is already registered in our database. Please "
++"choose another."
++msgstr "鐢靛瓙閭欢宸茶娉ㄥ唽銆傝浣跨敤涓涓柊鐨勯偖浠跺湴鍧銆"
++
++#: django_authopenid/forms.py:214
++msgid ""
++"This username don't exist. Please choose another."
++msgstr "鐢ㄦ埛鍚嶄笉瀛樺湪"
++
++#: django_authopenid/forms.py:330
++msgid ""
++"Old password is incorrect. Please enter the correct "
++"password."
++msgstr "鏃у瘑鐮侀敊璇"
++
++#: django_authopenid/forms.py:342
++msgid "new passwords do not match"
++msgstr "鏂板瘑鐮佷笉鍖归厤"
++
++#: django_authopenid/forms.py:434
++msgid "Incorrect username."
++msgstr "鐢ㄦ埛鍚嶄笉姝g‘"
++
++#: django_authopenid/urls.py:10
++msgid "signout/"
++msgstr ""
++
++#: django_authopenid/urls.py:11
++msgid "complete/"
++msgstr ""
++
++#: django_authopenid/urls.py:13
++msgid "register/"
++msgstr ""
++
++#: django_authopenid/urls.py:14
++msgid "signup/"
++msgstr ""
++
++#: django_authopenid/urls.py:16
++msgid "sendpw/"
++msgstr ""
++
++#: django_authopenid/urls.py:26
++msgid "delete/"
++msgstr ""
++
++#: django_authopenid/views.py:99
++#, python-format
++msgid "闈炴硶OpenID鍦板潃锛 %s"
++msgstr ""
++
++#: django_authopenid/views.py:366 templates/index.html:78
++msgid "Welcome"
++msgstr "娆㈣繋"
++
++#: django_authopenid/views.py:456
++msgid "Password changed."
++msgstr "瀵嗙爜宸叉洿鏂般"
++
++#: django_authopenid/views.py:488
++msgid "Email changed."
++msgstr "閭欢鍦板潃宸叉洿鏂般"
++
++#: django_authopenid/views.py:519 django_authopenid/views.py:671
++#, python-format
++msgid "No OpenID %s found associated in our database"
++msgstr "璇penID %s 涓嶅湪绯荤粺涓"
++
++#: django_authopenid/views.py:523 django_authopenid/views.py:678
++#, python-format
++msgid "The OpenID %s isn't associated to current user logged in"
++msgstr "OpenID %s 娌℃湁鍜屽綋鍓嶇櫥褰曠敤鎴风粦瀹氥"
++
++#: django_authopenid/views.py:531
++msgid "Email Changed."
++msgstr "閭欢鍦板潃宸叉洿鏂般"
++
++#: django_authopenid/views.py:606
++msgid "This OpenID is already associated with another account."
++msgstr "杩欎釜OpenID宸茬粡缁戝畾鍒板彟澶栦竴涓笎鍙枫"
++
++#: django_authopenid/views.py:611
++#, python-format
++msgid "OpenID %s is now associated with your account."
++msgstr "OpenID %s 宸茬粡缁戝畾鍒版偍鐨勫笎鍙枫"
++
++#: django_authopenid/views.py:681
++msgid "Account deleted."
++msgstr "甯愬彿宸插垹闄ゃ"
++
++#: django_authopenid/views.py:721
++msgid "Request for new password"
++msgstr "鎵惧洖瀵嗙爜"
++
++#: django_authopenid/views.py:734
++msgid "A new password has been sent to your email address."
++msgstr "鏂扮殑瀵嗙爜宸茬粡鍙戦佸埌鎮ㄧ殑閭欢甯愬彿銆"
++
++#: django_authopenid/views.py:764
++#, python-format
++msgid ""
++"Could not change password. Confirmation key '%s' is not "
++"registered."
++msgstr "涓嶈兘淇敼瀵嗙爜銆傜‘璁や俊鎭 '%s' 鏈夎銆"
++
++#: django_authopenid/views.py:773
++msgid ""
++"Can not change password. User don't exist anymore in our "
++"database."
++msgstr "涓嶈兘淇敼瀵嗙爜銆傜敤鎴峰笎鍙蜂笉瀛樺湪銆"
++
++#: django_authopenid/views.py:782
++#, python-format
++msgid "Password changed for %s. You may now sign in."
++msgstr "甯愬彿 %s 鐨勫瘑鐮佸凡缁忎慨鏀广傛偍鐜板湪鍙互鐢ㄥ畠鏉ョ櫥褰曘"
++
++#: forum/user.py:17
++msgid "Overview"
++msgstr "姒傝"
++
++#: forum/user.py:18
++msgid "User overview"
++msgstr "鐢ㄦ埛姒傝"
++
++#: forum/user.py:19
++msgid "Overview - User Profile"
++msgstr "姒傝-鐢ㄦ埛璧勬枡"
++
++#: forum/user.py:25
++msgid "Recent"
++msgstr "鏈杩戞椿鍔"
++
++#: forum/user.py:26
++msgid "Recent activities"
++msgstr "鐢ㄦ埛鏈杩戞椿鍔ㄦ儏鍐"
++
++#: forum/user.py:27
++msgid "Recent - User Profile"
++msgstr "鏈杩戞椿鍔-鐢ㄦ埛璧勬枡"
++
++#: forum/user.py:34
++msgid "Response"
++msgstr "鍥炲簲"
++
++#: forum/user.py:35
++msgid "Responses from others"
++msgstr "鍏朵粬鐢ㄦ埛鐨勫洖绛斿拰璇勮"
++
++#: forum/user.py:36
++msgid "Response - User Profile"
++msgstr "鍥炲簲-鐢ㄦ埛璧勬枡"
++
++#: forum/user.py:43
++msgid "Reputation"
++msgstr "绉垎"
++
++#: forum/user.py:44
++msgid "Community reputation"
++msgstr "绀惧尯绉垎"
++
++#: forum/user.py:45
++msgid "Reputation - User Profile"
++msgstr "绉垎-鐢ㄦ埛璧勬枡"
++
++#: forum/user.py:51
++msgid "Favorites"
++msgstr "鏀惰棌"
++
++#: forum/user.py:52
++msgid "User's favorite questions"
++msgstr "鐢ㄦ埛鏀惰棌鐨勯棶棰"
++
++#: forum/user.py:53
++msgid "Favorites - User Profile"
++msgstr "鏀惰棌-鐢ㄦ埛璧勬枡"
++
++#: forum/user.py:60 templates/index.html:46 templates/questions.html:45
++msgid "Votes"
++msgstr "鎶曠エ"
++
++#: forum/user.py:61
++msgid "Votes history"
++msgstr "鐢ㄦ埛鎶曠エ鍘嗗彶"
++
++#: forum/user.py:62
++msgid "Votes - User Profile"
++msgstr "鎶曠エ-鐢ㄦ埛璧勬枡"
++
++#: forum/user.py:69
++msgid "Preferences"
++msgstr "璁剧疆"
++
++#: forum/user.py:70
++msgid "User preferences"
++msgstr "鐢ㄦ埛鍙傛暟璁剧疆"
++
++#: forum/user.py:71
++msgid "Preferences - User Profile"
++msgstr "璁剧疆-鐢ㄦ埛璧勬枡"
++
++#: templates/badges.html:5 templates/badges.html.py:16
++#: templates/header.html:31
++msgid "Badges"
++msgstr "濂栫墝姒"
++
++#: templates/base.html:53 templates/base_content.html:52
++msgid "Congratulations! You have new badges: "
++msgstr "鎭枩鎮ㄨ鎺堜簣濂栫墝锛"
++
++#: templates/base.html:54 templates/base_content.html:53
++msgid "go to see"
++msgstr "鏌ョ湅"
++
++#: templates/base.html:55 templates/base_content.html:54
++#: templates/header.html:35
++msgid "Profile"
++msgstr "鎴戠殑璧勬枡"
++
++#: templates/footer.html:5 templates/header.html:10 templates/index.html:81
++msgid "About us"
++msgstr "鍏充簬鎴戜滑"
++
++#: templates/footer.html:6 templates/header.html:11
++msgid "faq"
++msgstr "甯歌闂"
++
++#: templates/footer.html:8
++msgid "Contact"
++msgstr "鑱旂郴鎴戜滑"
++
++#: templates/footer.html:9
++msgid "Privacy"
++msgstr "闅愮鏀跨瓥"
++
++#: templates/footer.html:10
++msgid "Feedback"
++msgstr "鐢ㄦ埛鍙嶉"
++
++#: templates/header.html:6 templates/logout.html:5 templates/logout.html.py:16
++msgid "Logout"
++msgstr "閫鍑虹櫥褰"
++
++#: templates/header.html:8
++msgid "Login"
++msgstr "鐧诲綍"
++
++#: templates/header.html:21
++msgid "link to homepage"
++msgstr "杩斿洖棣栭〉"
++
++#: templates/header.html:27 templates/header.html.py:56
++#: templates/index.html:21
++msgid "Questions"
++msgstr "闂"
++
++#: templates/header.html:28 templates/header.html.py:57
++msgid "Tags"
++msgstr "鏍囩"
++
++#: templates/header.html:29 templates/header.html.py:58
++msgid "Users"
++msgstr "鐢ㄦ埛"
++
++#: templates/header.html:30
++msgid "Books"
++msgstr "璇讳功"
++
++#: templates/header.html:32
++msgid "Unanswered"
++msgstr "娌℃湁鍥炵瓟鐨勯棶棰"
++
++#: templates/header.html:38
++msgid "Ask a question"
++msgstr "鎴戣鎻愰棶"
++
++#: templates/header.html:53
++msgid "Search"
++msgstr "鎼滅储"
++
++#: templates/index.html:6
++msgid "Home"
++msgstr "棣栭〉"
++
++#: templates/index.html:23 templates/questions.html:25
++msgid "Newest updated questions"
++msgstr "鏈鏂版洿鏂扮殑闂"
++
++#: templates/index.html:23 templates/questions.html:24
++msgid "Newest"
++msgstr "鏈鏂伴棶棰"
++
++#: templates/index.html:24 templates/questions.html:26
++msgid "Questions with most answers"
++msgstr "琚洖澶嶆渶澶氱殑闂"
++
++#: templates/index.html:24 templates/questions.html:26
++msgid "Hottest"
++msgstr "鏈鐑棶棰"
++
++#: templates/index.html:25 templates/questions.html:27
++msgid "Questions with most votes"
++msgstr "琚姇绁ㄦ渶澶氱殑闂"
++
++#: templates/index.html:25 templates/questions.html:27
++msgid "Best"
++msgstr "鏈鏈変环鍊奸棶棰"
++
++#: templates/index.html:26 templates/index.html.py:118
++#: templates/questions.html:22
++msgid "All questions"
++msgstr "鎵鏈夐棶棰"
++
++#: templates/index.html:26
++msgid "All"
++msgstr "鎵鏈夐棶棰"
++
++#: templates/index.html:45 templates/questions.html:44
++msgid "Answers"
++msgstr "鍥炵瓟"
++
++#: templates/index.html:47 templates/questions.html:46
++msgid "Visits"
++msgstr "璁块棶"
++
++#: templates/index.html:55 templates/questions.html:57
++#: templates/questions.html.py:69
++msgid "Community wiki"
++msgstr "绀惧尯wiki"
++
++#: templates/index.html:67 templates/index.html.py:91
++#: templates/questions.html:83
++msgid "Browse questions with tag of "
++msgstr "鏌ョ湅鎵鏈変互涓嬩富棰橀棶棰橈細"
++
++#: templates/index.html:87
++msgid "Recent tags"
++msgstr "鏈鏂版爣绛"
++
++#: templates/index.html:94 templates/index.html.py:118
++msgid "Popular tags"
++msgstr "鍙楁杩庣殑鏍囩"
++
++#: templates/index.html:98
++msgid "Recent badges"
++msgstr "鏈鏂板鐗"
++
++#: templates/index.html:109
++msgid "All badges"
++msgstr "鎵鏈夊鐗"
++
++#: templates/index.html:113
++msgid "RSS feed of recent 30 questions"
++msgstr "RSS璁㈤槄鏈鏂30涓棶棰"
++
++#: templates/index.html:113
++msgid "Subscribe"
++msgstr "璁㈤槄鏈鏂伴棶棰"
++
++#: templates/index.html:118
++msgid "Are you looking for more questions? Try to browse"
++msgstr "鍦ㄥ鎵炬洿澶氶棶棰樺悧锛熻鏌ラ槄"
++
++#: templates/index.html:118
++msgid " or "
++msgstr " 鎴栬 "
++
++#: templates/index.html:118
++msgid ". Please help us answer "
++msgstr "銆傝甯姪鎴戜滑鍥炵瓟"
++
++#: templates/index.html:118
++msgid "Unanswered questions"
++msgstr "娌℃湁鍥炵瓟鐨勯棶棰"
++
++#: templates/pagesize.html:5
++msgid "Size per page:"
++msgstr "姣忛〉鏄剧ず锛"
++
++#: templates/paginator.html:5
++msgid "Previous"
++msgstr "涓婁竴椤"
++
++#: templates/questions.html:6
++msgid "Question list"
++msgstr "闂鍒楄〃"
++
++#: templates/questions.html:22
++msgid "Tagged questions"
++msgstr "鏍囩闂"
++
++#: templates/questions.html:22
++msgid "Query result"
++msgstr "鏌ヨ缁撴灉"
++
++#: templates/questions.html:24
++msgid "New questions"
++msgstr "鏈鏂伴棶棰"
++
++#: templates/questions.html:25
++msgid "Active"
++msgstr "娲昏穬闂"
++
++#: templates/questions.html:125
++msgid "Related tags"
++msgstr "鐩稿叧鏍囩"
++
++#: templates/authopenid/changeemail.html:10
++msgid "Account: change email"
++msgstr "淇敼鐢靛瓙閭欢"
++
++#: templates/authopenid/changeemail.html:13
++msgid ""
++"This is where you can change the email address associated with your account. "
++"Please keep this email address up to date so we can send you a password-"
++"reset email if you request one."
++msgstr ""
++"鎮ㄥ彲浠ュ湪杩欓噷淇敼鎮ㄧ殑鐢靛瓙閭欢锛岃纭繚杩欎釜閭欢鍦板潃鏈夋晥-鎵惧洖瀵嗙爜灏嗗彂閫佹柊瀵嗙爜鍒版偍"
++"鐨勯偖浠跺湴鍧銆"
++
++#: templates/authopenid/changeemail.html:15
++#: templates/authopenid/changeopenid.html:13
++#: templates/authopenid/changepw.html:18 templates/authopenid/delete.html:14
++#: templates/authopenid/delete.html:24
++msgid "Please correct errors below:"
++msgstr "璇锋敼姝d互涓嬮敊璇細"
++
++#: templates/authopenid/changeemail.html:32
++msgid "Email"
++msgstr "鐢靛瓙閭欢"
++
++#: templates/authopenid/changeemail.html:33
++msgid "Password"
++msgstr "瀵嗙爜"
++
++#: templates/authopenid/changeemail.html:35
++msgid "Change email"
++msgstr "淇敼鐢靛瓙閭欢"
++
++#: templates/authopenid/changeopenid.html:7
++msgid "Account: change OpenID URL"
++msgstr "淇敼OpenID鍦板潃"
++
++#: templates/authopenid/changeopenid.html:11
++msgid ""
++"This is where you can change your OpenID URL. Make sure you remember it!"
++msgstr "璇蜂慨鏀规偍鐨凮penID鍦板潃锛岃涓嶈蹇樿杩欎釜鍦板潃锛"
++
++#: templates/authopenid/changeopenid.html:28
++msgid "OpenID URL:"
++msgstr "OpenID鍦板潃锛"
++
++#: templates/authopenid/changeopenid.html:29
++msgid "Change OpenID"
++msgstr "淇敼OpenID"
++
++#: templates/authopenid/changepw.html:13
++msgid "Account: change password"
++msgstr "淇敼瀵嗙爜"
++
++#: templates/authopenid/changepw.html:16
++msgid "This is where you can change your password. Make sure you remember it!"
++msgstr "璇蜂慨鏀规偍鐨勫瘑鐮侊紝鍒囪涓嶈蹇樿锛"
++
++#: templates/authopenid/changepw.html:26
++msgid "Current password"
++msgstr "鏃у瘑鐮"
++
++#: templates/authopenid/changepw.html:27
++msgid "New password"
++msgstr "鏂板瘑鐮"
++
++#: templates/authopenid/changepw.html:28
++msgid "New password again"
++msgstr "閲嶅瀵嗙爜"
++
++#: templates/authopenid/changepw.html:29
++msgid "Change password"
++msgstr "淇敼瀵嗙爜"
++
++#: templates/authopenid/delete.html:8
++msgid "Account: delete account"
++msgstr "鍒犻櫎甯愬彿"
++
++#: templates/authopenid/delete.html:12
++msgid ""
++"Note: After deleting your account, anyone will be able to register this "
++"username."
++msgstr "娉ㄦ剰锛氬垹闄ゆ偍鐨勫笎鍙峰悗锛屼换浣曞叾浠栦汉鍙互鍐嶆敞鍐岃繖涓笎鍙枫"
++
++#: templates/authopenid/delete.html:16
++msgid "Check confirm box, if you want delete your account."
++msgstr "濡傛灉纭畾鍒犻櫎锛岃閫変腑澶氶夋銆"
++
++#: templates/authopenid/delete.html:19
++msgid "Password:"
++msgstr "瀵嗙爜锛"
++
++#: templates/authopenid/delete.html:31
++msgid "I am sure I want to delete my account."
++msgstr "鎴戠‘璁よ鍒犻櫎杩欎釜甯愬彿銆"
++
++#: templates/authopenid/delete.html:32
++msgid "Password/OpenID URL"
++msgstr "瀵嗙爜/OpenID鍦板潃"
++
++#: templates/authopenid/delete.html:32
++msgid "(required for your security)"
++msgstr "锛堝繀闇锛"
++
++#: templates/authopenid/delete.html:34
++msgid "Delete account permanently"
++msgstr "姘镐箙鍒犻櫎甯愬彿"
++
++#: templates/authopenid/settings.html:29
++msgid "Give your account a new password."
++msgstr "淇敼瀵嗙爜"
++
++#: templates/authopenid/settings.html:31
++msgid "Add or update the email address associated with your account."
++msgstr "娣诲姞鎴栬呮洿鏂版偍鐨勯偖浠跺湴鍧銆"
++
++#: templates/authopenid/settings.html:34
++msgid "Change openid associated to your account"
++msgstr "淇敼鍜屼綘甯愬彿缁戝畾鐨凮penID鍦板潃"
++
++#: templates/authopenid/settings.html:38
++msgid "Erase your username and all your data from website"
++msgstr "鍒犻櫎鎮ㄧ殑甯愬彿鍜屾墍鏈夊唴瀹"
++
++#, fuzzy
++#~ msgid "Badges "
++#~ msgstr "濂栫墝鍒楄〃"
++
++#~ msgid ""
++#~ "This username is already taken. Please choose another."
++#~ msgstr "鐢ㄦ埛鍚嶅凡缁忚娉ㄥ唽锛岃閫夌敤涓涓柊鐨勫笎鍙枫"
++
++#~ msgid "Your OpenID is verified! "
++#~ msgstr "鎮ㄧ殑OpenID甯愬彿宸茬粡楠岃瘉閫氳繃"
++
++#~ msgid "Associate your OpenID"
++#~ msgstr "缁戝畾鎮ㄧ殑OpenID"
++
++#~ msgid ""
++#~ "\n"
++#~ "\t<p>If you're joining <strong>Sitename</strong>, associate your OpenID "
++#~ "with a new account. If you're already a member, associate with your "
++#~ "existing account.</p>\n"
++#~ "\t"
++#~ msgstr ""
++#~ "\n"
++#~ "\t<p>杈撳叆鎮ㄧ殑鏂板笎鍙锋垨鑰呮寚瀹氬凡缁忓瓨鍦ㄧ殑甯愬彿銆</p>\n"
++#~ "\t"
++
++#~ msgid "A new account"
++#~ msgstr "鏂板笎鍙"
++
++#~ msgid "An exisiting account"
++#~ msgstr "宸茬粡瀛樺湪鐨勫笎鍙"
++
++#~ msgid "Account: Send a new password"
++#~ msgstr "鍙戦佷竴涓柊鐨勫瘑鐮"
++
++#~ msgid ""
++#~ "Lost your password ? Here you can ask to reset your password. Enter the "
++#~ "username you use and you will get a confirmation email with your new "
++#~ "password. This new password will be activated only after you have clicked "
++#~ "on the link in the email."
++#~ msgstr ""
++#~ "涓㈠け浜嗘偍鐨勫瘑鐮侊紵浣犲彲浠ュ湪杩欓噷閲嶈瀵嗙爜銆傝緭鍏ョ敤鎴峰悕浣犱細鏀跺埌鏂扮殑瀵嗙爜鐨勯偖浠躲傚瘑"
++#~ "鐮佸彧鏈夋偍鍦ㄦ縺娲婚偖浠朵腑鐨勯摼鎺ユ墠浼氳婵娲汇"
++
++#~ msgid "Send new password"
++#~ msgstr "鍙戦佹柊瀵嗙爜"
+diff -ruN CNPROG/middleware/pagesize.py mikes/middleware/pagesize.py
+--- CNPROG/middleware/pagesize.py 1969-12-31 19:00:00.000000000 -0500
++++ mikes/middleware/pagesize.py 2009-07-25 19:09:58.108151006 -0400
+@@ -0,0 +1,29 @@
++# used in questions
++QUESTIONS_PAGE_SIZE = 10
++class QuestionsPageSizeMiddleware(object):
++ def process_request(self, request):
++ # Set flag to False by default. If it is equal to True, then need to be saved.
++ pagesize_changed = False
++ # get pagesize from session, if failed then get default value
++ user_page_size = request.session.get("pagesize", QUESTIONS_PAGE_SIZE)
++ # set pagesize equal to logon user specified value in database
++ if request.user.is_authenticated() and request.user.questions_per_page > 0:
++ user_page_size = request.user.questions_per_page
++
++ try:
++ # get new pagesize from UI selection
++ pagesize = int(request.GET.get('pagesize', user_page_size))
++ if pagesize <> user_page_size:
++ pagesize_changed = True
++
++ except ValueError:
++ pagesize = user_page_size
++
++ # save this pagesize to user database
++ if pagesize_changed:
++ if request.user.is_authenticated():
++ user = request.user
++ user.questions_per_page = pagesize
++ user.save()
++ # put pagesize into session
++ request.session["pagesize"] = pagesize
+\ No newline at end of file
+diff -ruN CNPROG/settings_local.py mikes/settings_local.py
+--- CNPROG/settings_local.py 2009-07-25 18:49:15.158341746 -0400
++++ mikes/settings_local.py 1969-12-31 19:00:00.000000000 -0500
+@@ -1,21 +0,0 @@
+-# encoding:utf-8
+-SITE_SRC_ROOT = '/change_me/'
+-
+-#for logging
+-import logging
+-LOG_FILENAME = SITE_SRC_ROOT + 'django.lanai.log'
+-logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG,)
+-
+-DATABASE_NAME = 'cnprog' # Or path to database file if using sqlite3.
+-DATABASE_USER = 'root' # Not used with sqlite3.
+-DATABASE_PASSWORD = '' # Not used with sqlite3.
+-
+-MIDDLEWARE_CLASSES = (
+- 'django.middleware.gzip.GZipMiddleware',
+- 'django.contrib.sessions.middleware.SessionMiddleware',
+- 'django.middleware.locale.LocaleMiddleware',
+- 'django.middleware.common.CommonMiddleware',
+- 'django.contrib.auth.middleware.AuthenticationMiddleware',
+- 'django.middleware.transaction.TransactionMiddleware',
+- #'debug_toolbar.middleware.DebugToolbarMiddleware',
+-)
+diff -ruN CNPROG/settings_local.py.dist mikes/settings_local.py.dist
+--- CNPROG/settings_local.py.dist 1969-12-31 19:00:00.000000000 -0500
++++ mikes/settings_local.py.dist 2009-07-25 19:09:58.108151006 -0400
+@@ -0,0 +1,25 @@
++SITE_SRC_ROOT = '/Users/sailing/Development/cnprog_beta2'
++
++#for logging
++import logging
++LOG_FILENAME = '/Users/sailing/Development/cnprog_beta2/django.lanai.log'
++logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG,)
++
++
++#Database configuration
++DATABASE_ENGINE = 'mysql'
++DATABASE_HOST = ''
++DATABASE_PORT = ''
++DATABASE_NAME = 'cnprog' # Or path to database file if using sqlite3.
++DATABASE_USER = 'root' # Not used with sqlite3.
++DATABASE_PASSWORD = '' # Not used with sqlite3.
++
++
++# Absolute path to the directory that holds media.
++# Example: "/home/media/media.lawrence.com/"
++MEDIA_ROOT = '/Users/sailing/Development/cnprog_beta2/templates/upfiles/'
++
++# URL that handles the media served from MEDIA_ROOT. Make sure to use a
++# trailing slash if there is a path component (optional in other cases).
++# Examples: "http://media.lawrence.com", "http://example.com/media/"
++MEDIA_URL = 'http://127.0.0.1:8000/upfiles/'
+diff -ruN CNPROG/settings.py mikes/settings.py
+--- CNPROG/settings.py 2009-07-25 18:49:15.158341746 -0400
++++ mikes/settings.py 2009-07-25 19:09:58.108151006 -0400
+@@ -1,51 +1,24 @@
++# encoding:utf-8
+ # Django settings for lanai project.
+ import os.path
+
++#DEBUG SETTINGS
+ DEBUG = True
+ TEMPLATE_DEBUG = DEBUG
+-
+-
+-#David Cramer debug toolbar
+ INTERNAL_IPS = ('127.0.0.1',)
+-DEBUG_TOOLBAR_PANELS = (
+- 'debug_toolbar.panels.sql.SQLDebugPanel',
+- 'debug_toolbar.panels.headers.HeaderDebugPanel',
+- 'debug_toolbar.panels.cache.CacheDebugPanel',
+- 'debug_toolbar.panels.profiler.ProfilerDebugPanel',
+- 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
+- 'debug_toolbar.panels.templates.TemplatesDebugPanel',
+- # If you are using the profiler panel you don't need the timer
+- # 'debug_toolbar.panels.timer.TimerDebugPanel',
+-)
+-
+-DEBUG_TOOLBAR_CONFIG = {
+- "INTERCEPT_REDIRECTS":False
+-}
+
+ #for OpenID auth
+ ugettext = lambda s: s
+ LOGIN_URL = '/%s%s' % (ugettext('account/'), ugettext('signin/'))
+
+-#system will send admins email about error stacktrace if DEBUG=False
++#EMAIL AND ADMINS
+ ADMINS = (
+- ('you', 'you@where.com'),
++ ('CNProg team', 'team@cnprog.com'),
+ )
+-
+ MANAGERS = ADMINS
+
+-DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+-#DATABASE_NAME = 'cnprog' # Or path to database file if using sqlite3.
+-#DATABASE_USER = 'root' # Not used with sqlite3.
+-#DATABASE_PASSWORD = '' # Not used with sqlite3.
+-DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
+-DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
+-
+-DATABASE_NAME = 'dbname' # Or path to database file if using sqlite3.
+-DATABASE_USER = 'dbuser' # Not used with sqlite3.
+-DATABASE_PASSWORD = 'dbpass' # Not used with sqlite3.
+-
+-SERVER_EMAIL = 'server@where.com'
+-DEFAULT_FROM_EMAIL = 'from@where.com'
++SERVER_EMAIL = 'webmaster@cnprog.com'
++DEFAULT_FROM_EMAIL = 'webmaster@cnprog.com'
+ EMAIL_HOST_USER = ''
+ EMAIL_HOST_PASSWORD = ''
+ EMAIL_SUBJECT_PREFIX = '[cnprog.com]'
+@@ -53,44 +26,21 @@
+ EMAIL_PORT='587'
+ EMAIL_USE_TLS=True
+
+-
+-
+-
+-# Local time zone for this installation. Choices can be found here:
+-# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+-# although not all choices may be available on all operating systems.
+-# If running in a Windows environment this must be set to the same as your
+-# system time zone.
+-TIME_ZONE = 'America/Chicago'
+-
+-# Language code for this installation. All choices can be found here:
+-# http://www.i18nguy.com/unicode/language-identifiers.html
+-#LANGUAGE_CODE = 'en'
++#LOCALIZATIONS
++TIME_ZONE = 'Asia/Chongqing Asia/Chungking'
++# LANGUAGE_CODE = 'en-us'
+ LANGUAGE_CODE = 'zh-cn'
+-
+ SITE_ID = 1
+-
+-# If you set this to False, Django will make some optimizations so as not
+-# to load the internationalization machinery.
+ USE_I18N = True
+
+-# Absolute path to the directory that holds media.
+-# Example: "/home/media/media.lawrence.com/"
+-MEDIA_ROOT = '/var/www/vhosts/cnprog/templates/upfiles/'
+-
+-# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+-# trailing slash if there is a path component (optional in other cases).
+-# Examples: "http://media.lawrence.com", "http://example.com/media/"
+-MEDIA_URL = 'http://where.com/upfiles/'
+-
+-# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+-# trailing slash.
+-# Examples: "http://foo.com/media/", "/media/".
++#OTHER SETTINS
++APP_TITLE = u'CNProg.com 绋嬪簭鍛橀棶绛旂ぞ鍖'
++APP_URL = 'http://www.cnprog.com'
++APP_KEYWORDS = u'鎶鏈棶绛旂ぞ鍖猴紝涓浗绋嬪簭鍛橈紝缂栫▼鎶鏈ぞ鍖猴紝绋嬪簭鍛樼ぞ鍖猴紝绋嬪簭鍛樿鍧涳紝绋嬪簭鍛榳iki锛岀▼搴忓憳鍗氬'
++APP_DESCRIPTION = u'涓浗绋嬪簭鍛樼殑缂栫▼鎶鏈棶绛旂ぞ鍖恒傛垜浠仛涓撲笟鐨勩佸彲鍗忎綔缂栬緫鐨勬妧鏈棶绛旂ぞ鍖恒'
++APP_INTRO = u' <p>CNProg鏄竴涓<strong>闈㈠悜绋嬪簭鍛</strong>鐨勫彲鍗忎綔缂栬緫鐨<strong>寮鏀炬簮浠g爜闂瓟绀惧尯</strong>銆</p><p> 鎮ㄥ彲浠ュ湪杩欓噷鎻愰棶鍚勭被<strong>绋嬪簭鎶鏈棶棰</strong> - 闂涓嶅垎璇█鍜屽钩鍙般 鍚屾椂涔熷笇鏈涙偍瀵瑰姏鎵鑳藉強鐨勯棶棰橈紝缁欎簣鎮ㄧ殑瀹濊吹绛旀銆</p>'
+ ADMIN_MEDIA_PREFIX = '/admin/media/'
+-
+-# Make this unique, and don't share it with anybody.
+-SECRET_KEY = '$oo^&_m&qwbib=ffljk_4m_n*zn-d=g#s0he5fx9xonnym#8p6yigm'
+-
++SECRET_KEY = '$oo^&_m&qwbib=(_4m_n*zn-d=g#s0he5fx9xonnym#8p6yigm'
+ # List of callables that know how to import templates from various sources.
+ TEMPLATE_LOADERS = (
+ 'django.template.loaders.filesystem.load_template_source',
+@@ -105,12 +55,15 @@
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.middleware.transaction.TransactionMiddleware',
+- 'debug_toolbar.middleware.DebugToolbarMiddleware',
++ #'django.middleware.sqlprint.SqlPrintingMiddleware',
++ 'middleware.pagesize.QuestionsPageSizeMiddleware',
++ #'debug_toolbar.middleware.DebugToolbarMiddleware',
+ )
+
+ TEMPLATE_CONTEXT_PROCESSORS = (
+ 'django.core.context_processors.request',
+ 'django.core.context_processors.auth',
++ 'context.application_settings'
+ )
+
+ ROOT_URLCONF = 'urls'
+@@ -119,6 +72,7 @@
+ os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
+ )
+
++#UPLOAD SETTINGS
+ FILE_UPLOAD_TEMP_DIR = os.path.join(os.path.dirname(__file__), 'tmp').replace('\\','/')
+ FILE_UPLOAD_HANDLERS = ("django.core.files.uploadhandler.MemoryFileUploadHandler",
+ "django.core.files.uploadhandler.TemporaryFileUploadHandler",)
+@@ -139,6 +93,7 @@
+ 'django_authopenid',
+ 'debug_toolbar' ,
+ )
+-#local configs
+-from settings_local import *
+-
++
++# User settings
++from settings_local import *
++
+diff -ruN CNPROG/templates/allfiles mikes/templates/allfiles
+--- CNPROG/templates/allfiles 2009-06-22 21:42:52.000000000 -0400
++++ mikes/templates/allfiles 1969-12-31 19:00:00.000000000 -0500
+@@ -1,30 +0,0 @@
+-404.html
+-500.html
+-about.html
+-ask.html
+-badges.html
+-base_content.html
+-base.html
+-book.html
+-close.html
+-faq.html
+-footer.html
+-header.html
+-index.html
+-logout.html
+-pagesize.html
+-paginator.html
+-privacy.html
+-question_edit_tips.html
+-question.html
+-questions.html
+-revisions_answer.html
+-tags.html
+-unanswered.html
+-user_edit.html
+-user_info.html
+-users.html
+-users_questions.html
+-user_stats.html
+-user_tabs.html
+-user_votes.html
+diff -ruN CNPROG/templates/authopenid/htmlfiles mikes/templates/authopenid/htmlfiles
+--- CNPROG/templates/authopenid/htmlfiles 2009-06-22 21:42:52.000000000 -0400
++++ mikes/templates/authopenid/htmlfiles 1969-12-31 19:00:00.000000000 -0500
+@@ -1,8 +0,0 @@
+-changeemail.html
+-changeopenid.html
+-changepw.html
+-delete.html
+-failure.html
+-sendpw.html
+-settings.html
+-signup.html
+diff -ruN CNPROG/templates/base_content.html mikes/templates/base_content.html
+--- CNPROG/templates/base_content.html 2009-06-22 21:49:26.000000000 -0400
++++ mikes/templates/base_content.html 2009-07-25 19:09:58.118151716 -0400
+@@ -1,9 +1,8 @@
++锘縶% load i18n %}
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+-<!-- template base_content.html -->
+-{% load i18n %}
+ <html>
+ <head>
+- <title>{% block title %}{% endblock %} - {% trans "site title" %} - {% trans "site slogan" %}</title>
++ <title>{% block title %}{% endblock %} - {{ APP_TITLE }}</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <meta name="verify-v1" content="55uGNnQVJW8p1bbXeF/Xbh9I7nZBM/wLhRz6N/I1kkA=" />
+ <link rel="shortcut icon" href="/content/images/favicon.ico" >
+@@ -83,4 +74,3 @@
+ {% endblock %}
+ </body>
+ </html>
+-<!-- end template base_content.html -->
+diff -ruN CNPROG/templates/base.html mikes/templates/base.html
+--- CNPROG/templates/base.html 2009-06-22 21:49:58.000000000 -0400
++++ mikes/templates/base.html 2009-07-25 19:09:58.118151716 -0400
+@@ -48,6 +40,7 @@
+ notify.show();
+ });
+ </script>
++
+ {% endif %}
+ {% endwith %}
+
+@@ -88,4 +81,3 @@
+ {% endblock %}
+ </body>
+ </html>
+-<!-- end template base.html -->
+diff -ruN CNPROG/templates/content/js/com.cnprog.post.js mikes/templates/content/js/com.cnprog.post.js
+--- CNPROG/templates/content/js/com.cnprog.post.js 2009-06-22 21:42:51.000000000 -0400
++++ mikes/templates/content/js/com.cnprog.post.js 2009-07-25 19:09:58.138152577 -0400
+@@ -613,4 +570,4 @@
+ Prettify
+ http://www.apache.org/licenses/LICENSE-2.0
+ */
+-var PR_SHOULD_USE_CONTINUATION = true; var PR_TAB_WIDTH = 8; var PR_normalizedHtml; var PR; var prettyPrintOne; var prettyPrint; function _pr_isIE6() { var isIE6 = navigator && navigator.userAgent && /\bMSIE 6\./.test(navigator.userAgent); _pr_isIE6 = function() { return isIE6; }; return isIE6; } (function() { function wordSet(words) { words = words.split(/ /g); var set = {}; for (var i = words.length; --i >= 0; ) { var w = words[i]; if (w) { set[w] = null; } } return set; } var FLOW_CONTROL_KEYWORDS = "break continue do else for if return while "; var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " + "double enum extern float goto int long register short signed sizeof " + "static struct switch typedef union unsigned void volatile "; var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " + "new operator private protected public this throw true try "; var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " + "concept concept_map const_cast constexpr decltype " + "dynamic_cast explicit export friend inline late_check " + "mutable namespace nullptr reinterpret_cast static_assert static_cast " + "template typeid typename typeof using virtual wchar_t where "; var JAVA_KEYWORDS = COMMON_KEYWORDS + "boolean byte extends final finally implements import instanceof null " + "native package strictfp super synchronized throws transient "; var CSHARP_KEYWORDS = JAVA_KEYWORDS + "as base by checked decimal delegate descending event " + "fixed foreach from group implicit in interface internal into is lock " + "object out override orderby params readonly ref sbyte sealed " + "stackalloc string select uint ulong unchecked unsafe ushort var "; var JSCRIPT_KEYWORDS = COMMON_KEYWORDS + "debugger eval export function get null set undefined var with " + "Infinity NaN "; var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " + "goto if import last local my next no our print package redo require " + "sub undef unless until use wantarray while BEGIN END "; var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " + "elif except exec finally from global import in is lambda " + "nonlocal not or pass print raise try with yield " + "False True None "; var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" + " defined elsif end ensure false in module next nil not or redo rescue " + "retry self super then true undef unless until when yield BEGIN END "; var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " + "function in local set then until "; var ALL_KEYWORDS = (CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS + PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS); var PR_STRING = 'str'; var PR_KEYWORD = 'kwd'; var PR_COMMENT = 'com'; var PR_TYPE = 'typ'; var PR_LITERAL = 'lit'; var PR_PUNCTUATION = 'pun'; var PR_PLAIN = 'pln'; var PR_TAG = 'tag'; var PR_DECLARATION = 'dec'; var PR_SOURCE = 'src'; var PR_ATTRIB_NAME = 'atn'; var PR_ATTRIB_VALUE = 'atv'; var PR_NOCODE = 'nocode'; function isWordChar(ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } function spliceArrayInto(inserted, container, containerPosition, countReplaced) { inserted.unshift(containerPosition, countReplaced || 0); try { container.splice.apply(container, inserted); } finally { inserted.splice(0, 2); } } var REGEXP_PRECEDER_PATTERN = function() { var preceders = ["!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=", "&=", "(", "*", "*=", "+=", ",", "-=", "->", "/", "/=", ":", "::", ";", "<", "<<", "<<=", "<=", "=", "==", "===", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[", "^", "^=", "^^", "^^=", "{", "|", "|=", "||", "||=", "~", "break", "case", "continue", "delete", "do", "else", "finally", "instanceof", "return", "throw", "try", "typeof"]; var pattern = '(?:' + '(?:(?:^|[^0-9.])\\.{1,3})|' + '(?:(?:^|[^\\+])\\+)|' + '(?:(?:^|[^\\-])-)'; for (var i = 0; i < preceders.length; ++i) { var preceder = preceders[i]; if (isWordChar(preceder.charAt(0))) { pattern += '|\\b' + preceder; } else { pattern += '|' + preceder.replace(/([^=<>:&])/g, '\\$1'); } } pattern += '|^)\\s*$'; return new RegExp(pattern); } (); var pr_amp = /&/g; var pr_lt = /</g; var pr_gt = />/g; var pr_quot = /\"/g; function attribToHtml(str) { return str.replace(pr_amp, '&amp;').replace(pr_lt, '&lt;').replace(pr_gt, '&gt;').replace(pr_quot, '&quot;'); } function textToHtml(str) { return str.replace(pr_amp, '&amp;').replace(pr_lt, '&lt;').replace(pr_gt, '&gt;'); } var pr_ltEnt = /&lt;/g; var pr_gtEnt = /&gt;/g; var pr_aposEnt = /&apos;/g; var pr_quotEnt = /&quot;/g; var pr_ampEnt = /&amp;/g; var pr_nbspEnt = /&nbsp;/g; function htmlToText(html) { var pos = html.indexOf('&'); if (pos < 0) { return html; } for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0; ) { var end = html.indexOf(';', pos); if (end >= 0) { var num = html.substring(pos + 3, end); var radix = 10; if (num && num.charAt(0) === 'x') { num = num.substring(1); radix = 16; } var codePoint = parseInt(num, radix); if (!isNaN(codePoint)) { html = (html.substring(0, pos) + String.fromCharCode(codePoint) + html.substring(end + 1)); } } } return html.replace(pr_ltEnt, '<').replace(pr_gtEnt, '>').replace(pr_aposEnt, "'").replace(pr_quotEnt, '"').replace(pr_ampEnt, '&').replace(pr_nbspEnt, ' '); } function isRawContent(node) { return 'XMP' === node.tagName; } function normalizedHtml(node, out) { switch (node.nodeType) { case 1: var name = node.tagName.toLowerCase(); out.push('<', name); for (var i = 0; i < node.attributes.length; ++i) { var attr = node.attributes[i]; if (!attr.specified) { continue; } out.push(' '); normalizedHtml(attr, out); } out.push('>'); for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } if (node.firstChild || !/^(?:br|link|img)$/.test(name)) { out.push('<\/', name, '>'); } break; case 2: out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"'); break; case 3: case 4: out.push(textToHtml(node.nodeValue)); break; } } var PR_innerHtmlWorks = null; function getInnerHtml(node) { if (null === PR_innerHtmlWorks) { var testNode = document.createElement('PRE'); testNode.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />')); PR_innerHtmlWorks = !/</.test(testNode.innerHTML); } if (PR_innerHtmlWorks) { var content = node.innerHTML; if (isRawContent(node)) { content = textToHtml(content); } return content; } var out = []; for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } return out.join(''); } function makeTabExpander(tabWidth) { var SPACES = ' '; var charInLine = 0; return function(plainText) { var out = null; var pos = 0; for (var i = 0, n = plainText.length; i < n; ++i) { var ch = plainText.charAt(i); switch (ch) { case '\t': if (!out) { out = []; } out.push(plainText.substring(pos, i)); var nSpaces = tabWidth - (charInLine % tabWidth); charInLine += nSpaces; for (; nSpaces >= 0; nSpaces -= SPACES.length) { out.push(SPACES.substring(0, nSpaces)); } pos = i + 1; break; case '\n': charInLine = 0; break; default: ++charInLine; } } if (!out) { return plainText; } out.push(plainText.substring(pos)); return out.join(''); }; } var pr_chunkPattern = /(?:[^<]+|<!--[\s\S]*?-->|<!\[CDATA\[([\s\S]*?)\]\]>|<\/?[a-zA-Z][^>]*>|<)/g; var pr_commentPrefix = /^<!--/; var pr_cdataPrefix = /^<\[CDATA\[/; var pr_brPrefix = /^<br\b/i; var pr_tagNameRe = /^<(\/?)([a-zA-Z]+)/; function extractTags(s) { var matches = s.match(pr_chunkPattern); var sourceBuf = []; var sourceBufLen = 0; var extractedTags = []; if (matches) { for (var i = 0, n = matches.length; i < n; ++i) { var match = matches[i]; if (match.length > 1 && match.charAt(0) === '<') { if (pr_commentPrefix.test(match)) { continue; } if (pr_cdataPrefix.test(match)) { sourceBuf.push(match.substring(9, match.length - 3)); sourceBufLen += match.length - 12; } else if (pr_brPrefix.test(match)) { sourceBuf.push('\n'); ++sourceBufLen; } else { if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) { var name = match.match(pr_tagNameRe)[2]; var depth = 1; end_tag_loop: for (var j = i + 1; j < n; ++j) { var name2 = matches[j].match(pr_tagNameRe); if (name2 && name2[2] === name) { if (name2[1] === '/') { if (--depth === 0) { break end_tag_loop; } } else { ++depth; } } } if (j < n) { extractedTags.push(sourceBufLen, matches.slice(i, j + 1).join('')); i = j; } else { extractedTags.push(sourceBufLen, match); } } else { extractedTags.push(sourceBufLen, match); } } } else { var literalText = htmlToText(match); sourceBuf.push(literalText); sourceBufLen += literalText.length; } } } return { source: sourceBuf.join(''), tags: extractedTags }; } function isNoCodeTag(tag) { return !!tag.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g, ' $1="$2$3$4"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/); } function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) { var shortcuts = {}; (function() { var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns); for (var i = allPatterns.length; --i >= 0; ) { var patternParts = allPatterns[i]; var shortcutChars = patternParts[3]; if (shortcutChars) { for (var c = shortcutChars.length; --c >= 0; ) { shortcuts[shortcutChars.charAt(c)] = patternParts; } } } })(); var nPatterns = fallthroughStylePatterns.length; var notWs = /\S/; return function(sourceCode, opt_basePos) { opt_basePos = opt_basePos || 0; var decorations = [opt_basePos, PR_PLAIN]; var lastToken = ''; var pos = 0; var tail = sourceCode; while (tail.length) { var style; var token = null; var match; var patternParts = shortcuts[tail.charAt(0)]; if (patternParts) { match = tail.match(patternParts[1]); token = match[0]; style = patternParts[0]; } else { for (var i = 0; i < nPatterns; ++i) { patternParts = fallthroughStylePatterns[i]; var contextPattern = patternParts[2]; if (contextPattern && !contextPattern.test(lastToken)) { continue; } match = tail.match(patternParts[1]); if (match) { token = match[0]; style = patternParts[0]; break; } } if (!token) { style = PR_PLAIN; token = tail.substring(0, 1); } } decorations.push(opt_basePos + pos, style); pos += token.length; tail = tail.substring(token.length); if (style !== PR_COMMENT && notWs.test(token)) { lastToken = token; } } return decorations; }; } var PR_MARKUP_LEXER = createSimpleLexer([], [[PR_PLAIN, /^[^<]+/, null], [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/, null], [PR_COMMENT, /^<!--[\s\S]*?(?:-->|$)/, null], [PR_SOURCE, /^<\?[\s\S]*?(?:\?>|$)/, null], [PR_SOURCE, /^<%[\s\S]*?(?:%>|$)/, null], [PR_SOURCE, /^<(script|style|xmp)\b[^>]*>[\s\S]*?<\/\1\b[^>]*>/i, null], [PR_TAG, /^<\/?\w[^<>]*>/, null]]); var PR_SOURCE_CHUNK_PARTS = /^(<[^>]*>)([\s\S]*)(<\/[^>]*>)$/; function tokenizeMarkup(source) { var decorations = PR_MARKUP_LEXER(source); for (var i = 0; i < decorations.length; i += 2) { if (decorations[i + 1] === PR_SOURCE) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var sourceChunk = source.substring(start, end); var match = sourceChunk.match(PR_SOURCE_CHUNK_PARTS); if (match) { decorations.splice(i, 2, start, PR_TAG, start + match[1].length, PR_SOURCE, start + match[1].length + (match[2] || '').length, PR_TAG); } } } return decorations; } var PR_TAG_LEXER = createSimpleLexer([[PR_ATTRIB_VALUE, /^\'[^\']*(?:\'|$)/, null, "'"], [PR_ATTRIB_VALUE, /^\"[^\"]*(?:\"|$)/, null, '"'], [PR_PUNCTUATION, /^[<>\/=]+/, null, '<>/=']], [[PR_TAG, /^[\w:\-]+/, /^</], [PR_ATTRIB_VALUE, /^[\w\-]+/, /^=/], [PR_ATTRIB_NAME, /^[\w:\-]+/, null], [PR_PLAIN, /^\s+/, null, ' \t\r\n']]); function splitTagAttributes(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_TAG) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var chunk = source.substring(start, end); var subDecorations = PR_TAG_LEXER(chunk, start); spliceArrayInto(subDecorations, decorations, i, 2); i += subDecorations.length - 2; } } return decorations; } function sourceDecorator(options) { var shortcutStylePatterns = [], fallthroughStylePatterns = []; if (options.tripleQuotedStrings) { shortcutStylePatterns.push([PR_STRING, /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/, null, '\'"']); } else if (options.multiLineStrings) { shortcutStylePatterns.push([PR_STRING, /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/, null, '\'"`']); } else { shortcutStylePatterns.push([PR_STRING, /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/, null, '"\'']); } fallthroughStylePatterns.push([PR_PLAIN, /^(?:[^\'\"\`\/\#]+)/, null, ' \r\n']); if (options.hashComments) { shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']); } if (options.cStyleComments) { fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]); fallthroughStylePatterns.push([PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]); } if (options.regexLiterals) { var REGEX_LITERAL = ('^/(?=[^/*])' + '(?:[^/\\x5B\\x5C]' + '|\\x5C[\\s\\S]' + '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+' + '(?:/|$)'); fallthroughStylePatterns.push([PR_STRING, new RegExp(REGEX_LITERAL), REGEXP_PRECEDER_PATTERN]); } var keywords = wordSet(options.keywords); options = null; var splitStringAndCommentTokens = createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns); var styleLiteralIdentifierPuncRecognizer = createSimpleLexer([], [[PR_PLAIN, /^\s+/, null, ' \r\n'], [PR_PLAIN, /^[a-z_$@][a-z_$@0-9]*/i, null], [PR_LITERAL, /^0x[a-f0-9]+[a-z]/i, null], [PR_LITERAL, /^(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?[a-z]*/i, null, '123456789'], [PR_PUNCTUATION, /^[^\s\w\.$@]+/, null]]); function splitNonStringNonCommentTokens(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_PLAIN) { var start, end, chunk, subDecs; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; chunk = source.substring(start, end); subDecs = styleLiteralIdentifierPuncRecognizer(chunk, start); for (var j = 0, m = subDecs.length; j < m; j += 2) { var subStyle = subDecs[j + 1]; if (subStyle === PR_PLAIN) { var subStart = subDecs[j]; var subEnd = j + 2 < m ? subDecs[j + 2] : chunk.length; var token = source.substring(subStart, subEnd); if (token === '.') { subDecs[j + 1] = PR_PUNCTUATION; } else if (token in keywords) { subDecs[j + 1] = PR_KEYWORD; } else if (/^@?[A-Z][A-Z$]*[a-z][A-Za-z$]*$/.test(token)) { subDecs[j + 1] = token.charAt(0) === '@' ? PR_LITERAL : PR_TYPE; } } } spliceArrayInto(subDecs, decorations, i, 2); i += subDecs.length - 2; } } return decorations; } return function(sourceCode) { var decorations = splitStringAndCommentTokens(sourceCode); decorations = splitNonStringNonCommentTokens(sourceCode, decorations); return decorations; }; } var decorateSource = sourceDecorator({ keywords: ALL_KEYWORDS, hashComments: true, cStyleComments: true, multiLineStrings: true, regexLiterals: true }); function splitSourceNodes(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_SOURCE) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var subDecorations = decorateSource(source.substring(start, end)); for (var j = 0, m = subDecorations.length; j < m; j += 2) { subDecorations[j] += start; } spliceArrayInto(subDecorations, decorations, i, 2); i += subDecorations.length - 2; } } return decorations; } function splitSourceAttributes(source, decorations) { var nextValueIsSource = false; for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; var start, end; if (style === PR_ATTRIB_NAME) { start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; nextValueIsSource = /^on|^style$/i.test(source.substring(start, end)); } else if (style === PR_ATTRIB_VALUE) { if (nextValueIsSource) { start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var attribValue = source.substring(start, end); var attribLen = attribValue.length; var quoted = (attribLen >= 2 && /^[\"\']/.test(attribValue) && attribValue.charAt(0) === attribValue.charAt(attribLen - 1)); var attribSource; var attribSourceStart; var attribSourceEnd; if (quoted) { attribSourceStart = start + 1; attribSourceEnd = end - 1; attribSource = attribValue; } else { attribSourceStart = start + 1; attribSourceEnd = end - 1; attribSource = attribValue.substring(1, attribValue.length - 1); } var attribSourceDecorations = decorateSource(attribSource); for (var j = 0, m = attribSourceDecorations.length; j < m; j += 2) { attribSourceDecorations[j] += attribSourceStart; } if (quoted) { attribSourceDecorations.push(attribSourceEnd, PR_ATTRIB_VALUE); spliceArrayInto(attribSourceDecorations, decorations, i + 2, 0); } else { spliceArrayInto(attribSourceDecorations, decorations, i, 2); } } nextValueIsSource = false; } } return decorations; } function decorateMarkup(sourceCode) { var decorations = tokenizeMarkup(sourceCode); decorations = splitTagAttributes(sourceCode, decorations); decorations = splitSourceNodes(sourceCode, decorations); decorations = splitSourceAttributes(sourceCode, decorations); return decorations; } function recombineTagsAndDecorations(sourceText, extractedTags, decorations) { var html = []; var outputIdx = 0; var openDecoration = null; var currentDecoration = null; var tagPos = 0; var decPos = 0; var tabExpander = makeTabExpander(PR_TAB_WIDTH); var adjacentSpaceRe = /([\r\n ]) /g; var startOrSpaceRe = /(^| ) /gm; var newlineRe = /\r\n?|\n/g; var trailingSpaceRe = /[ \r\n]$/; var lastWasSpace = true; function emitTextUpTo(sourceIdx) { if (sourceIdx > outputIdx) { if (openDecoration && openDecoration !== currentDecoration) { html.push('</span>'); openDecoration = null; } if (!openDecoration && currentDecoration) { openDecoration = currentDecoration; html.push('<span class="', openDecoration, '">'); } var htmlChunk = textToHtml(tabExpander(sourceText.substring(outputIdx, sourceIdx))).replace(lastWasSpace ? startOrSpaceRe : adjacentSpaceRe, '$1&nbsp;'); lastWasSpace = trailingSpaceRe.test(htmlChunk); html.push(htmlChunk.replace(newlineRe, '<br />')); outputIdx = sourceIdx; } } while (true) { var outputTag; if (tagPos < extractedTags.length) { if (decPos < decorations.length) { outputTag = extractedTags[tagPos] <= decorations[decPos]; } else { outputTag = true; } } else { outputTag = false; } if (outputTag) { emitTextUpTo(extractedTags[tagPos]); if (openDecoration) { html.push('</span>'); openDecoration = null; } html.push(extractedTags[tagPos + 1]); tagPos += 2; } else if (decPos < decorations.length) { emitTextUpTo(decorations[decPos]); currentDecoration = decorations[decPos + 1]; decPos += 2; } else { break; } } emitTextUpTo(sourceText.length); if (openDecoration) { html.push('</span>'); } return html.join(''); } var langHandlerRegistry = {}; function registerLangHandler(handler, fileExtensions) { for (var i = fileExtensions.length; --i >= 0; ) { var ext = fileExtensions[i]; if (!langHandlerRegistry.hasOwnProperty(ext)) { langHandlerRegistry[ext] = handler; } else if ('console' in window) { console.log('cannot override language handler %s', ext); } } } registerLangHandler(decorateSource, ['default-code']); registerLangHandler(decorateMarkup, ['default-markup', 'html', 'htm', 'xhtml', 'xml', 'xsl']); registerLangHandler(sourceDecorator({ keywords: CPP_KEYWORDS, hashComments: true, cStyleComments: true }), ['c', 'cc', 'cpp', 'cs', 'cxx', 'cyc']); registerLangHandler(sourceDecorator({ keywords: JAVA_KEYWORDS, cStyleComments: true }), ['java']); registerLangHandler(sourceDecorator({ keywords: SH_KEYWORDS, hashComments: true, multiLineStrings: true }), ['bsh', 'csh', 'sh']); registerLangHandler(sourceDecorator({ keywords: PYTHON_KEYWORDS, hashComments: true, multiLineStrings: true, tripleQuotedStrings: true }), ['cv', 'py']); registerLangHandler(sourceDecorator({ keywords: PERL_KEYWORDS, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['perl', 'pl', 'pm']); registerLangHandler(sourceDecorator({ keywords: RUBY_KEYWORDS, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['rb']); registerLangHandler(sourceDecorator({ keywords: JSCRIPT_KEYWORDS, cStyleComments: true, regexLiterals: true }), ['js']); function prettyPrintOne(sourceCodeHtml, opt_langExtension) { try { var sourceAndExtractedTags = extractTags(sourceCodeHtml); var source = sourceAndExtractedTags.source; var extractedTags = sourceAndExtractedTags.tags; if (!langHandlerRegistry.hasOwnProperty(opt_langExtension)) { opt_langExtension = /^\s*</.test(source) ? 'default-markup' : 'default-code'; } var decorations = langHandlerRegistry[opt_langExtension].call({}, source); return recombineTagsAndDecorations(source, extractedTags, decorations); } catch (e) { if ('console' in window) { console.log(e); console.trace(); } return sourceCodeHtml; } } function prettyPrint(opt_whenDone) { var isIE6 = _pr_isIE6(); var codeSegments = [document.getElementsByTagName('pre'), document.getElementsByTagName('code'), document.getElementsByTagName('xmp')]; var elements = []; for (var i = 0; i < codeSegments.length; ++i) { for (var j = 0; j < codeSegments[i].length; ++j) { elements.push(codeSegments[i][j]); } } codeSegments = null; var k = 0; function doWork() { var endTime = (PR_SHOULD_USE_CONTINUATION ? new Date().getTime() + 250 : Infinity); for (; k < elements.length && new Date().getTime() < endTime; k++) { var cs = elements[k]; if (cs.className && cs.className.indexOf('prettyprint') >= 0) { var langExtension = cs.className.match(/\blang-(\w+)\b/); if (langExtension) { langExtension = langExtension[1]; } var nested = false; for (var p = cs.parentNode; p; p = p.parentNode) { if ((p.tagName === 'pre' || p.tagName === 'code' || p.tagName === 'xmp') && p.className && p.className.indexOf('prettyprint') >= 0) { nested = true; break; } } if (!nested) { var content = getInnerHtml(cs); content = content.replace(/(?:\r\n?|\n)$/, ''); var newContent = prettyPrintOne(content, langExtension); if (!isRawContent(cs)) { cs.innerHTML = newContent; } else { var pre = document.createElement('PRE'); for (var i = 0; i < cs.attributes.length; ++i) { var a = cs.attributes[i]; if (a.specified) { var aname = a.name.toLowerCase(); if (aname === 'class') { pre.className = a.value; } else { pre.setAttribute(a.name, a.value); } } } pre.innerHTML = newContent; cs.parentNode.replaceChild(pre, cs); cs = pre; } if (isIE6 && cs.tagName === 'PRE') { var lineBreaks = cs.getElementsByTagName('br'); for (var j = lineBreaks.length; --j >= 0; ) { var lineBreak = lineBreaks[j]; lineBreak.parentNode.replaceChild(document.createTextNode('\r\n'), lineBreak); } } } } } if (k < elements.length) { setTimeout(doWork, 250); } else if (opt_whenDone) { opt_whenDone(); } } doWork(); } window['PR_normalizedHtml'] = normalizedHtml; window['prettyPrintOne'] = prettyPrintOne; window['prettyPrint'] = prettyPrint; window['PR'] = { 'createSimpleLexer': createSimpleLexer, 'registerLangHandler': registerLangHandler, 'sourceDecorator': sourceDecorator, 'PR_ATTRIB_NAME': PR_ATTRIB_NAME, 'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE, 'PR_COMMENT': PR_COMMENT, 'PR_DECLARATION': PR_DECLARATION, 'PR_KEYWORD': PR_KEYWORD, 'PR_LITERAL': PR_LITERAL, 'PR_NOCODE': PR_NOCODE, 'PR_PLAIN': PR_PLAIN, 'PR_PUNCTUATION': PR_PUNCTUATION, 'PR_SOURCE': PR_SOURCE, 'PR_STRING': PR_STRING, 'PR_TAG': PR_TAG, 'PR_TYPE': PR_TYPE }; })();
++var PR_SHOULD_USE_CONTINUATION = true; var PR_TAB_WIDTH = 8; var PR_normalizedHtml; var PR; var prettyPrintOne; var prettyPrint; function _pr_isIE6() { var isIE6 = navigator && navigator.userAgent && /\bMSIE 6\./.test(navigator.userAgent); _pr_isIE6 = function() { return isIE6; }; return isIE6; } (function() { function wordSet(words) { words = words.split(/ /g); var set = {}; for (var i = words.length; --i >= 0; ) { var w = words[i]; if (w) { set[w] = null; } } return set; } var FLOW_CONTROL_KEYWORDS = "break continue do else for if return while "; var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " + "double enum extern float goto int long register short signed sizeof " + "static struct switch typedef union unsigned void volatile "; var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " + "new operator private protected public this throw true try "; var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " + "concept concept_map const_cast constexpr decltype " + "dynamic_cast explicit export friend inline late_check " + "mutable namespace nullptr reinterpret_cast static_assert static_cast " + "template typeid typename typeof using virtual wchar_t where "; var JAVA_KEYWORDS = COMMON_KEYWORDS + "boolean byte extends final finally implements import instanceof null " + "native package strictfp super synchronized throws transient "; var CSHARP_KEYWORDS = JAVA_KEYWORDS + "as base by checked decimal delegate descending event " + "fixed foreach from group implicit in interface internal into is lock " + "object out override orderby params readonly ref sbyte sealed " + "stackalloc string select uint ulong unchecked unsafe ushort var "; var JSCRIPT_KEYWORDS = COMMON_KEYWORDS + "debugger eval export function get null set undefined var with " + "Infinity NaN "; var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " + "goto if import last local my next no our print package redo require " + "sub undef unless until use wantarray while BEGIN END "; var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " + "elif except exec finally from global import in is lambda " + "nonlocal not or pass print raise try with yield " + "False True None "; var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" + " defined elsif end ensure false in module next nil not or redo rescue " + "retry self super then true undef unless until when yield BEGIN END "; var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " + "function in local set then until "; var ALL_KEYWORDS = (CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS + PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS); var PR_STRING = 'str'; var PR_KEYWORD = 'kwd'; var PR_COMMENT = 'com'; var PR_TYPE = 'typ'; var PR_LITERAL = 'lit'; var PR_PUNCTUATION = 'pun'; var PR_PLAIN = 'pln'; var PR_TAG = 'tag'; var PR_DECLARATION = 'dec'; var PR_SOURCE = 'src'; var PR_ATTRIB_NAME = 'atn'; var PR_ATTRIB_VALUE = 'atv'; var PR_NOCODE = 'nocode'; function isWordChar(ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } function spliceArrayInto(inserted, container, containerPosition, countReplaced) { inserted.unshift(containerPosition, countReplaced || 0); try { container.splice.apply(container, inserted); } finally { inserted.splice(0, 2); } } var REGEXP_PRECEDER_PATTERN = function() { var preceders = ["!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=", "&=", "(", "*", "*=", "+=", ",", "-=", "->", "/", "/=", ":", "::", ";", "<", "<<", "<<=", "<=", "=", "==", "===", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[", "^", "^=", "^^", "^^=", "{", "|", "|=", "||", "||=", "~", "break", "case", "continue", "delete", "do", "else", "finally", "instanceof", "return", "throw", "try", "typeof"]; var pattern = '(?:' + '(?:(?:^|[^0-9.])\\.{1,3})|' + '(?:(?:^|[^\\+])\\+)|' + '(?:(?:^|[^\\-])-)'; for (var i = 0; i < preceders.length; ++i) { var preceder = preceders[i]; if (isWordChar(preceder.charAt(0))) { pattern += '|\\b' + preceder; } else { pattern += '|' + preceder.replace(/([^=<>:&])/g, '\\$1'); } } pattern += '|^)\\s*$'; return new RegExp(pattern); } (); var pr_amp = /&/g; var pr_lt = /</g; var pr_gt = />/g; var pr_quot = /\"/g; function attribToHtml(str) { return str.replace(pr_amp, '&amp;').replace(pr_lt, '&lt;').replace(pr_gt, '&gt;').replace(pr_quot, '&quot;'); } function textToHtml(str) { return str.replace(pr_amp, '&amp;').replace(pr_lt, '&lt;').replace(pr_gt, '&gt;'); } var pr_ltEnt = /&lt;/g; var pr_gtEnt = /&gt;/g; var pr_aposEnt = /&apos;/g; var pr_quotEnt = /&quot;/g; var pr_ampEnt = /&amp;/g; var pr_nbspEnt = /&nbsp;/g; function htmlToText(html) { var pos = html.indexOf('&'); if (pos < 0) { return html; } for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0; ) { var end = html.indexOf(';', pos); if (end >= 0) { var num = html.substring(pos + 3, end); var radix = 10; if (num && num.charAt(0) === 'x') { num = num.substring(1); radix = 16; } var codePoint = parseInt(num, radix); if (!isNaN(codePoint)) { html = (html.substring(0, pos) + String.fromCharCode(codePoint) + html.substring(end + 1)); } } } return html.replace(pr_ltEnt, '<').replace(pr_gtEnt, '>').replace(pr_aposEnt, "'").replace(pr_quotEnt, '"').replace(pr_ampEnt, '&').replace(pr_nbspEnt, ' '); } function isRawContent(node) { return 'XMP' === node.tagName; } function normalizedHtml(node, out) { switch (node.nodeType) { case 1: var name = node.tagName.toLowerCase(); out.push('<', name); for (var i = 0; i < node.attributes.length; ++i) { var attr = node.attributes[i]; if (!attr.specified) { continue; } out.push(' '); normalizedHtml(attr, out); } out.push('>'); for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } if (node.firstChild || !/^(?:br|link|img)$/.test(name)) { out.push('<\/', name, '>'); } break; case 2: out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"'); break; case 3: case 4: out.push(textToHtml(node.nodeValue)); break; } } var PR_innerHtmlWorks = null; function getInnerHtml(node) { if (null === PR_innerHtmlWorks) { var testNode = document.createElement('PRE'); testNode.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />')); PR_innerHtmlWorks = !/</.test(testNode.innerHTML); } if (PR_innerHtmlWorks) { var content = node.innerHTML; if (isRawContent(node)) { content = textToHtml(content); } return content; } var out = []; for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } return out.join(''); } function makeTabExpander(tabWidth) { var SPACES = ' '; var charInLine = 0; return function(plainText) { var out = null; var pos = 0; for (var i = 0, n = plainText.length; i < n; ++i) { var ch = plainText.charAt(i); switch (ch) { case '\t': if (!out) { out = []; } out.push(plainText.substring(pos, i)); var nSpaces = tabWidth - (charInLine % tabWidth); charInLine += nSpaces; for (; nSpaces >= 0; nSpaces -= SPACES.length) { out.push(SPACES.substring(0, nSpaces)); } pos = i + 1; break; case '\n': charInLine = 0; break; default: ++charInLine; } } if (!out) { return plainText; } out.push(plainText.substring(pos)); return out.join(''); }; } var pr_chunkPattern = /(?:[^<]+|<!--[\s\S]*?-->|<!\[CDATA\[([\s\S]*?)\]\]>|<\/?[a-zA-Z][^>]*>|<)/g; var pr_commentPrefix = /^<!--/; var pr_cdataPrefix = /^<\[CDATA\[/; var pr_brPrefix = /^<br\b/i; var pr_tagNameRe = /^<(\/?)([a-zA-Z]+)/; function extractTags(s) { var matches = s.match(pr_chunkPattern); var sourceBuf = []; var sourceBufLen = 0; var extractedTags = []; if (matches) { for (var i = 0, n = matches.length; i < n; ++i) { var match = matches[i]; if (match.length > 1 && match.charAt(0) === '<') { if (pr_commentPrefix.test(match)) { continue; } if (pr_cdataPrefix.test(match)) { sourceBuf.push(match.substring(9, match.length - 3)); sourceBufLen += match.length - 12; } else if (pr_brPrefix.test(match)) { sourceBuf.push('\n'); ++sourceBufLen; } else { if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) { var name = match.match(pr_tagNameRe)[2]; var depth = 1; end_tag_loop: for (var j = i + 1; j < n; ++j) { var name2 = matches[j].match(pr_tagNameRe); if (name2 && name2[2] === name) { if (name2[1] === '/') { if (--depth === 0) { break end_tag_loop; } } else { ++depth; } } } if (j < n) { extractedTags.push(sourceBufLen, matches.slice(i, j + 1).join('')); i = j; } else { extractedTags.push(sourceBufLen, match); } } else { extractedTags.push(sourceBufLen, match); } } } else { var literalText = htmlToText(match); sourceBuf.push(literalText); sourceBufLen += literalText.length; } } } return { source: sourceBuf.join(''), tags: extractedTags }; } function isNoCodeTag(tag) { return !!tag.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g, ' $1="$2$3$4"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/); } function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) { var shortcuts = {}; (function() { var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns); for (var i = allPatterns.length; --i >= 0; ) { var patternParts = allPatterns[i]; var shortcutChars = patternParts[3]; if (shortcutChars) { for (var c = shortcutChars.length; --c >= 0; ) { shortcuts[shortcutChars.charAt(c)] = patternParts; } } } })(); var nPatterns = fallthroughStylePatterns.length; var notWs = /\S/; return function(sourceCode, opt_basePos) { opt_basePos = opt_basePos || 0; var decorations = [opt_basePos, PR_PLAIN]; var lastToken = ''; var pos = 0; var tail = sourceCode; while (tail.length) { var style; var token = null; var match; var patternParts = shortcuts[tail.charAt(0)]; if (patternParts) { match = tail.match(patternParts[1]); token = match[0]; style = patternParts[0]; } else { for (var i = 0; i < nPatterns; ++i) { patternParts = fallthroughStylePatterns[i]; var contextPattern = patternParts[2]; if (contextPattern && !contextPattern.test(lastToken)) { continue; } match = tail.match(patternParts[1]); if (match) { token = match[0]; style = patternParts[0]; break; } } if (!token) { style = PR_PLAIN; token = tail.substring(0, 1); } } decorations.push(opt_basePos + pos, style); pos += token.length; tail = tail.substring(token.length); if (style !== PR_COMMENT && notWs.test(token)) { lastToken = token; } } return decorations; }; } var PR_MARKUP_LEXER = createSimpleLexer([], [[PR_PLAIN, /^[^<]+/, null], [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/, null], [PR_COMMENT, /^<!--[\s\S]*?(?:-->|$)/, null], [PR_SOURCE, /^<\?[\s\S]*?(?:\?>|$)/, null], [PR_SOURCE, /^<%[\s\S]*?(?:%>|$)/, null], [PR_SOURCE, /^<(script|style|xmp)\b[^>]*>[\s\S]*?<\/\1\b[^>]*>/i, null], [PR_TAG, /^<\/?\w[^<>]*>/, null]]); var PR_SOURCE_CHUNK_PARTS = /^(<[^>]*>)([\s\S]*)(<\/[^>]*>)$/; function tokenizeMarkup(source) { var decorations = PR_MARKUP_LEXER(source); for (var i = 0; i < decorations.length; i += 2) { if (decorations[i + 1] === PR_SOURCE) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var sourceChunk = source.substring(start, end); var match = sourceChunk.match(PR_SOURCE_CHUNK_PARTS); if (match) { decorations.splice(i, 2, start, PR_TAG, start + match[1].length, PR_SOURCE, start + match[1].length + (match[2] || '').length, PR_TAG); } } } return decorations; } var PR_TAG_LEXER = createSimpleLexer([[PR_ATTRIB_VALUE, /^\'[^\']*(?:\'|$)/, null, "'"], [PR_ATTRIB_VALUE, /^\"[^\"]*(?:\"|$)/, null, '"'], [PR_PUNCTUATION, /^[<>\/=]+/, null, '<>/=']], [[PR_TAG, /^[\w:\-]+/, /^</], [PR_ATTRIB_VALUE, /^[\w\-]+/, /^=/], [PR_ATTRIB_NAME, /^[\w:\-]+/, null], [PR_PLAIN, /^\s+/, null, ' \t\r\n']]); function splitTagAttributes(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_TAG) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var chunk = source.substring(start, end); var subDecorations = PR_TAG_LEXER(chunk, start); spliceArrayInto(subDecorations, decorations, i, 2); i += subDecorations.length - 2; } } return decorations; } function sourceDecorator(options) { var shortcutStylePatterns = [], fallthroughStylePatterns = []; if (options.tripleQuotedStrings) { shortcutStylePatterns.push([PR_STRING, /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/, null, '\'"']); } else if (options.multiLineStrings) { shortcutStylePatterns.push([PR_STRING, /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/, null, '\'"`']); } else { shortcutStylePatterns.push([PR_STRING, /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/, null, '"\'']); } fallthroughStylePatterns.push([PR_PLAIN, /^(?:[^\'\"\`\/\#]+)/, null, ' \r\n']); if (options.hashComments) { shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']); } if (options.cStyleComments) { fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]); fallthroughStylePatterns.push([PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]); } if (options.regexLiterals) { var REGEX_LITERAL = ('^/(?=[^/*])' + '(?:[^/\\x5B\\x5C]' + '|\\x5C[\\s\\S]' + '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+' + '(?:/|$)'); fallthroughStylePatterns.push([PR_STRING, new RegExp(REGEX_LITERAL), REGEXP_PRECEDER_PATTERN]); } var keywords = wordSet(options.keywords); options = null; var splitStringAndCommentTokens = createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns); var styleLiteralIdentifierPuncRecognizer = createSimpleLexer([], [[PR_PLAIN, /^\s+/, null, ' \r\n'], [PR_PLAIN, /^[a-z_$@][a-z_$@0-9]*/i, null], [PR_LITERAL, /^0x[a-f0-9]+[a-z]/i, null], [PR_LITERAL, /^(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?[a-z]*/i, null, '123456789'], [PR_PUNCTUATION, /^[^\s\w\.$@]+/, null]]); function splitNonStringNonCommentTokens(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_PLAIN) { var start, end, chunk, subDecs; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; chunk = source.substring(start, end); subDecs = styleLiteralIdentifierPuncRecognizer(chunk, start); for (var j = 0, m = subDecs.length; j < m; j += 2) { var subStyle = subDecs[j + 1]; if (subStyle === PR_PLAIN) { var subStart = subDecs[j]; var subEnd = j + 2 < m ? subDecs[j + 2] : chunk.length; var token = source.substring(subStart, subEnd); if (token === '.') { subDecs[j + 1] = PR_PUNCTUATION; } else if (token in keywords) { subDecs[j + 1] = PR_KEYWORD; } else if (/^@?[A-Z][A-Z$]*[a-z][A-Za-z$]*$/.test(token)) { subDecs[j + 1] = token.charAt(0) === '@' ? PR_LITERAL : PR_TYPE; } } } spliceArrayInto(subDecs, decorations, i, 2); i += subDecs.length - 2; } } return decorations; } return function(sourceCode) { var decorations = splitStringAndCommentTokens(sourceCode); decorations = splitNonStringNonCommentTokens(sourceCode, decorations); return decorations; }; } var decorateSource = sourceDecorator({ keywords: ALL_KEYWORDS, hashComments: true, cStyleComments: true, multiLineStrings: true, regexLiterals: true }); function splitSourceNodes(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_SOURCE) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var subDecorations = decorateSource(source.substring(start, end)); for (var j = 0, m = subDecorations.length; j < m; j += 2) { subDecorations[j] += start; } spliceArrayInto(subDecorations, decorations, i, 2); i += subDecorations.length - 2; } } return decorations; } function splitSourceAttributes(source, decorations) { var nextValueIsSource = false; for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; var start, end; if (style === PR_ATTRIB_NAME) { start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; nextValueIsSource = /^on|^style$/i.test(source.substring(start, end)); } else if (style === PR_ATTRIB_VALUE) { if (nextValueIsSource) { start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var attribValue = source.substring(start, end); var attribLen = attribValue.length; var quoted = (attribLen >= 2 && /^[\"\']/.test(attribValue) && attribValue.charAt(0) === attribValue.charAt(attribLen - 1)); var attribSource; var attribSourceStart; var attribSourceEnd; if (quoted) { attribSourceStart = start + 1; attribSourceEnd = end - 1; attribSource = attribValue; } else { attribSourceStart = start + 1; attribSourceEnd = end - 1; attribSource = attribValue.substring(1, attribValue.length - 1); } var attribSourceDecorations = decorateSource(attribSource); for (var j = 0, m = attribSourceDecorations.length; j < m; j += 2) { attribSourceDecorations[j] += attribSourceStart; } if (quoted) { attribSourceDecorations.push(attribSourceEnd, PR_ATTRIB_VALUE); spliceArrayInto(attribSourceDecorations, decorations, i + 2, 0); } else { spliceArrayInto(attribSourceDecorations, decorations, i, 2); } } nextValueIsSource = false; } } return decorations; } function decorateMarkup(sourceCode) { var decorations = tokenizeMarkup(sourceCode); decorations = splitTagAttributes(sourceCode, decorations); decorations = splitSourceNodes(sourceCode, decorations); decorations = splitSourceAttributes(sourceCode, decorations); return decorations; } function recombineTagsAndDecorations(sourceText, extractedTags, decorations) { var html = []; var outputIdx = 0; var openDecoration = null; var currentDecoration = null; var tagPos = 0; var decPos = 0; var tabExpander = makeTabExpander(PR_TAB_WIDTH); var adjacentSpaceRe = /([\r\n ]) /g; var startOrSpaceRe = /(^| ) /gm; var newlineRe = /\r\n?|\n/g; var trailingSpaceRe = /[ \r\n]$/; var lastWasSpace = true; function emitTextUpTo(sourceIdx) { if (sourceIdx > outputIdx) { if (openDecoration && openDecoration !== currentDecoration) { html.push('</span>'); openDecoration = null; } if (!openDecoration && currentDecoration) { openDecoration = currentDecoration; html.push('<span class="', openDecoration, '">'); } var htmlChunk = textToHtml(tabExpander(sourceText.substring(outputIdx, sourceIdx))).replace(lastWasSpace ? startOrSpaceRe : adjacentSpaceRe, '$1&nbsp;'); lastWasSpace = trailingSpaceRe.test(htmlChunk); html.push(htmlChunk.replace(newlineRe, '<br />')); outputIdx = sourceIdx; } } while (true) { var outputTag; if (tagPos < extractedTags.length) { if (decPos < decorations.length) { outputTag = extractedTags[tagPos] <= decorations[decPos]; } else { outputTag = true; } } else { outputTag = false; } if (outputTag) { emitTextUpTo(extractedTags[tagPos]); if (openDecoration) { html.push('</span>'); openDecoration = null; } html.push(extractedTags[tagPos + 1]); tagPos += 2; } else if (decPos < decorations.length) { emitTextUpTo(decorations[decPos]); currentDecoration = decorations[decPos + 1]; decPos += 2; } else { break; } } emitTextUpTo(sourceText.length); if (openDecoration) { html.push('</span>'); } return html.join(''); } var langHandlerRegistry = {}; function registerLangHandler(handler, fileExtensions) { for (var i = fileExtensions.length; --i >= 0; ) { var ext = fileExtensions[i]; if (!langHandlerRegistry.hasOwnProperty(ext)) { langHandlerRegistry[ext] = handler; } else if ('console' in window) { console.log('cannot override language handler %s', ext); } } } registerLangHandler(decorateSource, ['default-code']); registerLangHandler(decorateMarkup, ['default-markup', 'html', 'htm', 'xhtml', 'xml', 'xsl']); registerLangHandler(sourceDecorator({ keywords: CPP_KEYWORDS, hashComments: true, cStyleComments: true }), ['c', 'cc', 'cpp', 'cs', 'cxx', 'cyc']); registerLangHandler(sourceDecorator({ keywords: JAVA_KEYWORDS, cStyleComments: true }), ['java']); registerLangHandler(sourceDecorator({ keywords: SH_KEYWORDS, hashComments: true, multiLineStrings: true }), ['bsh', 'csh', 'sh']); registerLangHandler(sourceDecorator({ keywords: PYTHON_KEYWORDS, hashComments: true, multiLineStrings: true, tripleQuotedStrings: true }), ['cv', 'py']); registerLangHandler(sourceDecorator({ keywords: PERL_KEYWORDS, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['perl', 'pl', 'pm']); registerLangHandler(sourceDecorator({ keywords: RUBY_KEYWORDS, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['rb']); registerLangHandler(sourceDecorator({ keywords: JSCRIPT_KEYWORDS, cStyleComments: true, regexLiterals: true }), ['js']); function prettyPrintOne(sourceCodeHtml, opt_langExtension) { try { var sourceAndExtractedTags = extractTags(sourceCodeHtml); var source = sourceAndExtractedTags.source; var extractedTags = sourceAndExtractedTags.tags; if (!langHandlerRegistry.hasOwnProperty(opt_langExtension)) { opt_langExtension = /^\s*</.test(source) ? 'default-markup' : 'default-code'; } var decorations = langHandlerRegistry[opt_langExtension].call({}, source); return recombineTagsAndDecorations(source, extractedTags, decorations); } catch (e) { if ('console' in window) { console.log(e); console.trace(); } return sourceCodeHtml; } } function prettyPrint(opt_whenDone) { var isIE6 = _pr_isIE6(); var codeSegments = [document.getElementsByTagName('pre'), document.getElementsByTagName('code'), document.getElementsByTagName('xmp')]; var elements = []; for (var i = 0; i < codeSegments.length; ++i) { for (var j = 0; j < codeSegments[i].length; ++j) { elements.push(codeSegments[i][j]); } } codeSegments = null; var k = 0; function doWork() { var endTime = (PR_SHOULD_USE_CONTINUATION ? new Date().getTime() + 250 : Infinity); for (; k < elements.length && new Date().getTime() < endTime; k++) { var cs = elements[k]; if (cs.className && cs.className.indexOf('prettyprint') >= 0) { var langExtension = cs.className.match(/\blang-(\w+)\b/); if (langExtension) { langExtension = langExtension[1]; } var nested = false; for (var p = cs.parentNode; p; p = p.parentNode) { if ((p.tagName === 'pre' || p.tagName === 'code' || p.tagName === 'xmp') && p.className && p.className.indexOf('prettyprint') >= 0) { nested = true; break; } } if (!nested) { var content = getInnerHtml(cs); content = content.replace(/(?:\r\n?|\n)$/, ''); var newContent = prettyPrintOne(content, langExtension); if (!isRawContent(cs)) { cs.innerHTML = newContent; } else { var pre = document.createElement('PRE'); for (var i = 0; i < cs.attributes.length; ++i) { var a = cs.attributes[i]; if (a.specified) { var aname = a.name.toLowerCase(); if (aname === 'class') { pre.className = a.value; } else { pre.setAttribute(a.name, a.value); } } } pre.innerHTML = newContent; cs.parentNode.replaceChild(pre, cs); cs = pre; } if (isIE6 && cs.tagName === 'PRE') { var lineBreaks = cs.getElementsByTagName('br'); for (var j = lineBreaks.length; --j >= 0; ) { var lineBreak = lineBreaks[j]; lineBreak.parentNode.replaceChild(document.createTextNode('\r\n'), lineBreak); } } } } } if (k < elements.length) { setTimeout(doWork, 250); } else if (opt_whenDone) { opt_whenDone(); } } doWork(); } window['PR_normalizedHtml'] = normalizedHtml; window['prettyPrintOne'] = prettyPrintOne; window['prettyPrint'] = prettyPrint; window['PR'] = { 'createSimpleLexer': createSimpleLexer, 'registerLangHandler': registerLangHandler, 'sourceDecorator': sourceDecorator, 'PR_ATTRIB_NAME': PR_ATTRIB_NAME, 'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE, 'PR_COMMENT': PR_COMMENT, 'PR_DECLARATION': PR_DECLARATION, 'PR_KEYWORD': PR_KEYWORD, 'PR_LITERAL': PR_LITERAL, 'PR_NOCODE': PR_NOCODE, 'PR_PLAIN': PR_PLAIN, 'PR_PUNCTUATION': PR_PUNCTUATION, 'PR_SOURCE': PR_SOURCE, 'PR_STRING': PR_STRING, 'PR_TAG': PR_TAG, 'PR_TYPE': PR_TYPE }; })();
+\ No newline at end of file
+diff -ruN CNPROG/templates/content/js/com.cnprog.utils.js mikes/templates/content/js/com.cnprog.utils.js
+--- CNPROG/templates/content/js/com.cnprog.utils.js 2009-06-22 21:42:51.000000000 -0400
++++ mikes/templates/content/js/com.cnprog.utils.js 2009-07-25 19:09:58.138152577 -0400
+@@ -119,4 +113,4 @@
+ }();
+ //Search Engine Keyword Highlight with Javascript
+ //http://scott.yang.id.au/code/se-hilite/
+-Hilite={elementid:"content",exact:true,max_nodes:1000,onload:true,style_name:"hilite",style_name_suffix:true,debug_referrer:""};Hilite.search_engines=[["local","q"],["cnprog\\.","q"],["google\\.","q"],["search\\.yahoo\\.","p"],["search\\.msn\\.","q"],["search\\.live\\.","query"],["search\\.aol\\.","userQuery"],["ask\\.com","q"],["altavista\\.","q"],["feedster\\.","q"],["search\\.lycos\\.","q"],["alltheweb\\.","q"],["technorati\\.com/search/([^\\?/]+)",1],["dogpile\\.com/info\\.dogpl/search/web/([^\\?/]+)",1,true]];Hilite.decodeReferrer=function(d){var g=null;var e=new RegExp("");for(var c=0;c<Hilite.search_engines.length;c++){var f=Hilite.search_engines[c];e.compile("^http://(www\\.)?"+f[0],"i");var b=d.match(e);if(b){var a;if(isNaN(f[1])){a=Hilite.decodeReferrerQS(d,f[1])}else{a=b[f[1]+1]}if(a){a=decodeURIComponent(a);if(f.length>2&&f[2]){a=decodeURIComponent(a)}a=a.replace(/\'|"/g,"");a=a.split(/[\s,\+\.]+/);return a}break}}return null};Hilite.decodeReferrerQS=function(f,d){var b=f.indexOf("?");var c;if(b>=0){var a=new String(f.substring(b+1));b=0;c=0;while((b>=0)&&((c=a.indexOf("=",b))>=0)){var e,g;e=a.substring(b,c);b=a.indexOf("&",c)+1;if(e==d){if(b<=0){return a.substring(c+1)}else{return a.substring(c+1,b-1)}}else{if(b<=0){return null}}}}return null};Hilite.hiliteElement=function(f,e){if(!e||f.childNodes.length==0){return}var c=new Array();for(var b=0;b<e.length;b++){e[b]=e[b].toLowerCase();if(Hilite.exact){c.push("\\b"+e[b]+"\\b")}else{c.push(e[b])}}c=new RegExp(c.join("|"),"i");var a={};for(var b=0;b<e.length;b++){if(Hilite.style_name_suffix){a[e[b]]=Hilite.style_name+(b+1)}else{a[e[b]]=Hilite.style_name}}var d=function(m){var j=c.exec(m.data);if(j){var n=j[0];var i="";var h=m.splitText(j.index);var g=h.splitText(n.length);var l=m.ownerDocument.createElement("SPAN");m.parentNode.replaceChild(l,h);l.className=a[n.toLowerCase()];l.appendChild(h);return l}else{return m}};Hilite.walkElements(f.childNodes[0],1,d)};Hilite.hilite=function(){var a=Hilite.debug_referrer?Hilite.debug_referrer:document.referrer;var b=null;a=Hilite.decodeReferrer(a);if(a&&((Hilite.elementid&&(b=document.getElementById(Hilite.elementid)))||(b=document.body))){Hilite.hiliteElement(b,a)}};Hilite.walkElements=function(d,f,e){var a=/^(script|style|textarea)/i;var c=0;while(d&&f>0){c++;if(c>=Hilite.max_nodes){var b=function(){Hilite.walkElements(d,f,e)};setTimeout(b,50);return}if(d.nodeType==1){if(!a.test(d.tagName)&&d.childNodes.length>0){d=d.childNodes[0];f++;continue}}else{if(d.nodeType==3){d=e(d)}}if(d.nextSibling){d=d.nextSibling}else{while(f>0){d=d.parentNode;f--;if(d.nextSibling){d=d.nextSibling;break}}}}};if(Hilite.onload){if(window.attachEvent){window.attachEvent("onload",Hilite.hilite)}else{if(window.addEventListener){window.addEventListener("load",Hilite.hilite,false)}else{var __onload=window.onload;window.onload=function(){Hilite.hilite();__onload()}}}};
++Hilite={elementid:"content",exact:true,max_nodes:1000,onload:true,style_name:"hilite",style_name_suffix:true,debug_referrer:""};Hilite.search_engines=[["local","q"],["cnprog\\.","q"],["google\\.","q"],["search\\.yahoo\\.","p"],["search\\.msn\\.","q"],["search\\.live\\.","query"],["search\\.aol\\.","userQuery"],["ask\\.com","q"],["altavista\\.","q"],["feedster\\.","q"],["search\\.lycos\\.","q"],["alltheweb\\.","q"],["technorati\\.com/search/([^\\?/]+)",1],["dogpile\\.com/info\\.dogpl/search/web/([^\\?/]+)",1,true]];Hilite.decodeReferrer=function(d){var g=null;var e=new RegExp("");for(var c=0;c<Hilite.search_engines.length;c++){var f=Hilite.search_engines[c];e.compile("^http://(www\\.)?"+f[0],"i");var b=d.match(e);if(b){var a;if(isNaN(f[1])){a=Hilite.decodeReferrerQS(d,f[1])}else{a=b[f[1]+1]}if(a){a=decodeURIComponent(a);if(f.length>2&&f[2]){a=decodeURIComponent(a)}a=a.replace(/\'|"/g,"");a=a.split(/[\s,\+\.]+/);return a}break}}return null};Hilite.decodeReferrerQS=function(f,d){var b=f.indexOf("?");var c;if(b>=0){var a=new String(f.substring(b+1));b=0;c=0;while((b>=0)&&((c=a.indexOf("=",b))>=0)){var e,g;e=a.substring(b,c);b=a.indexOf("&",c)+1;if(e==d){if(b<=0){return a.substring(c+1)}else{return a.substring(c+1,b-1)}}else{if(b<=0){return null}}}}return null};Hilite.hiliteElement=function(f,e){if(!e||f.childNodes.length==0){return}var c=new Array();for(var b=0;b<e.length;b++){e[b]=e[b].toLowerCase();if(Hilite.exact){c.push("\\b"+e[b]+"\\b")}else{c.push(e[b])}}c=new RegExp(c.join("|"),"i");var a={};for(var b=0;b<e.length;b++){if(Hilite.style_name_suffix){a[e[b]]=Hilite.style_name+(b+1)}else{a[e[b]]=Hilite.style_name}}var d=function(m){var j=c.exec(m.data);if(j){var n=j[0];var i="";var h=m.splitText(j.index);var g=h.splitText(n.length);var l=m.ownerDocument.createElement("SPAN");m.parentNode.replaceChild(l,h);l.className=a[n.toLowerCase()];l.appendChild(h);return l}else{return m}};Hilite.walkElements(f.childNodes[0],1,d)};Hilite.hilite=function(){var a=Hilite.debug_referrer?Hilite.debug_referrer:document.referrer;var b=null;a=Hilite.decodeReferrer(a);if(a&&((Hilite.elementid&&(b=document.getElementById(Hilite.elementid)))||(b=document.body))){Hilite.hiliteElement(b,a)}};Hilite.walkElements=function(d,f,e){var a=/^(script|style|textarea)/i;var c=0;while(d&&f>0){c++;if(c>=Hilite.max_nodes){var b=function(){Hilite.walkElements(d,f,e)};setTimeout(b,50);return}if(d.nodeType==1){if(!a.test(d.tagName)&&d.childNodes.length>0){d=d.childNodes[0];f++;continue}}else{if(d.nodeType==3){d=e(d)}}if(d.nextSibling){d=d.nextSibling}else{while(f>0){d=d.parentNode;f--;if(d.nextSibling){d=d.nextSibling;break}}}}};if(Hilite.onload){if(window.attachEvent){window.attachEvent("onload",Hilite.hilite)}else{if(window.addEventListener){window.addEventListener("load",Hilite.hilite,false)}else{var __onload=window.onload;window.onload=function(){Hilite.hilite();__onload()}}}};
+\ No newline at end of file
+diff -ruN CNPROG/templates/content/style/openid.css mikes/templates/content/style/openid.css
+--- CNPROG/templates/content/style/openid.css 2009-06-22 21:42:51.000000000 -0400
++++ mikes/templates/content/style/openid.css 2009-07-25 19:09:58.168153308 -0400
+@@ -42,4 +42,4 @@
+ }
+ .openid_selected {
+ border: 4px solid #DDD;
+- }
++ }
+\ No newline at end of file
+diff -ruN CNPROG/templates/okfiles mikes/templates/okfiles
+--- CNPROG/templates/okfiles 2009-06-22 21:42:52.000000000 -0400
++++ mikes/templates/okfiles 1969-12-31 19:00:00.000000000 -0500
+@@ -1,30 +0,0 @@
+-404.html
+-500.html
+-about.html
+-ask.html
+-badges.html
+-base_content.html
+-base.html
+-book.html
+-close.html
+-faq.html
+-footer.html
+-header.html
+-index.html
+-logout.html
+-pagesize.html
+-paginator.html
+-privacy.html
+-question_edit_tips.html
+-question.html
+-questions.html
+-revisions_answer.html
+-tags.html
+-unanswered.html
+-user_edit.html
+-user_info.html
+-users.html
+-users_questions.html
+-user_stats.html
+-user_tabs.html
+-user_votes.html
+diff -ruN CNPROG/templates/pagesize.html mikes/templates/pagesize.html
+--- CNPROG/templates/pagesize.html 2009-06-22 21:42:52.000000000 -0400
++++ mikes/templates/pagesize.html 2009-07-25 19:09:58.168153308 -0400
+@@ -1,9 +1,8 @@
+-<!-- template pagesize.html -->
+ {% spaceless %}
+ {% load i18n %}
+ {% if is_paginated %}
+ <div class="paginator">
+- <span class="text">{% trans "posts per page" %}</span>
++ <span class="text">{% trans "Size per page:" %}</span>
+ {% ifequal pagesize 10 %}
+ <span class="curr">10</span>
+ {% else %}
+@@ -24,4 +23,3 @@
+ </div>
+ {% endif %}
+ {% endspaceless %}
+-<!-- end template pagesize.html -->
+diff -ruN CNPROG/templates/question_retag.html mikes/templates/question_retag.html
+--- CNPROG/templates/question_retag.html 1969-12-31 19:00:00.000000000 -0500
++++ mikes/templates/question_retag.html 2009-07-25 19:09:58.178152900 -0400
+@@ -0,0 +1,109 @@
++{% extends "base.html" %}
++{% block title %}{% spaceless %}淇敼闂鏍囩{% endspaceless %}{% endblock %}
++{% block forejs %}
++ <script type='text/javascript' src='/content/js/com.cnprog.editor.js'></script>
++ <script type='text/javascript' src='/content/js/com.cnprog.post.js'></script>
++ <script type='text/javascript' src='/content/js/jquery.validate.pack.js'></script>
++ <script type="text/javascript">
++
++ $().ready(function(){
++ $("#nav_questions").attr('className',"on");
++ //Tags autocomplete action
++ var tags = {{ tags|safe }};
++ $("#id_tags").autocomplete(tags, {
++ minChars: 1,
++ matchContains: true,
++ max: 20,
++ multiple: true,
++ multipleSeparator: " ",
++ formatItem: function(row, i, max) {
++ return row.n + " ("+ row.c +")";
++ },
++ formatResult: function(row, i, max){
++ return row.n;
++ }
++
++ });
++
++ $("#fmretag").validate({
++ rules: {
++ tags: {
++ required: true,
++ maxength: 105
++ }
++ },
++ messages: {
++ tags: {
++ required: " 鏍囩涓嶈兘涓虹┖銆",
++ maxlength: " 鏈澶5涓爣绛撅紝姣忎釜鏍囩闀垮害灏忎簬20涓瓧绗︺"
++ }
++ }
++
++ });
++ lanai.highlightSyntax();
++
++ });
++ </script>
++{% endblock %}
++
++{% block content %}
++<div id="main-bar" class="headNormal">
++ 淇敼鏍囩 [<a href="{{ question.get_absolute_url }}">杩斿洖</a>]
++</div>
++<div id="main-body" class="ask-body">
++ <div id="askform">
++ <form id="fmretag" action="{% url edit_question question.id %}" method="post" >
++ <h3>
++ {{ question.get_question_title }}
++ </h3>
++ <div id="description" class="edit-content-html">
++ {{ question.html|safe }}
++ </div>
++
++
++ <div class="form-item">
++ <strong>{{ form.tags.label_tag }}:</strong> <span class="form-error"></span><br>
++ {{ form.tags }} {{ form.tags.errors }}
++ <div class="title-desc">
++ {{ form.tags.help_text }}
++ </div>
++ </div>
++ <br>
++
++ <div class="error" ></div>
++ <input type="submit" value="鐜板湪淇敼" class="submit" />
++ <input type="button" value="鍙栨秷" class="submit" onclick="history.back(-1);" />
++ <br>
++ <br>
++ </form>
++ </div>
++</div>
++{% endblock %}
++
++{% block sidebar %}
++<div class="boxC">
++ <p class="subtitle">涓轰粈涔堟垜鍙兘淇敼闂鏍囩锛</p>
++ <ul class="list-item">
++
++ <li>
++ CNProg鐢ㄦ爣绛炬潵鍒嗙被绯荤粺鐨勪俊鎭
++
++ </li>
++ <li>
++ 淇敼瀹屾暣闂闇瑕佺敤鎴风殑绉垎杈惧埌涓瀹氭潯浠讹紙姣斿锛氱Н鍒 >= 3000鍒嗭紝鑷繁鍙戝竷鐨勯棶棰橀櫎澶栵級锛岃岀敤鎴风Н鍒嗚揪鍒版瘮杈冧綆鐨勬椂鍊欙紝灏卞彲浠ヤ慨鏀归棶棰樼殑鏍囩锛堟瘮濡傦細绉垎 >= 500, 杩欓噷鎸囨墍鏈夐棶棰樼殑鏍囩锛夈
++
++ </li>
++ <li>
++ 淇敼鏍囩鐨勭敤鎴峰皢鎺堜簣鐗规畩鐨勭ぞ鍖哄鐗
++
++ </li>
++ </ul>
++ <a href="{% url faq %}" style="float:right;position:relative">faq 禄</a>
++ <br>
++</div>
++
++{% endblock %}
++
++{% block endjs %}
++{% endblock %}
++
+diff -ruN CNPROG/templates/template.list mikes/templates/template.list
+--- CNPROG/templates/template.list 2009-06-22 21:42:52.000000000 -0400
++++ mikes/templates/template.list 1969-12-31 19:00:00.000000000 -0500
+@@ -1,18 +0,0 @@
+-close.html
+-book.html
+-base_content.html
+-badges.html
+-badge.html
+-ask.html
+-answer_edit_tips.html
+-answer_edit.html
+-about.html
+-500.html
+-404.html
+-pagesize.html
+-logout.html
+-header.html
+-footer.html
+-faq.html
+-base.html
+-question.html
+diff -ruN CNPROG/templates/tough/faq.html mikes/templates/tough/faq.html
+--- CNPROG/templates/tough/faq.html 2009-06-22 21:42:52.000000000 -0400
++++ mikes/templates/tough/faq.html 1969-12-31 19:00:00.000000000 -0500
+@@ -1,110 +0,0 @@
+-{% extends "base_content.html" %}
+-{% load extra_tags %}
+-{% load humanize %}
+-{% block title %}{% spaceless %}FAQ{% endspaceless %}{% endblock %}
+-{% block forejs %}
+-{% endblock %}
+-{% block content %}
+-<div class="headNormal">
+- {% trans "Frequently Asked Questions " %}(FAQ)
+-</div>
+-<div id="main-body" style="width:100%">
+-
+- <h3 class="subtitle">{% trans "What kinds of questions can I ask here?" %}</h3>
+- <p>{% trans "Most importanly - questions should be <strong>relevant</strong> to this community." %}<br>
+- {% trans "Before asking the question - please make sure to use search to see whether your question has alredy been answered."%}<br>
+- </p><br>
+-
+- <h3 class="subtitle">{% trans "What questions should I avoid asking?" %}</h3>
+- <p>{% trans "Please avoid asking questions that are not relevant to this community, too subjective and argumentative." %}</p>
+- </p><br>
+-
+- <h3 class="subtitle">{% trans "What should I avoid in my answers?" %}</h3>
+- <p>{% trans "site title" %} {% trans "is a Q&A site, not a discussion group. Therefore - please avoid having discussions in your answers, comment facility allows some space for brief discussions." %}
+- </p><br>
+-
+- <h3 class="subtitle">{% trans "Who moderates this community?" %}</h3>
+- <p>{% trans "The short answer is: <strong>you</strong>." %}<br>
+- {% trans "This website is moderated by the users." %}
+- {% trans "The reputation system allows users earn the authorization to perform a variety of moderation tasks." %}
+- </p><br>
+-
+- <h3 class="subtitle">{% trans "How does reputation system work?" %}</h3>
+- <p>{% trans "Anyone can ask questions and give answers, points are not necessary for that." %}<br>
+- {% trans "As we've said before, users help running this site. Point system helps select users who can administer this community."%}
+- {% trans "Reputation points roughly measure how community trusts you. These points are given to you directly by other members of the community." %}
+- </p>
+- <p>
+- {% trans "For example, if you ask an interesting question or give a helpful answer, your input will be upvoted and you will gain more trust in the community." %}
+- {% trans "If on the other hand someone gives a misleading answer, the answer will be voted down and he/she loses some points." %}
+- {% trans "Each vote in favor will generate <strong>10</strong> points, each vote against will subtract <strong>2</strong> points." trans %}
+- {% trans "Through the votes of other people you can accumulate a maximum of <strong>200</strong> points." %}
+- {% "After accumulating certain number of points, you can do more:" %}
+- <table style="font-family:arial;" cellspacing="3" cellpadding="3">
+- <tr>
+- <th width="40px" style="text-align:right"></th>
+- <th width="300px"></th>
+- </tr>
+- <tr>
+- <td style="text-align:right;padding-right:5px"><strong>15</strong></td>
+- <td>{% trans "upvote" %}</td>
+- </tr>
+- <tr>
+- <td style="text-align:right;padding-right:5px"><strong>15</strong></td>
+- <td>{% trans "use tags" %}</td>
+- </tr>
+- <tr>
+- <td style="text-align:right;padding-right:5px"><strong>50</strong></td>
+- <td>{% trans "add comments" %}</td>
+- </tr>
+- <tr>
+- <td style="text-align:right;padding-right:5px"><strong>100</strong></td>
+- <td>{% trans "downvote" %}</td>
+- </tr><tr>
+- <td style="text-align:right;padding-right:5px"><strong>250</strong></td>
+- <td>鎵撳紑鍏抽棴鑷繁鐨勯棶棰</td>
+- </tr>
+- <tr>
+- <td style="text-align:right;padding-right:5px"><strong>500</strong></td>
+- <td>{% trans "retag questions" %}</td>
+- </tr>
+- <tr>
+- <td style="text-align:right;padding-right:5px"><strong>750</strong></td>
+- <td>{% trans "edit community wiki questions" %}</td>
+- </tr>
+- <tr>
+- <td style="text-align:right;padding-right:5px"><strong>2000</strong></td>
+- <td>{% trans "edit any answer" %}</td>
+- </tr>
+- <tr>
+- <td style="text-align:right;padding-right:5px"><strong>3000</strong></td>
+- <td>{% trans "open any closed question" %}</td>
+- </tr>
+- <tr>
+- <td style="text-align:right;padding-right:5px"><strong>5000</strong></td>
+- <td>{% trans "delete any comment" %}</td>
+- </tr>
+- <tr>
+- <td style="text-align:right;padding-right:5px"><strong>10000</strong></td>
+- <td>{% trans "delete any questions and answers and perform other moderation tasks" %}</td>
+- </tr>
+-
+- </table>
+-
+- </p><br>
+-
+- <h3 class="subtitle">{% trans "To register, do I need to create new password?"</h3>
+- <p>{% trans "No, you don't have to. You can login through any service that supports OpenID, e.g. Google, Yahoo, AOL, etc." %}
+- <strong><a href="/account/signin">{% trans "Login now!" %}</a> 禄</strong>
+- </p><br>
+-
+- <h3 class="subtitle">{% trans "Why other people can edit my questions/answers?" %}</h3>
+- <p> {% trans "Goal of this site is..." %} {% trans "So questions and answers can be edited like wiki pages by experienced users of this site and this improves the overall quality of the knowledge base content." %}
+- {% trans "If this approach is not for you, we respect your choice." %}
+- </p><br>
+- <h3 class="subtitle">{% trans "Still have questions?" %}</h3>
+- <p>{% "Please ask your question, help make our community better!" %} <a href="/tags/faq" class="big">{% trans "site title" %} {% trans "questions" %}</a>{% trans "." %}
+- </p>
+- <br><br>
+-</div>
+-{% endblock %}
+diff -ruN CNPROG/templates/tough/question_retag.html mikes/templates/tough/question_retag.html
+--- CNPROG/templates/tough/question_retag.html 2009-06-22 21:42:52.000000000 -0400
++++ mikes/templates/tough/question_retag.html 1969-12-31 19:00:00.000000000 -0500
+@@ -1,107 +0,0 @@
+-{% extends "base.html" %}
+-{% block title %}{% spaceless %}{% trans "Revise tags" %}{% endspaceless %}{% endblock %}
+-{% block forejs %}
+- <script type='text/javascript' src='/content/js/com.cnprog.editor.js'></script>
+- <script type='text/javascript' src='/content/js/com.cnprog.post.js'></script>
+- <script type='text/javascript' src='/content/js/jquery.validate.pack.js'></script>
+- <script type="text/javascript">
+-
+- $().ready(function(){
+- $("#nav_questions").attr('className',"on");
+- //Tags autocomplete action
+- var tags = {{ tags|safe }};
+- $("#id_tags").autocomplete(tags, {
+- minChars: 1,
+- matchContains: true,
+- max: 20,
+- multiple: true,
+- multipleSeparator: " ",
+- formatItem: function(row, i, max) {
+- return row.n + " ("+ row.c +")";
+- },
+- formatResult: function(row, i, max){
+- return row.n;
+- }
+-
+- });
+-
+- $("#fmretag").validate({
+- rules: {
+- tags: {
+- required: true,
+- maxength: 105
+- }
+- },
+- messages: {
+- tags: {
+- required: ' ' + {% trans "tags are requried" %},
+- maxlength: ' ' + {% trans "up to 5 tags, less than 20 characters each" %},
+- }
+- }
+-
+- });
+- lanai.highlightSyntax();
+-
+- });
+- </script>
+-{% endblock %}
+-
+-{% block content %}
+-<div id="main-bar" class="headNormal">
+- {% trans "Change tags" %} [<a href="{{ question.get_absolute_url }}">{% trans "back" %}</a>]
+-</div>
+-<div id="main-body" class="ask-body">
+- <div id="askform">
+- <form id="fmretag" action="{% url edit_question question.id %}" method="post" >
+- <h3>
+- {{ question.get_question_title }}
+- </h3>
+- <div id="description" class="edit-content-html">
+- {{ question.html|safe }}
+- </div>
+-
+-
+- <div class="form-item">
+- <strong>{{ form.tags.label_tag }}:</strong> <span class="form-error"></span><br>
+- {{ form.tags }} {{ form.tags.errors }}
+- <div class="title-desc">
+- {{ form.tags.help_text }}
+- </div>
+- </div>
+- <br>
+-
+- <div class="error" ></div>
+- <input type="submit" value="{% trans "Change now" %}" class="submit" />
+- <input type="button" value="{% trans "Cancel" %}" class="submit" onclick="history.back(-1);" />
+- <br>
+- <br>
+- </form>
+- </div>
+-</div>
+-{% endblock %}
+-
+-{% block sidebar %}
+-<div class="boxC">
+- <p class="subtitle">{% trans "Why use and modify tags?" %}</p>
+- <ul class="list-item">
+-
+- <li>
+- {% trans "site title" %} {% trans "uses tags for the classification of questions %}
+- </li>
+- <li>
+- 淇敼瀹屾暣闂闇瑕佺敤鎴风殑绉垎杈惧埌涓瀹氭潯浠讹紙姣斿锛氱Н鍒 >= 3000鍒嗭紝鑷繁鍙戝竷鐨勯棶棰橀櫎澶栵級锛岃岀敤鎴风Н鍒嗚揪鍒版瘮杈冧綆鐨勬椂鍊欙紝灏卞彲浠ヤ慨鏀归棶棰樼殑鏍囩锛堟瘮濡傦細绉垎 >= 500, 杩欓噷鎸囨墍鏈夐棶棰樼殑鏍囩锛夈
+-
+- </li>
+- <li>
+- {% trans "tag editors receive special awards from the community" %}
+- </li>
+- </ul>
+- <a href="{% url faq %}" style="float:right;position:relative">faq 禄</a>
+- <br>
+-</div>
+-
+-{% endblock %}
+-
+-{% block endjs %}
+-{% endblock %}
+-
+diff -ruN CNPROG/templates/tough/unanswered.html mikes/templates/tough/unanswered.html
+--- CNPROG/templates/tough/unanswered.html 2009-06-22 21:42:52.000000000 -0400
++++ mikes/templates/tough/unanswered.html 1969-12-31 19:00:00.000000000 -0500
+@@ -1,115 +0,0 @@
+-{% extends "base.html" %}
+-{% load extra_tags %}
+-{% load humanize %}
+-{% load extra_filters %}
+-{% block title %}{% spaceless %}{% trans "Unanswered questions" %}{% endspaceless %}{% endblock %}
+-{% block forejs %}
+- <script type="text/javascript">
+- $().ready(function(){
+- $("#nav_unanswered").attr('className',"on");
+- });
+-
+- </script>
+-{% endblock %}
+-{% block content %}
+-<div class="tabBar">
+- <span class="headQuestions">{% trans "Unanswered questions" %}</span>
+- <div class="tabsA">
+- <a id="latest" href="?sort=latest" class="on" title="{% trans "most recently asked questions" %}>{% trans "newest" %}</a>
+- </div>
+-</div>
+-
+-<div id="listA">
+- {% for question in questions.object_list %}
+- <div class="qstA">
+- <h2><a href="{{ question.get_absolute_url }}">{{ question.get_question_title }}</a></h2>
+- <div class="stat">
+- <table>
+- <tr>
+- <td><span class="num">{{ question.answer_count|intcomma }}</span> </td>
+- <td><span class="num">{{ question.score|intcomma }}</span> </td>
+- <td><span class="num">{{ question.view_count|cnprog_intword|safe }}</span> </td>
+- </tr>
+- <tr>
+- <td><span class="unit">{% trans "answers" %}</span></td>
+- <td><span class="unit">{% trans "votes" %}</span></td>
+- <td><span class="unit">{% trans "views" %}</span></td>
+- </tr>
+- </table>
+- </div>
+- <div class="summary">
+- {{ question.summary }}...
+- </div>
+-
+- {% ifequal tab_id 'active'%}
+- {% if question.wiki %}
+- <span class="from wiki">{% trans "community wiki" %}</span>
+- <span class="date" title="{{ question.added_at }}">{% diff_date question.added_at %}</span>
+- {% else %}
+- <div class="from">
+- {% comment %}{% gravatar question.last_activity_by 24 %}{% endcomment %}
+- <span class="author"><a href="{{ question.last_activity_by.get_profile_url }}">{{ question.last_activity_by }}</a></span>
+- <span class="score">{% get_score_badge question.last_activity_by %} </span>
+- <span class="date" title="{{ question.last_activity_at }}">{% diff_date question.last_activity_at %}</span>
+- </div>
+- {% endif %}
+- {% else %}
+- {% if question.wiki %}
+- <span class="from wiki">{% trans "community wiki" %}</span>
+- <span class="date" title="{{ question.added_at }}">{% diff_date question.added_at %}</span>
+- {% else %}
+- <div class="from">
+- {% comment %}{% gravatar question.author 24 %}{% endcomment %}
+- <span class="author"><a href="{{ question.author.get_profile_url }}">{{ question.author }}</a></span>
+- <span class="score">{% get_score_badge question.author %} </span>
+- <span class="date" title="{{ question.added_at }}">{% diff_date question.added_at %}</span>
+- </div>
+- {% endif %}
+- {% endifequal %}
+-
+- <div class="tags">
+- {% for tag in question.tagname_list %}
+- <a href="{% url forum.views.tag tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+- {% endfor %}
+- </div>
+- </div>
+- {% endfor %}
+-</div>
+-{% endblock %}
+-
+-{% block tail %}
+- <div class="pager">
+- {% cnprog_paginator context %}
+-
+- </div>
+- <div class="pagesize">
+- {% cnprog_pagesize context %}
+- </div>
+-{% endblock %}
+-
+-{% block sidebar %}
+-<div class="boxC">
+- <p>
+- <!--todo: move this to blocktrans -->
+- {% tans "Have a total of" %}<br><div class="questions-count">{{ questions_count|intcomma }}</div>
+- <p>{% trans "number of <strong>unanswered</strong> questions" %}</p>
+- <p>闂鎸 <strong>闂鍒涘缓鏃堕棿</strong> 鎺掑簭銆傛渶鏂板姞鍏ョ殑闂灏嗘樉绀哄湪鏈鍓嶉潰銆</p>
+-
+- </p>
+-</div>
+-<div class="boxC">
+- <h3 class="subtitle">{% trans "Related tags" %}</h3>
+- <div class="body">
+- <div class="tags">
+- {% for tag in tags %}
+- <a rel="tag" title="{% trans "see questions tagged"%}'{{ tag.name }}'{% trans "using tags" %}" href="{% url forum.views.tag tag.name|urlencode %}">{{ tag.name }}</a>
+- <span class="tag-number">脳 {{ tag.used_count|intcomma }}</span>
+- <br>
+- {% endfor %}
+- <br>
+- </div>
+- </div>
+-</div>
+-
+-{% endblock %}
+-
+diff -ruN CNPROG/templates/user_preferences.html mikes/templates/user_preferences.html
+--- CNPROG/templates/user_preferences.html 2009-06-22 21:42:52.000000000 -0400
++++ mikes/templates/user_preferences.html 2009-07-25 19:09:58.178152900 -0400
+@@ -1,11 +1,20 @@
+-<!-- user_preferences.html -->
+ {% extends "user.html" %}
+ {% load extra_tags %}
+ {% load humanize %}
+
+ {% block usercontent %}
+ <div style="padding:5px;">
+- <h1>Surprise will be here soon ;-)</h1>
++ <fieldset>
++ <legend><b>鍚屾Twitter娑堟伅</b></legend>
++ <form>
++ <label for="name">璐﹀彿:</label>
++ <input id="name" /><br>
++ <label for="password">瀵嗙爜:</label>
++ <input id="password" type="password"/><br>
++ <input id="cbMessage" type="checkbox" />鍙戝竷鎴戠殑鎻愰棶鍒版垜鐨凾witter<br>
++ <input id="cbReply" type="checkbox" />鍙戝竷鎴戠殑鍥炵瓟鍒版垜鐨凾witter<br>
++ <input type="submit" value="淇濆瓨" />
++ </form>
++ </fieldset>
+ </div>
+ {% endblock %}
+-<!-- end user_preferences.html -->
+diff -ruN CNPROG/urls.py mikes/urls.py
+--- CNPROG/urls.py 2009-06-22 21:42:52.000000000 -0400
++++ mikes/urls.py 2009-07-25 19:09:58.178152900 -0400
+@@ -60,4 +60,5 @@
+ url(r'^books/ask/(?P<short_name>[^/]+)/$', app.ask_book, name='ask_book'),
+ url(r'^books/(?P<short_name>[^/]+)/$', app.book, name='book'),
+ url(r'^search/$', app.search, name='search'),
++ (r'^i18n/', include('django.conf.urls.i18n')),
+ )
diff --git a/settings.py b/settings.py
index 88dd0cc7..985de51a 100644
--- a/settings.py
+++ b/settings.py
@@ -1,51 +1,24 @@
+# encoding:utf-8
# Django settings for lanai project.
import os.path
+#DEBUG SETTINGS
DEBUG = True
TEMPLATE_DEBUG = DEBUG
-
-
-#David Cramer debug toolbar
INTERNAL_IPS = ('127.0.0.1',)
-DEBUG_TOOLBAR_PANELS = (
- 'debug_toolbar.panels.sql.SQLDebugPanel',
- 'debug_toolbar.panels.headers.HeaderDebugPanel',
- 'debug_toolbar.panels.cache.CacheDebugPanel',
- 'debug_toolbar.panels.profiler.ProfilerDebugPanel',
- 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
- 'debug_toolbar.panels.templates.TemplatesDebugPanel',
- # If you are using the profiler panel you don't need the timer
- # 'debug_toolbar.panels.timer.TimerDebugPanel',
-)
-
-DEBUG_TOOLBAR_CONFIG = {
- "INTERCEPT_REDIRECTS":False
-}
#for OpenID auth
ugettext = lambda s: s
LOGIN_URL = '/%s%s' % (ugettext('account/'), ugettext('signin/'))
-#system will send admins email about error stacktrace if DEBUG=False
+#EMAIL AND ADMINS
ADMINS = (
- ('you', 'you@where.com'),
+ ('CNProg team', 'team@cnprog.com'),
)
-
MANAGERS = ADMINS
-DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
-#DATABASE_NAME = 'cnprog' # Or path to database file if using sqlite3.
-#DATABASE_USER = 'root' # Not used with sqlite3.
-#DATABASE_PASSWORD = '' # Not used with sqlite3.
-DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
-DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
-
-DATABASE_NAME = 'dbname' # Or path to database file if using sqlite3.
-DATABASE_USER = 'dbuser' # Not used with sqlite3.
-DATABASE_PASSWORD = 'dbpass' # Not used with sqlite3.
-
-SERVER_EMAIL = 'server@where.com'
-DEFAULT_FROM_EMAIL = 'from@where.com'
+SERVER_EMAIL = 'webmaster@cnprog.com'
+DEFAULT_FROM_EMAIL = 'webmaster@cnprog.com'
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_SUBJECT_PREFIX = '[cnprog.com]'
@@ -53,44 +26,21 @@ EMAIL_HOST='smtp.gmail.com'
EMAIL_PORT='587'
EMAIL_USE_TLS=True
-
-
-
-# Local time zone for this installation. Choices can be found here:
-# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
-# although not all choices may be available on all operating systems.
-# If running in a Windows environment this must be set to the same as your
-# system time zone.
-TIME_ZONE = 'America/Chicago'
-
-# Language code for this installation. All choices can be found here:
-# http://www.i18nguy.com/unicode/language-identifiers.html
-#LANGUAGE_CODE = 'en'
+#LOCALIZATIONS
+TIME_ZONE = 'Asia/Chongqing Asia/Chungking'
+# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-cn'
-
SITE_ID = 1
-
-# If you set this to False, Django will make some optimizations so as not
-# to load the internationalization machinery.
USE_I18N = True
-# Absolute path to the directory that holds media.
-# Example: "/home/media/media.lawrence.com/"
-MEDIA_ROOT = '/var/www/vhosts/cnprog/templates/upfiles/'
-
-# URL that handles the media served from MEDIA_ROOT. Make sure to use a
-# trailing slash if there is a path component (optional in other cases).
-# Examples: "http://media.lawrence.com", "http://example.com/media/"
-MEDIA_URL = 'http://where.com/upfiles/'
-
-# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
-# trailing slash.
-# Examples: "http://foo.com/media/", "/media/".
+#OTHER SETTINS
+APP_TITLE = u'CNProg.com 绋嬪簭鍛橀棶绛旂ぞ鍖'
+APP_URL = 'http://www.cnprog.com'
+APP_KEYWORDS = u'鎶鏈棶绛旂ぞ鍖猴紝涓浗绋嬪簭鍛橈紝缂栫▼鎶鏈ぞ鍖猴紝绋嬪簭鍛樼ぞ鍖猴紝绋嬪簭鍛樿鍧涳紝绋嬪簭鍛榳iki锛岀▼搴忓憳鍗氬'
+APP_DESCRIPTION = u'涓浗绋嬪簭鍛樼殑缂栫▼鎶鏈棶绛旂ぞ鍖恒傛垜浠仛涓撲笟鐨勩佸彲鍗忎綔缂栬緫鐨勬妧鏈棶绛旂ぞ鍖恒'
+APP_INTRO = u' <p>CNProg鏄竴涓<strong>闈㈠悜绋嬪簭鍛</strong>鐨勫彲鍗忎綔缂栬緫鐨<strong>寮鏀炬簮浠g爜闂瓟绀惧尯</strong>銆</p><p> 鎮ㄥ彲浠ュ湪杩欓噷鎻愰棶鍚勭被<strong>绋嬪簭鎶鏈棶棰</strong> - 闂涓嶅垎璇█鍜屽钩鍙般 鍚屾椂涔熷笇鏈涙偍瀵瑰姏鎵鑳藉強鐨勯棶棰橈紝缁欎簣鎮ㄧ殑瀹濊吹绛旀銆</p>'
ADMIN_MEDIA_PREFIX = '/admin/media/'
-
-# Make this unique, and don't share it with anybody.
-SECRET_KEY = '$oo^&_m&qwbib=ffljk_4m_n*zn-d=g#s0he5fx9xonnym#8p6yigm'
-
+SECRET_KEY = '$oo^&_m&qwbib=(_4m_n*zn-d=g#s0he5fx9xonnym#8p6yigm'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
@@ -105,12 +55,15 @@ MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.transaction.TransactionMiddleware',
- 'debug_toolbar.middleware.DebugToolbarMiddleware',
+ #'django.middleware.sqlprint.SqlPrintingMiddleware',
+ 'middleware.pagesize.QuestionsPageSizeMiddleware',
+ #'debug_toolbar.middleware.DebugToolbarMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.request',
'django.core.context_processors.auth',
+ 'context.application_settings'
)
ROOT_URLCONF = 'urls'
@@ -119,6 +72,7 @@ TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)
+#UPLOAD SETTINGS
FILE_UPLOAD_TEMP_DIR = os.path.join(os.path.dirname(__file__), 'tmp').replace('\\','/')
FILE_UPLOAD_HANDLERS = ("django.core.files.uploadhandler.MemoryFileUploadHandler",
"django.core.files.uploadhandler.TemporaryFileUploadHandler",)
@@ -139,6 +93,7 @@ INSTALLED_APPS = (
'django_authopenid',
'debug_toolbar' ,
)
-#local configs
-from settings_local import *
-
+
+# User settings
+from settings_local import *
+
diff --git a/settings_local.py.dist b/settings_local.py.dist
new file mode 100644
index 00000000..2c8f939d
--- /dev/null
+++ b/settings_local.py.dist
@@ -0,0 +1,25 @@
+SITE_SRC_ROOT = '/Users/sailing/Development/cnprog_beta2'
+
+#for logging
+import logging
+LOG_FILENAME = '/Users/sailing/Development/cnprog_beta2/django.lanai.log'
+logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG,)
+
+
+#Database configuration
+DATABASE_ENGINE = 'mysql'
+DATABASE_HOST = ''
+DATABASE_PORT = ''
+DATABASE_NAME = 'cnprog' # Or path to database file if using sqlite3.
+DATABASE_USER = 'root' # Not used with sqlite3.
+DATABASE_PASSWORD = '' # Not used with sqlite3.
+
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = '/Users/sailing/Development/cnprog_beta2/templates/upfiles/'
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = 'http://127.0.0.1:8000/upfiles/'
diff --git a/templates/base.html b/templates/base.html
index dca312e3..0852f7de 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -48,6 +48,7 @@
notify.show();
});
</script>
+
{% endif %}
{% endwith %}
@@ -88,4 +89,3 @@
{% endblock %}
</body>
</html>
-<!-- end template base.html -->
diff --git a/templates/base_content.html b/templates/base_content.html
index 98a09150..39627a0e 100644
--- a/templates/base_content.html
+++ b/templates/base_content.html
@@ -1,9 +1,8 @@
+锘縶% load i18n %}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<!-- template base_content.html -->
-{% load i18n %}
<html>
<head>
- <title>{% block title %}{% endblock %} - {% trans "site title" %} - {% trans "site slogan" %}</title>
+ <title>{% block title %}{% endblock %} - {{ APP_TITLE }}</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="verify-v1" content="55uGNnQVJW8p1bbXeF/Xbh9I7nZBM/wLhRz6N/I1kkA=" />
<link rel="shortcut icon" href="/content/images/favicon.ico" >
@@ -83,4 +82,3 @@
{% endblock %}
</body>
</html>
-<!-- end template base_content.html -->
diff --git a/templates/content/js/com.cnprog.post.js b/templates/content/js/com.cnprog.post.js
index bd4b00fd..e3101ea7 100644
--- a/templates/content/js/com.cnprog.post.js
+++ b/templates/content/js/com.cnprog.post.js
@@ -613,4 +613,4 @@ var commentsFactory = {'question' : questionComments, 'answer' : answerComments}
Prettify
http://www.apache.org/licenses/LICENSE-2.0
*/
-var PR_SHOULD_USE_CONTINUATION = true; var PR_TAB_WIDTH = 8; var PR_normalizedHtml; var PR; var prettyPrintOne; var prettyPrint; function _pr_isIE6() { var isIE6 = navigator && navigator.userAgent && /\bMSIE 6\./.test(navigator.userAgent); _pr_isIE6 = function() { return isIE6; }; return isIE6; } (function() { function wordSet(words) { words = words.split(/ /g); var set = {}; for (var i = words.length; --i >= 0; ) { var w = words[i]; if (w) { set[w] = null; } } return set; } var FLOW_CONTROL_KEYWORDS = "break continue do else for if return while "; var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " + "double enum extern float goto int long register short signed sizeof " + "static struct switch typedef union unsigned void volatile "; var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " + "new operator private protected public this throw true try "; var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " + "concept concept_map const_cast constexpr decltype " + "dynamic_cast explicit export friend inline late_check " + "mutable namespace nullptr reinterpret_cast static_assert static_cast " + "template typeid typename typeof using virtual wchar_t where "; var JAVA_KEYWORDS = COMMON_KEYWORDS + "boolean byte extends final finally implements import instanceof null " + "native package strictfp super synchronized throws transient "; var CSHARP_KEYWORDS = JAVA_KEYWORDS + "as base by checked decimal delegate descending event " + "fixed foreach from group implicit in interface internal into is lock " + "object out override orderby params readonly ref sbyte sealed " + "stackalloc string select uint ulong unchecked unsafe ushort var "; var JSCRIPT_KEYWORDS = COMMON_KEYWORDS + "debugger eval export function get null set undefined var with " + "Infinity NaN "; var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " + "goto if import last local my next no our print package redo require " + "sub undef unless until use wantarray while BEGIN END "; var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " + "elif except exec finally from global import in is lambda " + "nonlocal not or pass print raise try with yield " + "False True None "; var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" + " defined elsif end ensure false in module next nil not or redo rescue " + "retry self super then true undef unless until when yield BEGIN END "; var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " + "function in local set then until "; var ALL_KEYWORDS = (CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS + PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS); var PR_STRING = 'str'; var PR_KEYWORD = 'kwd'; var PR_COMMENT = 'com'; var PR_TYPE = 'typ'; var PR_LITERAL = 'lit'; var PR_PUNCTUATION = 'pun'; var PR_PLAIN = 'pln'; var PR_TAG = 'tag'; var PR_DECLARATION = 'dec'; var PR_SOURCE = 'src'; var PR_ATTRIB_NAME = 'atn'; var PR_ATTRIB_VALUE = 'atv'; var PR_NOCODE = 'nocode'; function isWordChar(ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } function spliceArrayInto(inserted, container, containerPosition, countReplaced) { inserted.unshift(containerPosition, countReplaced || 0); try { container.splice.apply(container, inserted); } finally { inserted.splice(0, 2); } } var REGEXP_PRECEDER_PATTERN = function() { var preceders = ["!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=", "&=", "(", "*", "*=", "+=", ",", "-=", "->", "/", "/=", ":", "::", ";", "<", "<<", "<<=", "<=", "=", "==", "===", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[", "^", "^=", "^^", "^^=", "{", "|", "|=", "||", "||=", "~", "break", "case", "continue", "delete", "do", "else", "finally", "instanceof", "return", "throw", "try", "typeof"]; var pattern = '(?:' + '(?:(?:^|[^0-9.])\\.{1,3})|' + '(?:(?:^|[^\\+])\\+)|' + '(?:(?:^|[^\\-])-)'; for (var i = 0; i < preceders.length; ++i) { var preceder = preceders[i]; if (isWordChar(preceder.charAt(0))) { pattern += '|\\b' + preceder; } else { pattern += '|' + preceder.replace(/([^=<>:&])/g, '\\$1'); } } pattern += '|^)\\s*$'; return new RegExp(pattern); } (); var pr_amp = /&/g; var pr_lt = /</g; var pr_gt = />/g; var pr_quot = /\"/g; function attribToHtml(str) { return str.replace(pr_amp, '&amp;').replace(pr_lt, '&lt;').replace(pr_gt, '&gt;').replace(pr_quot, '&quot;'); } function textToHtml(str) { return str.replace(pr_amp, '&amp;').replace(pr_lt, '&lt;').replace(pr_gt, '&gt;'); } var pr_ltEnt = /&lt;/g; var pr_gtEnt = /&gt;/g; var pr_aposEnt = /&apos;/g; var pr_quotEnt = /&quot;/g; var pr_ampEnt = /&amp;/g; var pr_nbspEnt = /&nbsp;/g; function htmlToText(html) { var pos = html.indexOf('&'); if (pos < 0) { return html; } for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0; ) { var end = html.indexOf(';', pos); if (end >= 0) { var num = html.substring(pos + 3, end); var radix = 10; if (num && num.charAt(0) === 'x') { num = num.substring(1); radix = 16; } var codePoint = parseInt(num, radix); if (!isNaN(codePoint)) { html = (html.substring(0, pos) + String.fromCharCode(codePoint) + html.substring(end + 1)); } } } return html.replace(pr_ltEnt, '<').replace(pr_gtEnt, '>').replace(pr_aposEnt, "'").replace(pr_quotEnt, '"').replace(pr_ampEnt, '&').replace(pr_nbspEnt, ' '); } function isRawContent(node) { return 'XMP' === node.tagName; } function normalizedHtml(node, out) { switch (node.nodeType) { case 1: var name = node.tagName.toLowerCase(); out.push('<', name); for (var i = 0; i < node.attributes.length; ++i) { var attr = node.attributes[i]; if (!attr.specified) { continue; } out.push(' '); normalizedHtml(attr, out); } out.push('>'); for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } if (node.firstChild || !/^(?:br|link|img)$/.test(name)) { out.push('<\/', name, '>'); } break; case 2: out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"'); break; case 3: case 4: out.push(textToHtml(node.nodeValue)); break; } } var PR_innerHtmlWorks = null; function getInnerHtml(node) { if (null === PR_innerHtmlWorks) { var testNode = document.createElement('PRE'); testNode.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />')); PR_innerHtmlWorks = !/</.test(testNode.innerHTML); } if (PR_innerHtmlWorks) { var content = node.innerHTML; if (isRawContent(node)) { content = textToHtml(content); } return content; } var out = []; for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } return out.join(''); } function makeTabExpander(tabWidth) { var SPACES = ' '; var charInLine = 0; return function(plainText) { var out = null; var pos = 0; for (var i = 0, n = plainText.length; i < n; ++i) { var ch = plainText.charAt(i); switch (ch) { case '\t': if (!out) { out = []; } out.push(plainText.substring(pos, i)); var nSpaces = tabWidth - (charInLine % tabWidth); charInLine += nSpaces; for (; nSpaces >= 0; nSpaces -= SPACES.length) { out.push(SPACES.substring(0, nSpaces)); } pos = i + 1; break; case '\n': charInLine = 0; break; default: ++charInLine; } } if (!out) { return plainText; } out.push(plainText.substring(pos)); return out.join(''); }; } var pr_chunkPattern = /(?:[^<]+|<!--[\s\S]*?-->|<!\[CDATA\[([\s\S]*?)\]\]>|<\/?[a-zA-Z][^>]*>|<)/g; var pr_commentPrefix = /^<!--/; var pr_cdataPrefix = /^<\[CDATA\[/; var pr_brPrefix = /^<br\b/i; var pr_tagNameRe = /^<(\/?)([a-zA-Z]+)/; function extractTags(s) { var matches = s.match(pr_chunkPattern); var sourceBuf = []; var sourceBufLen = 0; var extractedTags = []; if (matches) { for (var i = 0, n = matches.length; i < n; ++i) { var match = matches[i]; if (match.length > 1 && match.charAt(0) === '<') { if (pr_commentPrefix.test(match)) { continue; } if (pr_cdataPrefix.test(match)) { sourceBuf.push(match.substring(9, match.length - 3)); sourceBufLen += match.length - 12; } else if (pr_brPrefix.test(match)) { sourceBuf.push('\n'); ++sourceBufLen; } else { if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) { var name = match.match(pr_tagNameRe)[2]; var depth = 1; end_tag_loop: for (var j = i + 1; j < n; ++j) { var name2 = matches[j].match(pr_tagNameRe); if (name2 && name2[2] === name) { if (name2[1] === '/') { if (--depth === 0) { break end_tag_loop; } } else { ++depth; } } } if (j < n) { extractedTags.push(sourceBufLen, matches.slice(i, j + 1).join('')); i = j; } else { extractedTags.push(sourceBufLen, match); } } else { extractedTags.push(sourceBufLen, match); } } } else { var literalText = htmlToText(match); sourceBuf.push(literalText); sourceBufLen += literalText.length; } } } return { source: sourceBuf.join(''), tags: extractedTags }; } function isNoCodeTag(tag) { return !!tag.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g, ' $1="$2$3$4"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/); } function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) { var shortcuts = {}; (function() { var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns); for (var i = allPatterns.length; --i >= 0; ) { var patternParts = allPatterns[i]; var shortcutChars = patternParts[3]; if (shortcutChars) { for (var c = shortcutChars.length; --c >= 0; ) { shortcuts[shortcutChars.charAt(c)] = patternParts; } } } })(); var nPatterns = fallthroughStylePatterns.length; var notWs = /\S/; return function(sourceCode, opt_basePos) { opt_basePos = opt_basePos || 0; var decorations = [opt_basePos, PR_PLAIN]; var lastToken = ''; var pos = 0; var tail = sourceCode; while (tail.length) { var style; var token = null; var match; var patternParts = shortcuts[tail.charAt(0)]; if (patternParts) { match = tail.match(patternParts[1]); token = match[0]; style = patternParts[0]; } else { for (var i = 0; i < nPatterns; ++i) { patternParts = fallthroughStylePatterns[i]; var contextPattern = patternParts[2]; if (contextPattern && !contextPattern.test(lastToken)) { continue; } match = tail.match(patternParts[1]); if (match) { token = match[0]; style = patternParts[0]; break; } } if (!token) { style = PR_PLAIN; token = tail.substring(0, 1); } } decorations.push(opt_basePos + pos, style); pos += token.length; tail = tail.substring(token.length); if (style !== PR_COMMENT && notWs.test(token)) { lastToken = token; } } return decorations; }; } var PR_MARKUP_LEXER = createSimpleLexer([], [[PR_PLAIN, /^[^<]+/, null], [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/, null], [PR_COMMENT, /^<!--[\s\S]*?(?:-->|$)/, null], [PR_SOURCE, /^<\?[\s\S]*?(?:\?>|$)/, null], [PR_SOURCE, /^<%[\s\S]*?(?:%>|$)/, null], [PR_SOURCE, /^<(script|style|xmp)\b[^>]*>[\s\S]*?<\/\1\b[^>]*>/i, null], [PR_TAG, /^<\/?\w[^<>]*>/, null]]); var PR_SOURCE_CHUNK_PARTS = /^(<[^>]*>)([\s\S]*)(<\/[^>]*>)$/; function tokenizeMarkup(source) { var decorations = PR_MARKUP_LEXER(source); for (var i = 0; i < decorations.length; i += 2) { if (decorations[i + 1] === PR_SOURCE) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var sourceChunk = source.substring(start, end); var match = sourceChunk.match(PR_SOURCE_CHUNK_PARTS); if (match) { decorations.splice(i, 2, start, PR_TAG, start + match[1].length, PR_SOURCE, start + match[1].length + (match[2] || '').length, PR_TAG); } } } return decorations; } var PR_TAG_LEXER = createSimpleLexer([[PR_ATTRIB_VALUE, /^\'[^\']*(?:\'|$)/, null, "'"], [PR_ATTRIB_VALUE, /^\"[^\"]*(?:\"|$)/, null, '"'], [PR_PUNCTUATION, /^[<>\/=]+/, null, '<>/=']], [[PR_TAG, /^[\w:\-]+/, /^</], [PR_ATTRIB_VALUE, /^[\w\-]+/, /^=/], [PR_ATTRIB_NAME, /^[\w:\-]+/, null], [PR_PLAIN, /^\s+/, null, ' \t\r\n']]); function splitTagAttributes(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_TAG) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var chunk = source.substring(start, end); var subDecorations = PR_TAG_LEXER(chunk, start); spliceArrayInto(subDecorations, decorations, i, 2); i += subDecorations.length - 2; } } return decorations; } function sourceDecorator(options) { var shortcutStylePatterns = [], fallthroughStylePatterns = []; if (options.tripleQuotedStrings) { shortcutStylePatterns.push([PR_STRING, /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/, null, '\'"']); } else if (options.multiLineStrings) { shortcutStylePatterns.push([PR_STRING, /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/, null, '\'"`']); } else { shortcutStylePatterns.push([PR_STRING, /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/, null, '"\'']); } fallthroughStylePatterns.push([PR_PLAIN, /^(?:[^\'\"\`\/\#]+)/, null, ' \r\n']); if (options.hashComments) { shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']); } if (options.cStyleComments) { fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]); fallthroughStylePatterns.push([PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]); } if (options.regexLiterals) { var REGEX_LITERAL = ('^/(?=[^/*])' + '(?:[^/\\x5B\\x5C]' + '|\\x5C[\\s\\S]' + '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+' + '(?:/|$)'); fallthroughStylePatterns.push([PR_STRING, new RegExp(REGEX_LITERAL), REGEXP_PRECEDER_PATTERN]); } var keywords = wordSet(options.keywords); options = null; var splitStringAndCommentTokens = createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns); var styleLiteralIdentifierPuncRecognizer = createSimpleLexer([], [[PR_PLAIN, /^\s+/, null, ' \r\n'], [PR_PLAIN, /^[a-z_$@][a-z_$@0-9]*/i, null], [PR_LITERAL, /^0x[a-f0-9]+[a-z]/i, null], [PR_LITERAL, /^(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?[a-z]*/i, null, '123456789'], [PR_PUNCTUATION, /^[^\s\w\.$@]+/, null]]); function splitNonStringNonCommentTokens(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_PLAIN) { var start, end, chunk, subDecs; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; chunk = source.substring(start, end); subDecs = styleLiteralIdentifierPuncRecognizer(chunk, start); for (var j = 0, m = subDecs.length; j < m; j += 2) { var subStyle = subDecs[j + 1]; if (subStyle === PR_PLAIN) { var subStart = subDecs[j]; var subEnd = j + 2 < m ? subDecs[j + 2] : chunk.length; var token = source.substring(subStart, subEnd); if (token === '.') { subDecs[j + 1] = PR_PUNCTUATION; } else if (token in keywords) { subDecs[j + 1] = PR_KEYWORD; } else if (/^@?[A-Z][A-Z$]*[a-z][A-Za-z$]*$/.test(token)) { subDecs[j + 1] = token.charAt(0) === '@' ? PR_LITERAL : PR_TYPE; } } } spliceArrayInto(subDecs, decorations, i, 2); i += subDecs.length - 2; } } return decorations; } return function(sourceCode) { var decorations = splitStringAndCommentTokens(sourceCode); decorations = splitNonStringNonCommentTokens(sourceCode, decorations); return decorations; }; } var decorateSource = sourceDecorator({ keywords: ALL_KEYWORDS, hashComments: true, cStyleComments: true, multiLineStrings: true, regexLiterals: true }); function splitSourceNodes(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_SOURCE) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var subDecorations = decorateSource(source.substring(start, end)); for (var j = 0, m = subDecorations.length; j < m; j += 2) { subDecorations[j] += start; } spliceArrayInto(subDecorations, decorations, i, 2); i += subDecorations.length - 2; } } return decorations; } function splitSourceAttributes(source, decorations) { var nextValueIsSource = false; for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; var start, end; if (style === PR_ATTRIB_NAME) { start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; nextValueIsSource = /^on|^style$/i.test(source.substring(start, end)); } else if (style === PR_ATTRIB_VALUE) { if (nextValueIsSource) { start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var attribValue = source.substring(start, end); var attribLen = attribValue.length; var quoted = (attribLen >= 2 && /^[\"\']/.test(attribValue) && attribValue.charAt(0) === attribValue.charAt(attribLen - 1)); var attribSource; var attribSourceStart; var attribSourceEnd; if (quoted) { attribSourceStart = start + 1; attribSourceEnd = end - 1; attribSource = attribValue; } else { attribSourceStart = start + 1; attribSourceEnd = end - 1; attribSource = attribValue.substring(1, attribValue.length - 1); } var attribSourceDecorations = decorateSource(attribSource); for (var j = 0, m = attribSourceDecorations.length; j < m; j += 2) { attribSourceDecorations[j] += attribSourceStart; } if (quoted) { attribSourceDecorations.push(attribSourceEnd, PR_ATTRIB_VALUE); spliceArrayInto(attribSourceDecorations, decorations, i + 2, 0); } else { spliceArrayInto(attribSourceDecorations, decorations, i, 2); } } nextValueIsSource = false; } } return decorations; } function decorateMarkup(sourceCode) { var decorations = tokenizeMarkup(sourceCode); decorations = splitTagAttributes(sourceCode, decorations); decorations = splitSourceNodes(sourceCode, decorations); decorations = splitSourceAttributes(sourceCode, decorations); return decorations; } function recombineTagsAndDecorations(sourceText, extractedTags, decorations) { var html = []; var outputIdx = 0; var openDecoration = null; var currentDecoration = null; var tagPos = 0; var decPos = 0; var tabExpander = makeTabExpander(PR_TAB_WIDTH); var adjacentSpaceRe = /([\r\n ]) /g; var startOrSpaceRe = /(^| ) /gm; var newlineRe = /\r\n?|\n/g; var trailingSpaceRe = /[ \r\n]$/; var lastWasSpace = true; function emitTextUpTo(sourceIdx) { if (sourceIdx > outputIdx) { if (openDecoration && openDecoration !== currentDecoration) { html.push('</span>'); openDecoration = null; } if (!openDecoration && currentDecoration) { openDecoration = currentDecoration; html.push('<span class="', openDecoration, '">'); } var htmlChunk = textToHtml(tabExpander(sourceText.substring(outputIdx, sourceIdx))).replace(lastWasSpace ? startOrSpaceRe : adjacentSpaceRe, '$1&nbsp;'); lastWasSpace = trailingSpaceRe.test(htmlChunk); html.push(htmlChunk.replace(newlineRe, '<br />')); outputIdx = sourceIdx; } } while (true) { var outputTag; if (tagPos < extractedTags.length) { if (decPos < decorations.length) { outputTag = extractedTags[tagPos] <= decorations[decPos]; } else { outputTag = true; } } else { outputTag = false; } if (outputTag) { emitTextUpTo(extractedTags[tagPos]); if (openDecoration) { html.push('</span>'); openDecoration = null; } html.push(extractedTags[tagPos + 1]); tagPos += 2; } else if (decPos < decorations.length) { emitTextUpTo(decorations[decPos]); currentDecoration = decorations[decPos + 1]; decPos += 2; } else { break; } } emitTextUpTo(sourceText.length); if (openDecoration) { html.push('</span>'); } return html.join(''); } var langHandlerRegistry = {}; function registerLangHandler(handler, fileExtensions) { for (var i = fileExtensions.length; --i >= 0; ) { var ext = fileExtensions[i]; if (!langHandlerRegistry.hasOwnProperty(ext)) { langHandlerRegistry[ext] = handler; } else if ('console' in window) { console.log('cannot override language handler %s', ext); } } } registerLangHandler(decorateSource, ['default-code']); registerLangHandler(decorateMarkup, ['default-markup', 'html', 'htm', 'xhtml', 'xml', 'xsl']); registerLangHandler(sourceDecorator({ keywords: CPP_KEYWORDS, hashComments: true, cStyleComments: true }), ['c', 'cc', 'cpp', 'cs', 'cxx', 'cyc']); registerLangHandler(sourceDecorator({ keywords: JAVA_KEYWORDS, cStyleComments: true }), ['java']); registerLangHandler(sourceDecorator({ keywords: SH_KEYWORDS, hashComments: true, multiLineStrings: true }), ['bsh', 'csh', 'sh']); registerLangHandler(sourceDecorator({ keywords: PYTHON_KEYWORDS, hashComments: true, multiLineStrings: true, tripleQuotedStrings: true }), ['cv', 'py']); registerLangHandler(sourceDecorator({ keywords: PERL_KEYWORDS, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['perl', 'pl', 'pm']); registerLangHandler(sourceDecorator({ keywords: RUBY_KEYWORDS, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['rb']); registerLangHandler(sourceDecorator({ keywords: JSCRIPT_KEYWORDS, cStyleComments: true, regexLiterals: true }), ['js']); function prettyPrintOne(sourceCodeHtml, opt_langExtension) { try { var sourceAndExtractedTags = extractTags(sourceCodeHtml); var source = sourceAndExtractedTags.source; var extractedTags = sourceAndExtractedTags.tags; if (!langHandlerRegistry.hasOwnProperty(opt_langExtension)) { opt_langExtension = /^\s*</.test(source) ? 'default-markup' : 'default-code'; } var decorations = langHandlerRegistry[opt_langExtension].call({}, source); return recombineTagsAndDecorations(source, extractedTags, decorations); } catch (e) { if ('console' in window) { console.log(e); console.trace(); } return sourceCodeHtml; } } function prettyPrint(opt_whenDone) { var isIE6 = _pr_isIE6(); var codeSegments = [document.getElementsByTagName('pre'), document.getElementsByTagName('code'), document.getElementsByTagName('xmp')]; var elements = []; for (var i = 0; i < codeSegments.length; ++i) { for (var j = 0; j < codeSegments[i].length; ++j) { elements.push(codeSegments[i][j]); } } codeSegments = null; var k = 0; function doWork() { var endTime = (PR_SHOULD_USE_CONTINUATION ? new Date().getTime() + 250 : Infinity); for (; k < elements.length && new Date().getTime() < endTime; k++) { var cs = elements[k]; if (cs.className && cs.className.indexOf('prettyprint') >= 0) { var langExtension = cs.className.match(/\blang-(\w+)\b/); if (langExtension) { langExtension = langExtension[1]; } var nested = false; for (var p = cs.parentNode; p; p = p.parentNode) { if ((p.tagName === 'pre' || p.tagName === 'code' || p.tagName === 'xmp') && p.className && p.className.indexOf('prettyprint') >= 0) { nested = true; break; } } if (!nested) { var content = getInnerHtml(cs); content = content.replace(/(?:\r\n?|\n)$/, ''); var newContent = prettyPrintOne(content, langExtension); if (!isRawContent(cs)) { cs.innerHTML = newContent; } else { var pre = document.createElement('PRE'); for (var i = 0; i < cs.attributes.length; ++i) { var a = cs.attributes[i]; if (a.specified) { var aname = a.name.toLowerCase(); if (aname === 'class') { pre.className = a.value; } else { pre.setAttribute(a.name, a.value); } } } pre.innerHTML = newContent; cs.parentNode.replaceChild(pre, cs); cs = pre; } if (isIE6 && cs.tagName === 'PRE') { var lineBreaks = cs.getElementsByTagName('br'); for (var j = lineBreaks.length; --j >= 0; ) { var lineBreak = lineBreaks[j]; lineBreak.parentNode.replaceChild(document.createTextNode('\r\n'), lineBreak); } } } } } if (k < elements.length) { setTimeout(doWork, 250); } else if (opt_whenDone) { opt_whenDone(); } } doWork(); } window['PR_normalizedHtml'] = normalizedHtml; window['prettyPrintOne'] = prettyPrintOne; window['prettyPrint'] = prettyPrint; window['PR'] = { 'createSimpleLexer': createSimpleLexer, 'registerLangHandler': registerLangHandler, 'sourceDecorator': sourceDecorator, 'PR_ATTRIB_NAME': PR_ATTRIB_NAME, 'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE, 'PR_COMMENT': PR_COMMENT, 'PR_DECLARATION': PR_DECLARATION, 'PR_KEYWORD': PR_KEYWORD, 'PR_LITERAL': PR_LITERAL, 'PR_NOCODE': PR_NOCODE, 'PR_PLAIN': PR_PLAIN, 'PR_PUNCTUATION': PR_PUNCTUATION, 'PR_SOURCE': PR_SOURCE, 'PR_STRING': PR_STRING, 'PR_TAG': PR_TAG, 'PR_TYPE': PR_TYPE }; })();
+var PR_SHOULD_USE_CONTINUATION = true; var PR_TAB_WIDTH = 8; var PR_normalizedHtml; var PR; var prettyPrintOne; var prettyPrint; function _pr_isIE6() { var isIE6 = navigator && navigator.userAgent && /\bMSIE 6\./.test(navigator.userAgent); _pr_isIE6 = function() { return isIE6; }; return isIE6; } (function() { function wordSet(words) { words = words.split(/ /g); var set = {}; for (var i = words.length; --i >= 0; ) { var w = words[i]; if (w) { set[w] = null; } } return set; } var FLOW_CONTROL_KEYWORDS = "break continue do else for if return while "; var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " + "double enum extern float goto int long register short signed sizeof " + "static struct switch typedef union unsigned void volatile "; var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " + "new operator private protected public this throw true try "; var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " + "concept concept_map const_cast constexpr decltype " + "dynamic_cast explicit export friend inline late_check " + "mutable namespace nullptr reinterpret_cast static_assert static_cast " + "template typeid typename typeof using virtual wchar_t where "; var JAVA_KEYWORDS = COMMON_KEYWORDS + "boolean byte extends final finally implements import instanceof null " + "native package strictfp super synchronized throws transient "; var CSHARP_KEYWORDS = JAVA_KEYWORDS + "as base by checked decimal delegate descending event " + "fixed foreach from group implicit in interface internal into is lock " + "object out override orderby params readonly ref sbyte sealed " + "stackalloc string select uint ulong unchecked unsafe ushort var "; var JSCRIPT_KEYWORDS = COMMON_KEYWORDS + "debugger eval export function get null set undefined var with " + "Infinity NaN "; var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " + "goto if import last local my next no our print package redo require " + "sub undef unless until use wantarray while BEGIN END "; var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " + "elif except exec finally from global import in is lambda " + "nonlocal not or pass print raise try with yield " + "False True None "; var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" + " defined elsif end ensure false in module next nil not or redo rescue " + "retry self super then true undef unless until when yield BEGIN END "; var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " + "function in local set then until "; var ALL_KEYWORDS = (CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS + PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS); var PR_STRING = 'str'; var PR_KEYWORD = 'kwd'; var PR_COMMENT = 'com'; var PR_TYPE = 'typ'; var PR_LITERAL = 'lit'; var PR_PUNCTUATION = 'pun'; var PR_PLAIN = 'pln'; var PR_TAG = 'tag'; var PR_DECLARATION = 'dec'; var PR_SOURCE = 'src'; var PR_ATTRIB_NAME = 'atn'; var PR_ATTRIB_VALUE = 'atv'; var PR_NOCODE = 'nocode'; function isWordChar(ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } function spliceArrayInto(inserted, container, containerPosition, countReplaced) { inserted.unshift(containerPosition, countReplaced || 0); try { container.splice.apply(container, inserted); } finally { inserted.splice(0, 2); } } var REGEXP_PRECEDER_PATTERN = function() { var preceders = ["!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=", "&=", "(", "*", "*=", "+=", ",", "-=", "->", "/", "/=", ":", "::", ";", "<", "<<", "<<=", "<=", "=", "==", "===", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[", "^", "^=", "^^", "^^=", "{", "|", "|=", "||", "||=", "~", "break", "case", "continue", "delete", "do", "else", "finally", "instanceof", "return", "throw", "try", "typeof"]; var pattern = '(?:' + '(?:(?:^|[^0-9.])\\.{1,3})|' + '(?:(?:^|[^\\+])\\+)|' + '(?:(?:^|[^\\-])-)'; for (var i = 0; i < preceders.length; ++i) { var preceder = preceders[i]; if (isWordChar(preceder.charAt(0))) { pattern += '|\\b' + preceder; } else { pattern += '|' + preceder.replace(/([^=<>:&])/g, '\\$1'); } } pattern += '|^)\\s*$'; return new RegExp(pattern); } (); var pr_amp = /&/g; var pr_lt = /</g; var pr_gt = />/g; var pr_quot = /\"/g; function attribToHtml(str) { return str.replace(pr_amp, '&amp;').replace(pr_lt, '&lt;').replace(pr_gt, '&gt;').replace(pr_quot, '&quot;'); } function textToHtml(str) { return str.replace(pr_amp, '&amp;').replace(pr_lt, '&lt;').replace(pr_gt, '&gt;'); } var pr_ltEnt = /&lt;/g; var pr_gtEnt = /&gt;/g; var pr_aposEnt = /&apos;/g; var pr_quotEnt = /&quot;/g; var pr_ampEnt = /&amp;/g; var pr_nbspEnt = /&nbsp;/g; function htmlToText(html) { var pos = html.indexOf('&'); if (pos < 0) { return html; } for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0; ) { var end = html.indexOf(';', pos); if (end >= 0) { var num = html.substring(pos + 3, end); var radix = 10; if (num && num.charAt(0) === 'x') { num = num.substring(1); radix = 16; } var codePoint = parseInt(num, radix); if (!isNaN(codePoint)) { html = (html.substring(0, pos) + String.fromCharCode(codePoint) + html.substring(end + 1)); } } } return html.replace(pr_ltEnt, '<').replace(pr_gtEnt, '>').replace(pr_aposEnt, "'").replace(pr_quotEnt, '"').replace(pr_ampEnt, '&').replace(pr_nbspEnt, ' '); } function isRawContent(node) { return 'XMP' === node.tagName; } function normalizedHtml(node, out) { switch (node.nodeType) { case 1: var name = node.tagName.toLowerCase(); out.push('<', name); for (var i = 0; i < node.attributes.length; ++i) { var attr = node.attributes[i]; if (!attr.specified) { continue; } out.push(' '); normalizedHtml(attr, out); } out.push('>'); for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } if (node.firstChild || !/^(?:br|link|img)$/.test(name)) { out.push('<\/', name, '>'); } break; case 2: out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"'); break; case 3: case 4: out.push(textToHtml(node.nodeValue)); break; } } var PR_innerHtmlWorks = null; function getInnerHtml(node) { if (null === PR_innerHtmlWorks) { var testNode = document.createElement('PRE'); testNode.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />')); PR_innerHtmlWorks = !/</.test(testNode.innerHTML); } if (PR_innerHtmlWorks) { var content = node.innerHTML; if (isRawContent(node)) { content = textToHtml(content); } return content; } var out = []; for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } return out.join(''); } function makeTabExpander(tabWidth) { var SPACES = ' '; var charInLine = 0; return function(plainText) { var out = null; var pos = 0; for (var i = 0, n = plainText.length; i < n; ++i) { var ch = plainText.charAt(i); switch (ch) { case '\t': if (!out) { out = []; } out.push(plainText.substring(pos, i)); var nSpaces = tabWidth - (charInLine % tabWidth); charInLine += nSpaces; for (; nSpaces >= 0; nSpaces -= SPACES.length) { out.push(SPACES.substring(0, nSpaces)); } pos = i + 1; break; case '\n': charInLine = 0; break; default: ++charInLine; } } if (!out) { return plainText; } out.push(plainText.substring(pos)); return out.join(''); }; } var pr_chunkPattern = /(?:[^<]+|<!--[\s\S]*?-->|<!\[CDATA\[([\s\S]*?)\]\]>|<\/?[a-zA-Z][^>]*>|<)/g; var pr_commentPrefix = /^<!--/; var pr_cdataPrefix = /^<\[CDATA\[/; var pr_brPrefix = /^<br\b/i; var pr_tagNameRe = /^<(\/?)([a-zA-Z]+)/; function extractTags(s) { var matches = s.match(pr_chunkPattern); var sourceBuf = []; var sourceBufLen = 0; var extractedTags = []; if (matches) { for (var i = 0, n = matches.length; i < n; ++i) { var match = matches[i]; if (match.length > 1 && match.charAt(0) === '<') { if (pr_commentPrefix.test(match)) { continue; } if (pr_cdataPrefix.test(match)) { sourceBuf.push(match.substring(9, match.length - 3)); sourceBufLen += match.length - 12; } else if (pr_brPrefix.test(match)) { sourceBuf.push('\n'); ++sourceBufLen; } else { if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) { var name = match.match(pr_tagNameRe)[2]; var depth = 1; end_tag_loop: for (var j = i + 1; j < n; ++j) { var name2 = matches[j].match(pr_tagNameRe); if (name2 && name2[2] === name) { if (name2[1] === '/') { if (--depth === 0) { break end_tag_loop; } } else { ++depth; } } } if (j < n) { extractedTags.push(sourceBufLen, matches.slice(i, j + 1).join('')); i = j; } else { extractedTags.push(sourceBufLen, match); } } else { extractedTags.push(sourceBufLen, match); } } } else { var literalText = htmlToText(match); sourceBuf.push(literalText); sourceBufLen += literalText.length; } } } return { source: sourceBuf.join(''), tags: extractedTags }; } function isNoCodeTag(tag) { return !!tag.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g, ' $1="$2$3$4"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/); } function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) { var shortcuts = {}; (function() { var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns); for (var i = allPatterns.length; --i >= 0; ) { var patternParts = allPatterns[i]; var shortcutChars = patternParts[3]; if (shortcutChars) { for (var c = shortcutChars.length; --c >= 0; ) { shortcuts[shortcutChars.charAt(c)] = patternParts; } } } })(); var nPatterns = fallthroughStylePatterns.length; var notWs = /\S/; return function(sourceCode, opt_basePos) { opt_basePos = opt_basePos || 0; var decorations = [opt_basePos, PR_PLAIN]; var lastToken = ''; var pos = 0; var tail = sourceCode; while (tail.length) { var style; var token = null; var match; var patternParts = shortcuts[tail.charAt(0)]; if (patternParts) { match = tail.match(patternParts[1]); token = match[0]; style = patternParts[0]; } else { for (var i = 0; i < nPatterns; ++i) { patternParts = fallthroughStylePatterns[i]; var contextPattern = patternParts[2]; if (contextPattern && !contextPattern.test(lastToken)) { continue; } match = tail.match(patternParts[1]); if (match) { token = match[0]; style = patternParts[0]; break; } } if (!token) { style = PR_PLAIN; token = tail.substring(0, 1); } } decorations.push(opt_basePos + pos, style); pos += token.length; tail = tail.substring(token.length); if (style !== PR_COMMENT && notWs.test(token)) { lastToken = token; } } return decorations; }; } var PR_MARKUP_LEXER = createSimpleLexer([], [[PR_PLAIN, /^[^<]+/, null], [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/, null], [PR_COMMENT, /^<!--[\s\S]*?(?:-->|$)/, null], [PR_SOURCE, /^<\?[\s\S]*?(?:\?>|$)/, null], [PR_SOURCE, /^<%[\s\S]*?(?:%>|$)/, null], [PR_SOURCE, /^<(script|style|xmp)\b[^>]*>[\s\S]*?<\/\1\b[^>]*>/i, null], [PR_TAG, /^<\/?\w[^<>]*>/, null]]); var PR_SOURCE_CHUNK_PARTS = /^(<[^>]*>)([\s\S]*)(<\/[^>]*>)$/; function tokenizeMarkup(source) { var decorations = PR_MARKUP_LEXER(source); for (var i = 0; i < decorations.length; i += 2) { if (decorations[i + 1] === PR_SOURCE) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var sourceChunk = source.substring(start, end); var match = sourceChunk.match(PR_SOURCE_CHUNK_PARTS); if (match) { decorations.splice(i, 2, start, PR_TAG, start + match[1].length, PR_SOURCE, start + match[1].length + (match[2] || '').length, PR_TAG); } } } return decorations; } var PR_TAG_LEXER = createSimpleLexer([[PR_ATTRIB_VALUE, /^\'[^\']*(?:\'|$)/, null, "'"], [PR_ATTRIB_VALUE, /^\"[^\"]*(?:\"|$)/, null, '"'], [PR_PUNCTUATION, /^[<>\/=]+/, null, '<>/=']], [[PR_TAG, /^[\w:\-]+/, /^</], [PR_ATTRIB_VALUE, /^[\w\-]+/, /^=/], [PR_ATTRIB_NAME, /^[\w:\-]+/, null], [PR_PLAIN, /^\s+/, null, ' \t\r\n']]); function splitTagAttributes(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_TAG) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var chunk = source.substring(start, end); var subDecorations = PR_TAG_LEXER(chunk, start); spliceArrayInto(subDecorations, decorations, i, 2); i += subDecorations.length - 2; } } return decorations; } function sourceDecorator(options) { var shortcutStylePatterns = [], fallthroughStylePatterns = []; if (options.tripleQuotedStrings) { shortcutStylePatterns.push([PR_STRING, /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/, null, '\'"']); } else if (options.multiLineStrings) { shortcutStylePatterns.push([PR_STRING, /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/, null, '\'"`']); } else { shortcutStylePatterns.push([PR_STRING, /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/, null, '"\'']); } fallthroughStylePatterns.push([PR_PLAIN, /^(?:[^\'\"\`\/\#]+)/, null, ' \r\n']); if (options.hashComments) { shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']); } if (options.cStyleComments) { fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]); fallthroughStylePatterns.push([PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]); } if (options.regexLiterals) { var REGEX_LITERAL = ('^/(?=[^/*])' + '(?:[^/\\x5B\\x5C]' + '|\\x5C[\\s\\S]' + '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+' + '(?:/|$)'); fallthroughStylePatterns.push([PR_STRING, new RegExp(REGEX_LITERAL), REGEXP_PRECEDER_PATTERN]); } var keywords = wordSet(options.keywords); options = null; var splitStringAndCommentTokens = createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns); var styleLiteralIdentifierPuncRecognizer = createSimpleLexer([], [[PR_PLAIN, /^\s+/, null, ' \r\n'], [PR_PLAIN, /^[a-z_$@][a-z_$@0-9]*/i, null], [PR_LITERAL, /^0x[a-f0-9]+[a-z]/i, null], [PR_LITERAL, /^(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?[a-z]*/i, null, '123456789'], [PR_PUNCTUATION, /^[^\s\w\.$@]+/, null]]); function splitNonStringNonCommentTokens(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_PLAIN) { var start, end, chunk, subDecs; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; chunk = source.substring(start, end); subDecs = styleLiteralIdentifierPuncRecognizer(chunk, start); for (var j = 0, m = subDecs.length; j < m; j += 2) { var subStyle = subDecs[j + 1]; if (subStyle === PR_PLAIN) { var subStart = subDecs[j]; var subEnd = j + 2 < m ? subDecs[j + 2] : chunk.length; var token = source.substring(subStart, subEnd); if (token === '.') { subDecs[j + 1] = PR_PUNCTUATION; } else if (token in keywords) { subDecs[j + 1] = PR_KEYWORD; } else if (/^@?[A-Z][A-Z$]*[a-z][A-Za-z$]*$/.test(token)) { subDecs[j + 1] = token.charAt(0) === '@' ? PR_LITERAL : PR_TYPE; } } } spliceArrayInto(subDecs, decorations, i, 2); i += subDecs.length - 2; } } return decorations; } return function(sourceCode) { var decorations = splitStringAndCommentTokens(sourceCode); decorations = splitNonStringNonCommentTokens(sourceCode, decorations); return decorations; }; } var decorateSource = sourceDecorator({ keywords: ALL_KEYWORDS, hashComments: true, cStyleComments: true, multiLineStrings: true, regexLiterals: true }); function splitSourceNodes(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_SOURCE) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var subDecorations = decorateSource(source.substring(start, end)); for (var j = 0, m = subDecorations.length; j < m; j += 2) { subDecorations[j] += start; } spliceArrayInto(subDecorations, decorations, i, 2); i += subDecorations.length - 2; } } return decorations; } function splitSourceAttributes(source, decorations) { var nextValueIsSource = false; for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; var start, end; if (style === PR_ATTRIB_NAME) { start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; nextValueIsSource = /^on|^style$/i.test(source.substring(start, end)); } else if (style === PR_ATTRIB_VALUE) { if (nextValueIsSource) { start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var attribValue = source.substring(start, end); var attribLen = attribValue.length; var quoted = (attribLen >= 2 && /^[\"\']/.test(attribValue) && attribValue.charAt(0) === attribValue.charAt(attribLen - 1)); var attribSource; var attribSourceStart; var attribSourceEnd; if (quoted) { attribSourceStart = start + 1; attribSourceEnd = end - 1; attribSource = attribValue; } else { attribSourceStart = start + 1; attribSourceEnd = end - 1; attribSource = attribValue.substring(1, attribValue.length - 1); } var attribSourceDecorations = decorateSource(attribSource); for (var j = 0, m = attribSourceDecorations.length; j < m; j += 2) { attribSourceDecorations[j] += attribSourceStart; } if (quoted) { attribSourceDecorations.push(attribSourceEnd, PR_ATTRIB_VALUE); spliceArrayInto(attribSourceDecorations, decorations, i + 2, 0); } else { spliceArrayInto(attribSourceDecorations, decorations, i, 2); } } nextValueIsSource = false; } } return decorations; } function decorateMarkup(sourceCode) { var decorations = tokenizeMarkup(sourceCode); decorations = splitTagAttributes(sourceCode, decorations); decorations = splitSourceNodes(sourceCode, decorations); decorations = splitSourceAttributes(sourceCode, decorations); return decorations; } function recombineTagsAndDecorations(sourceText, extractedTags, decorations) { var html = []; var outputIdx = 0; var openDecoration = null; var currentDecoration = null; var tagPos = 0; var decPos = 0; var tabExpander = makeTabExpander(PR_TAB_WIDTH); var adjacentSpaceRe = /([\r\n ]) /g; var startOrSpaceRe = /(^| ) /gm; var newlineRe = /\r\n?|\n/g; var trailingSpaceRe = /[ \r\n]$/; var lastWasSpace = true; function emitTextUpTo(sourceIdx) { if (sourceIdx > outputIdx) { if (openDecoration && openDecoration !== currentDecoration) { html.push('</span>'); openDecoration = null; } if (!openDecoration && currentDecoration) { openDecoration = currentDecoration; html.push('<span class="', openDecoration, '">'); } var htmlChunk = textToHtml(tabExpander(sourceText.substring(outputIdx, sourceIdx))).replace(lastWasSpace ? startOrSpaceRe : adjacentSpaceRe, '$1&nbsp;'); lastWasSpace = trailingSpaceRe.test(htmlChunk); html.push(htmlChunk.replace(newlineRe, '<br />')); outputIdx = sourceIdx; } } while (true) { var outputTag; if (tagPos < extractedTags.length) { if (decPos < decorations.length) { outputTag = extractedTags[tagPos] <= decorations[decPos]; } else { outputTag = true; } } else { outputTag = false; } if (outputTag) { emitTextUpTo(extractedTags[tagPos]); if (openDecoration) { html.push('</span>'); openDecoration = null; } html.push(extractedTags[tagPos + 1]); tagPos += 2; } else if (decPos < decorations.length) { emitTextUpTo(decorations[decPos]); currentDecoration = decorations[decPos + 1]; decPos += 2; } else { break; } } emitTextUpTo(sourceText.length); if (openDecoration) { html.push('</span>'); } return html.join(''); } var langHandlerRegistry = {}; function registerLangHandler(handler, fileExtensions) { for (var i = fileExtensions.length; --i >= 0; ) { var ext = fileExtensions[i]; if (!langHandlerRegistry.hasOwnProperty(ext)) { langHandlerRegistry[ext] = handler; } else if ('console' in window) { console.log('cannot override language handler %s', ext); } } } registerLangHandler(decorateSource, ['default-code']); registerLangHandler(decorateMarkup, ['default-markup', 'html', 'htm', 'xhtml', 'xml', 'xsl']); registerLangHandler(sourceDecorator({ keywords: CPP_KEYWORDS, hashComments: true, cStyleComments: true }), ['c', 'cc', 'cpp', 'cs', 'cxx', 'cyc']); registerLangHandler(sourceDecorator({ keywords: JAVA_KEYWORDS, cStyleComments: true }), ['java']); registerLangHandler(sourceDecorator({ keywords: SH_KEYWORDS, hashComments: true, multiLineStrings: true }), ['bsh', 'csh', 'sh']); registerLangHandler(sourceDecorator({ keywords: PYTHON_KEYWORDS, hashComments: true, multiLineStrings: true, tripleQuotedStrings: true }), ['cv', 'py']); registerLangHandler(sourceDecorator({ keywords: PERL_KEYWORDS, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['perl', 'pl', 'pm']); registerLangHandler(sourceDecorator({ keywords: RUBY_KEYWORDS, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['rb']); registerLangHandler(sourceDecorator({ keywords: JSCRIPT_KEYWORDS, cStyleComments: true, regexLiterals: true }), ['js']); function prettyPrintOne(sourceCodeHtml, opt_langExtension) { try { var sourceAndExtractedTags = extractTags(sourceCodeHtml); var source = sourceAndExtractedTags.source; var extractedTags = sourceAndExtractedTags.tags; if (!langHandlerRegistry.hasOwnProperty(opt_langExtension)) { opt_langExtension = /^\s*</.test(source) ? 'default-markup' : 'default-code'; } var decorations = langHandlerRegistry[opt_langExtension].call({}, source); return recombineTagsAndDecorations(source, extractedTags, decorations); } catch (e) { if ('console' in window) { console.log(e); console.trace(); } return sourceCodeHtml; } } function prettyPrint(opt_whenDone) { var isIE6 = _pr_isIE6(); var codeSegments = [document.getElementsByTagName('pre'), document.getElementsByTagName('code'), document.getElementsByTagName('xmp')]; var elements = []; for (var i = 0; i < codeSegments.length; ++i) { for (var j = 0; j < codeSegments[i].length; ++j) { elements.push(codeSegments[i][j]); } } codeSegments = null; var k = 0; function doWork() { var endTime = (PR_SHOULD_USE_CONTINUATION ? new Date().getTime() + 250 : Infinity); for (; k < elements.length && new Date().getTime() < endTime; k++) { var cs = elements[k]; if (cs.className && cs.className.indexOf('prettyprint') >= 0) { var langExtension = cs.className.match(/\blang-(\w+)\b/); if (langExtension) { langExtension = langExtension[1]; } var nested = false; for (var p = cs.parentNode; p; p = p.parentNode) { if ((p.tagName === 'pre' || p.tagName === 'code' || p.tagName === 'xmp') && p.className && p.className.indexOf('prettyprint') >= 0) { nested = true; break; } } if (!nested) { var content = getInnerHtml(cs); content = content.replace(/(?:\r\n?|\n)$/, ''); var newContent = prettyPrintOne(content, langExtension); if (!isRawContent(cs)) { cs.innerHTML = newContent; } else { var pre = document.createElement('PRE'); for (var i = 0; i < cs.attributes.length; ++i) { var a = cs.attributes[i]; if (a.specified) { var aname = a.name.toLowerCase(); if (aname === 'class') { pre.className = a.value; } else { pre.setAttribute(a.name, a.value); } } } pre.innerHTML = newContent; cs.parentNode.replaceChild(pre, cs); cs = pre; } if (isIE6 && cs.tagName === 'PRE') { var lineBreaks = cs.getElementsByTagName('br'); for (var j = lineBreaks.length; --j >= 0; ) { var lineBreak = lineBreaks[j]; lineBreak.parentNode.replaceChild(document.createTextNode('\r\n'), lineBreak); } } } } } if (k < elements.length) { setTimeout(doWork, 250); } else if (opt_whenDone) { opt_whenDone(); } } doWork(); } window['PR_normalizedHtml'] = normalizedHtml; window['prettyPrintOne'] = prettyPrintOne; window['prettyPrint'] = prettyPrint; window['PR'] = { 'createSimpleLexer': createSimpleLexer, 'registerLangHandler': registerLangHandler, 'sourceDecorator': sourceDecorator, 'PR_ATTRIB_NAME': PR_ATTRIB_NAME, 'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE, 'PR_COMMENT': PR_COMMENT, 'PR_DECLARATION': PR_DECLARATION, 'PR_KEYWORD': PR_KEYWORD, 'PR_LITERAL': PR_LITERAL, 'PR_NOCODE': PR_NOCODE, 'PR_PLAIN': PR_PLAIN, 'PR_PUNCTUATION': PR_PUNCTUATION, 'PR_SOURCE': PR_SOURCE, 'PR_STRING': PR_STRING, 'PR_TAG': PR_TAG, 'PR_TYPE': PR_TYPE }; })(); \ No newline at end of file
diff --git a/templates/content/js/com.cnprog.utils.js b/templates/content/js/com.cnprog.utils.js
index e271ed78..683b7a3f 100644
--- a/templates/content/js/com.cnprog.utils.js
+++ b/templates/content/js/com.cnprog.utils.js
@@ -119,4 +119,4 @@ var CPValidator = function(){
}();
//Search Engine Keyword Highlight with Javascript
//http://scott.yang.id.au/code/se-hilite/
-Hilite={elementid:"content",exact:true,max_nodes:1000,onload:true,style_name:"hilite",style_name_suffix:true,debug_referrer:""};Hilite.search_engines=[["local","q"],["cnprog\\.","q"],["google\\.","q"],["search\\.yahoo\\.","p"],["search\\.msn\\.","q"],["search\\.live\\.","query"],["search\\.aol\\.","userQuery"],["ask\\.com","q"],["altavista\\.","q"],["feedster\\.","q"],["search\\.lycos\\.","q"],["alltheweb\\.","q"],["technorati\\.com/search/([^\\?/]+)",1],["dogpile\\.com/info\\.dogpl/search/web/([^\\?/]+)",1,true]];Hilite.decodeReferrer=function(d){var g=null;var e=new RegExp("");for(var c=0;c<Hilite.search_engines.length;c++){var f=Hilite.search_engines[c];e.compile("^http://(www\\.)?"+f[0],"i");var b=d.match(e);if(b){var a;if(isNaN(f[1])){a=Hilite.decodeReferrerQS(d,f[1])}else{a=b[f[1]+1]}if(a){a=decodeURIComponent(a);if(f.length>2&&f[2]){a=decodeURIComponent(a)}a=a.replace(/\'|"/g,"");a=a.split(/[\s,\+\.]+/);return a}break}}return null};Hilite.decodeReferrerQS=function(f,d){var b=f.indexOf("?");var c;if(b>=0){var a=new String(f.substring(b+1));b=0;c=0;while((b>=0)&&((c=a.indexOf("=",b))>=0)){var e,g;e=a.substring(b,c);b=a.indexOf("&",c)+1;if(e==d){if(b<=0){return a.substring(c+1)}else{return a.substring(c+1,b-1)}}else{if(b<=0){return null}}}}return null};Hilite.hiliteElement=function(f,e){if(!e||f.childNodes.length==0){return}var c=new Array();for(var b=0;b<e.length;b++){e[b]=e[b].toLowerCase();if(Hilite.exact){c.push("\\b"+e[b]+"\\b")}else{c.push(e[b])}}c=new RegExp(c.join("|"),"i");var a={};for(var b=0;b<e.length;b++){if(Hilite.style_name_suffix){a[e[b]]=Hilite.style_name+(b+1)}else{a[e[b]]=Hilite.style_name}}var d=function(m){var j=c.exec(m.data);if(j){var n=j[0];var i="";var h=m.splitText(j.index);var g=h.splitText(n.length);var l=m.ownerDocument.createElement("SPAN");m.parentNode.replaceChild(l,h);l.className=a[n.toLowerCase()];l.appendChild(h);return l}else{return m}};Hilite.walkElements(f.childNodes[0],1,d)};Hilite.hilite=function(){var a=Hilite.debug_referrer?Hilite.debug_referrer:document.referrer;var b=null;a=Hilite.decodeReferrer(a);if(a&&((Hilite.elementid&&(b=document.getElementById(Hilite.elementid)))||(b=document.body))){Hilite.hiliteElement(b,a)}};Hilite.walkElements=function(d,f,e){var a=/^(script|style|textarea)/i;var c=0;while(d&&f>0){c++;if(c>=Hilite.max_nodes){var b=function(){Hilite.walkElements(d,f,e)};setTimeout(b,50);return}if(d.nodeType==1){if(!a.test(d.tagName)&&d.childNodes.length>0){d=d.childNodes[0];f++;continue}}else{if(d.nodeType==3){d=e(d)}}if(d.nextSibling){d=d.nextSibling}else{while(f>0){d=d.parentNode;f--;if(d.nextSibling){d=d.nextSibling;break}}}}};if(Hilite.onload){if(window.attachEvent){window.attachEvent("onload",Hilite.hilite)}else{if(window.addEventListener){window.addEventListener("load",Hilite.hilite,false)}else{var __onload=window.onload;window.onload=function(){Hilite.hilite();__onload()}}}};
+Hilite={elementid:"content",exact:true,max_nodes:1000,onload:true,style_name:"hilite",style_name_suffix:true,debug_referrer:""};Hilite.search_engines=[["local","q"],["cnprog\\.","q"],["google\\.","q"],["search\\.yahoo\\.","p"],["search\\.msn\\.","q"],["search\\.live\\.","query"],["search\\.aol\\.","userQuery"],["ask\\.com","q"],["altavista\\.","q"],["feedster\\.","q"],["search\\.lycos\\.","q"],["alltheweb\\.","q"],["technorati\\.com/search/([^\\?/]+)",1],["dogpile\\.com/info\\.dogpl/search/web/([^\\?/]+)",1,true]];Hilite.decodeReferrer=function(d){var g=null;var e=new RegExp("");for(var c=0;c<Hilite.search_engines.length;c++){var f=Hilite.search_engines[c];e.compile("^http://(www\\.)?"+f[0],"i");var b=d.match(e);if(b){var a;if(isNaN(f[1])){a=Hilite.decodeReferrerQS(d,f[1])}else{a=b[f[1]+1]}if(a){a=decodeURIComponent(a);if(f.length>2&&f[2]){a=decodeURIComponent(a)}a=a.replace(/\'|"/g,"");a=a.split(/[\s,\+\.]+/);return a}break}}return null};Hilite.decodeReferrerQS=function(f,d){var b=f.indexOf("?");var c;if(b>=0){var a=new String(f.substring(b+1));b=0;c=0;while((b>=0)&&((c=a.indexOf("=",b))>=0)){var e,g;e=a.substring(b,c);b=a.indexOf("&",c)+1;if(e==d){if(b<=0){return a.substring(c+1)}else{return a.substring(c+1,b-1)}}else{if(b<=0){return null}}}}return null};Hilite.hiliteElement=function(f,e){if(!e||f.childNodes.length==0){return}var c=new Array();for(var b=0;b<e.length;b++){e[b]=e[b].toLowerCase();if(Hilite.exact){c.push("\\b"+e[b]+"\\b")}else{c.push(e[b])}}c=new RegExp(c.join("|"),"i");var a={};for(var b=0;b<e.length;b++){if(Hilite.style_name_suffix){a[e[b]]=Hilite.style_name+(b+1)}else{a[e[b]]=Hilite.style_name}}var d=function(m){var j=c.exec(m.data);if(j){var n=j[0];var i="";var h=m.splitText(j.index);var g=h.splitText(n.length);var l=m.ownerDocument.createElement("SPAN");m.parentNode.replaceChild(l,h);l.className=a[n.toLowerCase()];l.appendChild(h);return l}else{return m}};Hilite.walkElements(f.childNodes[0],1,d)};Hilite.hilite=function(){var a=Hilite.debug_referrer?Hilite.debug_referrer:document.referrer;var b=null;a=Hilite.decodeReferrer(a);if(a&&((Hilite.elementid&&(b=document.getElementById(Hilite.elementid)))||(b=document.body))){Hilite.hiliteElement(b,a)}};Hilite.walkElements=function(d,f,e){var a=/^(script|style|textarea)/i;var c=0;while(d&&f>0){c++;if(c>=Hilite.max_nodes){var b=function(){Hilite.walkElements(d,f,e)};setTimeout(b,50);return}if(d.nodeType==1){if(!a.test(d.tagName)&&d.childNodes.length>0){d=d.childNodes[0];f++;continue}}else{if(d.nodeType==3){d=e(d)}}if(d.nextSibling){d=d.nextSibling}else{while(f>0){d=d.parentNode;f--;if(d.nextSibling){d=d.nextSibling;break}}}}};if(Hilite.onload){if(window.attachEvent){window.attachEvent("onload",Hilite.hilite)}else{if(window.addEventListener){window.addEventListener("load",Hilite.hilite,false)}else{var __onload=window.onload;window.onload=function(){Hilite.hilite();__onload()}}}}; \ No newline at end of file
diff --git a/templates/content/style/openid.css b/templates/content/style/openid.css
index 0d201df2..7a892840 100644
--- a/templates/content/style/openid.css
+++ b/templates/content/style/openid.css
@@ -42,4 +42,4 @@
}
.openid_selected {
border: 4px solid #DDD;
- }
+ } \ No newline at end of file
diff --git a/templates/pagesize.html b/templates/pagesize.html
index 5037f1f6..e5e17a24 100644
--- a/templates/pagesize.html
+++ b/templates/pagesize.html
@@ -1,9 +1,8 @@
-<!-- template pagesize.html -->
{% spaceless %}
{% load i18n %}
{% if is_paginated %}
<div class="paginator">
- <span class="text">{% trans "posts per page" %}</span>
+ <span class="text">{% trans "Size per page:" %}</span>
{% ifequal pagesize 10 %}
<span class="curr">10</span>
{% else %}
@@ -24,4 +23,3 @@
</div>
{% endif %}
{% endspaceless %}
-<!-- end template pagesize.html -->
diff --git a/templates/question_retag.html b/templates/question_retag.html
new file mode 100644
index 00000000..aebf93a5
--- /dev/null
+++ b/templates/question_retag.html
@@ -0,0 +1,109 @@
+{% extends "base.html" %}
+{% block title %}{% spaceless %}淇敼闂鏍囩{% endspaceless %}{% endblock %}
+{% block forejs %}
+ <script type='text/javascript' src='/content/js/com.cnprog.editor.js'></script>
+ <script type='text/javascript' src='/content/js/com.cnprog.post.js'></script>
+ <script type='text/javascript' src='/content/js/jquery.validate.pack.js'></script>
+ <script type="text/javascript">
+
+ $().ready(function(){
+ $("#nav_questions").attr('className',"on");
+ //Tags autocomplete action
+ var tags = {{ tags|safe }};
+ $("#id_tags").autocomplete(tags, {
+ minChars: 1,
+ matchContains: true,
+ max: 20,
+ multiple: true,
+ multipleSeparator: " ",
+ formatItem: function(row, i, max) {
+ return row.n + " ("+ row.c +")";
+ },
+ formatResult: function(row, i, max){
+ return row.n;
+ }
+
+ });
+
+ $("#fmretag").validate({
+ rules: {
+ tags: {
+ required: true,
+ maxength: 105
+ }
+ },
+ messages: {
+ tags: {
+ required: " 鏍囩涓嶈兘涓虹┖銆",
+ maxlength: " 鏈澶5涓爣绛撅紝姣忎釜鏍囩闀垮害灏忎簬20涓瓧绗︺"
+ }
+ }
+
+ });
+ lanai.highlightSyntax();
+
+ });
+ </script>
+{% endblock %}
+
+{% block content %}
+<div id="main-bar" class="headNormal">
+ 淇敼鏍囩 [<a href="{{ question.get_absolute_url }}">杩斿洖</a>]
+</div>
+<div id="main-body" class="ask-body">
+ <div id="askform">
+ <form id="fmretag" action="{% url edit_question question.id %}" method="post" >
+ <h3>
+ {{ question.get_question_title }}
+ </h3>
+ <div id="description" class="edit-content-html">
+ {{ question.html|safe }}
+ </div>
+
+
+ <div class="form-item">
+ <strong>{{ form.tags.label_tag }}:</strong> <span class="form-error"></span><br>
+ {{ form.tags }} {{ form.tags.errors }}
+ <div class="title-desc">
+ {{ form.tags.help_text }}
+ </div>
+ </div>
+ <br>
+
+ <div class="error" ></div>
+ <input type="submit" value="鐜板湪淇敼" class="submit" />
+ <input type="button" value="鍙栨秷" class="submit" onclick="history.back(-1);" />
+ <br>
+ <br>
+ </form>
+ </div>
+</div>
+{% endblock %}
+
+{% block sidebar %}
+<div class="boxC">
+ <p class="subtitle">涓轰粈涔堟垜鍙兘淇敼闂鏍囩锛</p>
+ <ul class="list-item">
+
+ <li>
+ CNProg鐢ㄦ爣绛炬潵鍒嗙被绯荤粺鐨勪俊鎭
+
+ </li>
+ <li>
+ 淇敼瀹屾暣闂闇瑕佺敤鎴风殑绉垎杈惧埌涓瀹氭潯浠讹紙姣斿锛氱Н鍒 >= 3000鍒嗭紝鑷繁鍙戝竷鐨勯棶棰橀櫎澶栵級锛岃岀敤鎴风Н鍒嗚揪鍒版瘮杈冧綆鐨勬椂鍊欙紝灏卞彲浠ヤ慨鏀归棶棰樼殑鏍囩锛堟瘮濡傦細绉垎 >= 500, 杩欓噷鎸囨墍鏈夐棶棰樼殑鏍囩锛夈
+
+ </li>
+ <li>
+ 淇敼鏍囩鐨勭敤鎴峰皢鎺堜簣鐗规畩鐨勭ぞ鍖哄鐗
+
+ </li>
+ </ul>
+ <a href="{% url faq %}" style="float:right;position:relative">faq 禄</a>
+ <br>
+</div>
+
+{% endblock %}
+
+{% block endjs %}
+{% endblock %}
+
diff --git a/templates/user_preferences.html b/templates/user_preferences.html
index 246a834e..3a760a25 100644
--- a/templates/user_preferences.html
+++ b/templates/user_preferences.html
@@ -1,11 +1,20 @@
-<!-- user_preferences.html -->
{% extends "user.html" %}
{% load extra_tags %}
{% load humanize %}
{% block usercontent %}
<div style="padding:5px;">
- <h1>Surprise will be here soon ;-)</h1>
+ <fieldset>
+ <legend><b>鍚屾Twitter娑堟伅</b></legend>
+ <form>
+ <label for="name">璐﹀彿:</label>
+ <input id="name" /><br>
+ <label for="password">瀵嗙爜:</label>
+ <input id="password" type="password"/><br>
+ <input id="cbMessage" type="checkbox" />鍙戝竷鎴戠殑鎻愰棶鍒版垜鐨凾witter<br>
+ <input id="cbReply" type="checkbox" />鍙戝竷鎴戠殑鍥炵瓟鍒版垜鐨凾witter<br>
+ <input type="submit" value="淇濆瓨" />
+ </form>
+ </fieldset>
</div>
{% endblock %}
-<!-- end user_preferences.html -->
diff --git a/urls.py b/urls.py
index 89b5127c..a219fd44 100644
--- a/urls.py
+++ b/urls.py
@@ -60,4 +60,5 @@ urlpatterns = patterns('',
url(r'^books/ask/(?P<short_name>[^/]+)/$', app.ask_book, name='ask_book'),
url(r'^books/(?P<short_name>[^/]+)/$', app.book, name='book'),
url(r'^search/$', app.search, name='search'),
+ (r'^i18n/', include('django.conf.urls.i18n')),
)